<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.kolmafia.us/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zarqon</id>
	<title>Kolmafia - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.kolmafia.us/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zarqon"/>
	<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Special:Contributions/Zarqon"/>
	<updated>2026-04-24T21:14:15Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Last_choice&amp;diff=8540</id>
		<title>Last choice</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Last_choice&amp;diff=8540"/>
		<updated>2020-03-11T17:05:56Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: Created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&lt;br /&gt;
#vardefine:name|last_choice}}{{&lt;br /&gt;
#vardefine:return_type|int}}{{&lt;br /&gt;
&lt;br /&gt;
FunctionPage|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
&lt;br /&gt;
function1={{Function|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
return_type={{#var:return_type}}|&lt;br /&gt;
&lt;br /&gt;
}}|&lt;br /&gt;
&lt;br /&gt;
function_description=Returns the number of the last choice you encountered, whether you are currently in it or not.  Use [[handling_choice|handling_choice()]] to determine if you are currently in a choice.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Adventuring]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Handling_choice&amp;diff=8539</id>
		<title>Handling choice</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Handling_choice&amp;diff=8539"/>
		<updated>2020-03-11T17:02:46Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: Page creation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&lt;br /&gt;
#vardefine:name|handling_choice}}{{&lt;br /&gt;
#vardefine:return_type|boolean}}{{&lt;br /&gt;
&lt;br /&gt;
FunctionPage|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
&lt;br /&gt;
function1={{Function|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
aggregate={{#var:aggregate}}|&lt;br /&gt;
return_type={{#var:return_type}}|&lt;br /&gt;
&lt;br /&gt;
}}|&lt;br /&gt;
&lt;br /&gt;
function_description=Returns true if you are currently in a choice and [[last_choice|last_choice()]] and [[available_choice_options|available_choice_options()]] are accurate for the choice.|&lt;br /&gt;
see_also={{SeeAlso|choice_follows_fight|available_choice_options|last_choice|run_choice}}|&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Adventuring]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7960</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7960"/>
		<updated>2018-10-01T16:37:35Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: added dmgformula keyword&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|cadenza&lt;br /&gt;
|accordion item number&lt;br /&gt;
|The results of Cadenza using the specified accordion.&lt;br /&gt;
|-&lt;br /&gt;
|canhandle&lt;br /&gt;
|beans item number&lt;br /&gt;
|The results of Canhandle when wielding the specified can of beans.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|headbutt&lt;br /&gt;
|hat item number&lt;br /&gt;
|Bonus damage from the specified turtle helmet.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|servant&lt;br /&gt;
|servant ID&lt;br /&gt;
|Results for your servant as Ed the Undying.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|-&lt;br /&gt;
|thrall&lt;br /&gt;
|thrall ID&lt;br /&gt;
|Per-round results from having the specified pasta thrall active.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname (user-friendly name), exists solely to make the data file human-readable and isn&#039;t even used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|mutex&lt;br /&gt;
|A mutually exclusive group this action belongs to.  Any action in the group makes all other actions in the same-named group unavailable (e.g. Sauceror curses, sixguns, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: aoe, pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|dmgformula X&lt;br /&gt;
|Use this to specify a monster&#039;s unique damage formula as a spread (for example, Your Shadow uses &amp;quot;95+maxhp/6&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|dmgformula X&lt;br /&gt;
|Specify a monster&#039;s unique formula for dealing damage.  For example, the entry for Your Shadow includes &amp;quot;dmgformula 95+maxhp/6&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7959</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7959"/>
		<updated>2018-10-01T16:34:29Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: better wording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|cadenza&lt;br /&gt;
|accordion item number&lt;br /&gt;
|The results of Cadenza using the specified accordion.&lt;br /&gt;
|-&lt;br /&gt;
|canhandle&lt;br /&gt;
|beans item number&lt;br /&gt;
|The results of Canhandle when wielding the specified can of beans.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|headbutt&lt;br /&gt;
|hat item number&lt;br /&gt;
|Bonus damage from the specified turtle helmet.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|servant&lt;br /&gt;
|servant ID&lt;br /&gt;
|Results for your servant as Ed the Undying.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|-&lt;br /&gt;
|thrall&lt;br /&gt;
|thrall ID&lt;br /&gt;
|Per-round results from having the specified pasta thrall active.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname (user-friendly name), exists solely to make the data file human-readable and isn&#039;t even used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|mutex&lt;br /&gt;
|A mutually exclusive group this action belongs to.  Any action in the group makes all other actions in the same-named group unavailable (e.g. Sauceror curses, sixguns, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: aoe, pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|dmgformula X&lt;br /&gt;
|Use this to specify a monster&#039;s unique damage formula as a spread (for example, Your Shadow uses &amp;quot;95+maxhp/6&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7958</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7958"/>
		<updated>2018-10-01T16:32:45Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: added mutex keyword&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|cadenza&lt;br /&gt;
|accordion item number&lt;br /&gt;
|The results of Cadenza using the specified accordion.&lt;br /&gt;
|-&lt;br /&gt;
|canhandle&lt;br /&gt;
|beans item number&lt;br /&gt;
|The results of Canhandle when wielding the specified can of beans.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|headbutt&lt;br /&gt;
|hat item number&lt;br /&gt;
|Bonus damage from the specified turtle helmet.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|servant&lt;br /&gt;
|servant ID&lt;br /&gt;
|Results for your servant as Ed the Undying.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|-&lt;br /&gt;
|thrall&lt;br /&gt;
|thrall ID&lt;br /&gt;
|Per-round results from having the specified pasta thrall active.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname (user-friendly name), exists solely to make the data file human-readable and isn&#039;t even used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|mutex X&lt;br /&gt;
|If specified, this action is part of a mutually exclusive group X.  Any action in group X makes all other actions in the group unavailable (e.g. Sauceror curses, sixguns, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: aoe, pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|dmgformula X&lt;br /&gt;
|Use this to specify a monster&#039;s unique damage formula as a spread (for example, Your Shadow uses &amp;quot;95+maxhp/6&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7957</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7957"/>
		<updated>2018-10-01T16:30:22Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: added &amp;quot;servant&amp;quot; category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|cadenza&lt;br /&gt;
|accordion item number&lt;br /&gt;
|The results of Cadenza using the specified accordion.&lt;br /&gt;
|-&lt;br /&gt;
|canhandle&lt;br /&gt;
|beans item number&lt;br /&gt;
|The results of Canhandle when wielding the specified can of beans.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|headbutt&lt;br /&gt;
|hat item number&lt;br /&gt;
|Bonus damage from the specified turtle helmet.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|servant&lt;br /&gt;
|servant ID&lt;br /&gt;
|Results for your servant as Ed the Undying.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|-&lt;br /&gt;
|thrall&lt;br /&gt;
|thrall ID&lt;br /&gt;
|Per-round results from having the specified pasta thrall active.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname (user-friendly name), exists solely to make the data file human-readable and isn&#039;t even used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: aoe, pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|dmgformula X&lt;br /&gt;
|Use this to specify a monster&#039;s unique damage formula as a spread (for example, Your Shadow uses &amp;quot;95+maxhp/6&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7956</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7956"/>
		<updated>2018-09-21T16:47:38Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: new keyword &amp;#039;dmgformula&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|cadenza&lt;br /&gt;
|accordion item number&lt;br /&gt;
|The results of Cadenza using the specified accordion.&lt;br /&gt;
|-&lt;br /&gt;
|canhandle&lt;br /&gt;
|beans item number&lt;br /&gt;
|The results of Canhandle when wielding the specified can of beans.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|headbutt&lt;br /&gt;
|hat item number&lt;br /&gt;
|Bonus damage from the specified turtle helmet.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|-&lt;br /&gt;
|thrall&lt;br /&gt;
|thrall ID&lt;br /&gt;
|Per-round results from having the specified pasta thrall active.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname (user-friendly name), exists solely to make the data file human-readable and isn&#039;t even used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: aoe, pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|dmgformula X&lt;br /&gt;
|Use this to specify a monster&#039;s unique damage formula as a spread (for example, Your Shadow uses &amp;quot;95+maxhp/6&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7955</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7955"/>
		<updated>2018-08-31T17:22:03Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: aoe&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|cadenza&lt;br /&gt;
|accordion item number&lt;br /&gt;
|The results of Cadenza using the specified accordion.&lt;br /&gt;
|-&lt;br /&gt;
|canhandle&lt;br /&gt;
|beans item number&lt;br /&gt;
|The results of Canhandle when wielding the specified can of beans.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|headbutt&lt;br /&gt;
|hat item number&lt;br /&gt;
|Bonus damage from the specified turtle helmet.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|-&lt;br /&gt;
|thrall&lt;br /&gt;
|thrall ID&lt;br /&gt;
|Per-round results from having the specified pasta thrall active.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname (user-friendly name), exists solely to make the data file human-readable and isn&#039;t even used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: aoe, pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7924</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7924"/>
		<updated>2018-08-31T16:54:34Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: &amp;quot;finished&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download instructions, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready; attack/jiggle/skill s/use i&lt;br /&gt;
   string cid;             // unique combat identifier: lastCombatStarted&lt;br /&gt;
   spread dmg;             // raw dmg dealt, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // this action ends combat&lt;br /&gt;
   string custom;          // if not empty, this action should not be used in normal automation -- value is action category (banish, attract, yellow, copy, runaway, etc)&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().  Most of these values are set in BatBrain&#039;s set_monster() function.&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
monster m;                 // the monster currently being fought&lt;br /&gt;
record monster_data {&lt;br /&gt;
   int variable;           // the +ML currently being run; if the same, the monster will be reloaded from cache&lt;br /&gt;
   boolean nopotato;       // potatos are useless here&lt;br /&gt;
   boolean nofamiliar;     // your familiar is useless here&lt;br /&gt;
   spread aura;            // passive damage dealt to you every round&lt;br /&gt;
   spread retal;           // damage dealt to you if you hit with a melee attack&lt;br /&gt;
   spread res;             // resistances to each element, expressed as -1.0 (vulnerability) to 1.0 (immunity)&lt;br /&gt;
   spread pen;             // the monster&#039;s penetration ($element[none] for DA penetration)&lt;br /&gt;
   int drpen;              // DR penetration.  The doctor is IN!&lt;br /&gt;
   int howmany;            // group monster size (default 1)&lt;br /&gt;
   int multiattack;        // number of attacks per round (default 1)&lt;br /&gt;
   int maxround;           // combat lasts till this round (default 30)&lt;br /&gt;
   int damagecap;          // damage in amounts beyond this will be reduced...&lt;br /&gt;
   float capexp;           // ...by this exponent&lt;br /&gt;
   float autohit;          // chance of automatically hitting, regardless of moxie&lt;br /&gt;
   float automiss;         // chance of automatically missing&lt;br /&gt;
   float nostagger;        // chance of shrugging staggers.  Usually 1.0 if anything&lt;br /&gt;
   float nostun;           // chance of shrugging multi-round stuns&lt;br /&gt;
   float noitems;          // chance of ignoring combat items&lt;br /&gt;
   float noskills;         // chance of ignoring skills&lt;br /&gt;
   float delevelres;       // percent resistance to deleveling&lt;br /&gt;
   float spellres;         // percent resistance to spells&lt;br /&gt;
   float dodge;            // chance of dodging melee attacks&lt;br /&gt;
   string onlyhurtby;      // can only be damaged by X.  possible: aoe, club, pottery, healing&lt;br /&gt;
   string[string] dmgkey;  // normalized damage type(s) vs. this monster (sauce, pasta, perfect)&lt;br /&gt;
   string note;            // special note about this monster&lt;br /&gt;
};&lt;br /&gt;
monster_data mdata;        // m&#039;s monster_data&lt;br /&gt;
float mvalcache;           // the value of the monster, including substats and meat/item drops&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
spread pres         // your resistances/vulnerabilities&lt;br /&gt;
string page         // the text of the most recent fight.php page load&lt;br /&gt;
int round           // the current/simulated round&lt;br /&gt;
int maxround        // the maximum rounds the combat can extend&lt;br /&gt;
float beatenup      // the cost of getting beaten up&lt;br /&gt;
float meatperhp     // the value of 1 HP&lt;br /&gt;
float meatpermp     // the value of 1 MP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int[item] stolen          // all items you have acquired during this combat&lt;br /&gt;
advevent adj              // all adjustments to the current combat (used when queueing)&lt;br /&gt;
boolean[monster, int, string, int] happenings;  // events that have happened in this fight.  Indices: m, lastCombatStarted, action id, round =&amp;gt; playeraction&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
advevent[int] opts        // all known combat options currently available to you&lt;br /&gt;
advevent[int] custom      // custom actions which SS has determined apply to this combat&lt;br /&gt;
advevent[int] queue       // queued actions (affects round number and uses adj to track adjustments)&lt;br /&gt;
int[string] blacklist     // blacklisted actions to be ignored&lt;br /&gt;
string batround_insert    // empty by default; calling scripts may insert additional macro code to batround (macro called each round between actions), formatted as &amp;quot;commands; &amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|finished}}{{Function|&lt;br /&gt;
name=finished|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
}}&lt;br /&gt;
This function simply returns true if your combat is over.  Useful as a condition in your combat script&#039;s master while() loop.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be one of: att, def, hp, drpen, howmany, damagecap, capexp, autohit, automiss, nostun, noskills, noitems, nostagger, delevelres, spellres, dodge, or itemres|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.  This function is also used to return any of the special monster attributes listed above (these attributes are specified in [[batfactors]]).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;br /&gt;
&lt;br /&gt;
[[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7923</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7923"/>
		<updated>2018-08-31T16:54:05Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: BatBrain is a function library&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download instructions, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready; attack/jiggle/skill s/use i&lt;br /&gt;
   string cid;             // unique combat identifier: lastCombatStarted&lt;br /&gt;
   spread dmg;             // raw dmg dealt, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // this action ends combat&lt;br /&gt;
   string custom;          // if not empty, this action should not be used in normal automation -- value is action category (banish, attract, yellow, copy, runaway, etc)&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().  Most of these values are set in BatBrain&#039;s set_monster() function.&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
monster m;                 // the monster currently being fought&lt;br /&gt;
record monster_data {&lt;br /&gt;
   int variable;           // the +ML currently being run; if the same, the monster will be reloaded from cache&lt;br /&gt;
   boolean nopotato;       // potatos are useless here&lt;br /&gt;
   boolean nofamiliar;     // your familiar is useless here&lt;br /&gt;
   spread aura;            // passive damage dealt to you every round&lt;br /&gt;
   spread retal;           // damage dealt to you if you hit with a melee attack&lt;br /&gt;
   spread res;             // resistances to each element, expressed as -1.0 (vulnerability) to 1.0 (immunity)&lt;br /&gt;
   spread pen;             // the monster&#039;s penetration ($element[none] for DA penetration)&lt;br /&gt;
   int drpen;              // DR penetration.  The doctor is IN!&lt;br /&gt;
   int howmany;            // group monster size (default 1)&lt;br /&gt;
   int multiattack;        // number of attacks per round (default 1)&lt;br /&gt;
   int maxround;           // combat lasts till this round (default 30)&lt;br /&gt;
   int damagecap;          // damage in amounts beyond this will be reduced...&lt;br /&gt;
   float capexp;           // ...by this exponent&lt;br /&gt;
   float autohit;          // chance of automatically hitting, regardless of moxie&lt;br /&gt;
   float automiss;         // chance of automatically missing&lt;br /&gt;
   float nostagger;        // chance of shrugging staggers.  Usually 1.0 if anything&lt;br /&gt;
   float nostun;           // chance of shrugging multi-round stuns&lt;br /&gt;
   float noitems;          // chance of ignoring combat items&lt;br /&gt;
   float noskills;         // chance of ignoring skills&lt;br /&gt;
   float delevelres;       // percent resistance to deleveling&lt;br /&gt;
   float spellres;         // percent resistance to spells&lt;br /&gt;
   float dodge;            // chance of dodging melee attacks&lt;br /&gt;
   string onlyhurtby;      // can only be damaged by X.  possible: aoe, club, pottery, healing&lt;br /&gt;
   string[string] dmgkey;  // normalized damage type(s) vs. this monster (sauce, pasta, perfect)&lt;br /&gt;
   string note;            // special note about this monster&lt;br /&gt;
};&lt;br /&gt;
monster_data mdata;        // m&#039;s monster_data&lt;br /&gt;
float mvalcache;           // the value of the monster, including substats and meat/item drops&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
spread pres         // your resistances/vulnerabilities&lt;br /&gt;
string page         // the text of the most recent fight.php page load&lt;br /&gt;
int round           // the current/simulated round&lt;br /&gt;
int maxround        // the maximum rounds the combat can extend&lt;br /&gt;
float beatenup      // the cost of getting beaten up&lt;br /&gt;
float meatperhp     // the value of 1 HP&lt;br /&gt;
float meatpermp     // the value of 1 MP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int[item] stolen          // all items you have acquired during this combat&lt;br /&gt;
advevent adj              // all adjustments to the current combat (used when queueing)&lt;br /&gt;
boolean[monster, int, string, int] happenings;  // events that have happened in this fight.  Indices: m, lastCombatStarted, action id, round =&amp;gt; playeraction&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
advevent[int] opts        // all known combat options currently available to you&lt;br /&gt;
advevent[int] custom      // custom actions which SS has determined apply to this combat&lt;br /&gt;
advevent[int] queue       // queued actions (affects round number and uses adj to track adjustments)&lt;br /&gt;
int[string] blacklist     // blacklisted actions to be ignored&lt;br /&gt;
string batround_insert    // empty by default; calling scripts may insert additional macro code to batround (macro called each round between actions), formatted as &amp;quot;commands; &amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|finished}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
}}&lt;br /&gt;
This function simply returns true if your combat is over.  Useful as a condition in your combat script&#039;s master while() loop.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be one of: att, def, hp, drpen, howmany, damagecap, capexp, autohit, automiss, nostun, noskills, noitems, nostagger, delevelres, spellres, dodge, or itemres|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.  This function is also used to return any of the special monster attributes listed above (these attributes are specified in [[batfactors]]).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;br /&gt;
&lt;br /&gt;
[[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7309</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7309"/>
		<updated>2018-08-31T16:19:15Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: added kadrop()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
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 &amp;quot;, &amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|stringlist}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|stringlist}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|stringlist}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|stringlist}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|stringlist}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|stringlist}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|stringlist}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|stringlist}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|stringlist}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|varname}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p2desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|getvar}}{{Function|&lt;br /&gt;
name=getvar|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|varname}}|&lt;br /&gt;
p1desc={{pspan|name}} is the setting to retrieve the value of|&lt;br /&gt;
}}&lt;br /&gt;
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[].&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them.&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia properties (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* 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&#039;s ZLib settings that have been changed from default are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* 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&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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.&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence in vardefaults[], which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* 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[&amp;quot;propertyToChange&amp;quot;] = newValue, followed by updatevars() to update the map with the new setting.  If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a setting called &amp;quot;threshold&amp;quot; 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 &amp;quot;threshold&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; is used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|qprop}}{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kadrop}}{{Function|&lt;br /&gt;
name=kadrop|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|m}}|&lt;br /&gt;
p1desc={{pspan|m}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // including items/meat gained&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   return (m.fromname == &amp;quot;Your Pen Pal&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7922</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7922"/>
		<updated>2017-06-01T04:40:20Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: advevents changed slightly&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready; attack/jiggle/skill s/use i&lt;br /&gt;
   string cid;             // unique combat identifier: lastCombatStarted&lt;br /&gt;
   spread dmg;             // raw dmg dealt, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // this action ends combat&lt;br /&gt;
   string custom;          // if not empty, this action should not be used in normal automation -- value is action category (banish, attract, yellow, copy, runaway, etc)&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().  Most of these values are set in BatBrain&#039;s set_monster() function.&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
monster m;                 // the monster currently being fought&lt;br /&gt;
record monster_data {&lt;br /&gt;
   int variable;           // the +ML currently being run; if the same, the monster will be reloaded from cache&lt;br /&gt;
   boolean nopotato;       // potatos are useless here&lt;br /&gt;
   boolean nofamiliar;     // your familiar is useless here&lt;br /&gt;
   spread aura;            // passive damage dealt to you every round&lt;br /&gt;
   spread retal;           // damage dealt to you if you hit with a melee attack&lt;br /&gt;
   spread res;             // resistances to each element, expressed as -1.0 (vulnerability) to 1.0 (immunity)&lt;br /&gt;
   spread pen;             // the monster&#039;s penetration ($element[none] for DA penetration)&lt;br /&gt;
   int drpen;              // DR penetration.  The doctor is IN!&lt;br /&gt;
   int howmany;            // group monster size (default 1)&lt;br /&gt;
   int multiattack;        // number of attacks per round (default 1)&lt;br /&gt;
   int maxround;           // combat lasts till this round (default 30)&lt;br /&gt;
   int damagecap;          // damage in amounts beyond this will be reduced...&lt;br /&gt;
   float capexp;           // ...by this exponent&lt;br /&gt;
   float autohit;          // chance of automatically hitting, regardless of moxie&lt;br /&gt;
   float automiss;         // chance of automatically missing&lt;br /&gt;
   float nostagger;        // chance of shrugging staggers.  Usually 1.0 if anything&lt;br /&gt;
   float nostun;           // chance of shrugging multi-round stuns&lt;br /&gt;
   float noitems;          // chance of ignoring combat items&lt;br /&gt;
   float noskills;         // chance of ignoring skills&lt;br /&gt;
   float delevelres;       // percent resistance to deleveling&lt;br /&gt;
   float spellres;         // percent resistance to spells&lt;br /&gt;
   float dodge;            // chance of dodging melee attacks&lt;br /&gt;
   string onlyhurtby;      // can only be damaged by X.  possible: club, pottery, healing&lt;br /&gt;
   string[string] dmgkey;  // normalized damage type(s) vs. this monster (sauce, pasta, perfect)&lt;br /&gt;
};&lt;br /&gt;
monster_data mdata;        // m&#039;s monster_data&lt;br /&gt;
float mvalcache;            // the value of the monster, including substats and meat/item drops&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
spread pres         // your resistances/vulnerabilities&lt;br /&gt;
string page         // the text of the most recent fight.php page load&lt;br /&gt;
int round           // the current/simulated round&lt;br /&gt;
int maxround        // the maximum rounds the combat can extend&lt;br /&gt;
float beatenup      // the cost of getting beaten up&lt;br /&gt;
float meatperhp     // the value of 1 HP&lt;br /&gt;
float meatpermp     // the value of 1 MP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int[item] stolen          // all items you have acquired during this combat&lt;br /&gt;
advevent adj              // all adjustments to the current combat (used when queueing)&lt;br /&gt;
boolean[monster, int, string, int] happenings;  // events that have happened in this fight.  Indices: m, lastCombatStarted, action id, round =&amp;gt; playeraction&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
advevent[int] opts        // all known combat options currently available to you&lt;br /&gt;
advevent[int] custom      // custom actions which SS has determined apply to this combat&lt;br /&gt;
advevent[int] queue       // queued actions (affects round number and uses adj to track adjustments)&lt;br /&gt;
int[string] blacklist     // blacklisted actions to be ignored&lt;br /&gt;
string batround_insert    // empty by default; calling scripts may insert additional macro code to batround (macro called each round between actions), formatted as &amp;quot;commands; &amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be one of: att, def, hp, drpen, howmany, damagecap, capexp, autohit, automiss, nostun, noskills, noitems, nostagger, delevelres, spellres, dodge, or itemres|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.  This function is also used to return any of the special monster attributes listed above (these attributes are specified in [[batfactors]]).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7921</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7921"/>
		<updated>2017-06-01T04:18:19Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: Monster data has changed considerably&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready name -- attack/jiggle/skill s/use i&lt;br /&gt;
   spread dmg;             // raw dmg dealt to the monster, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken by the player, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // whether or not this action ends the combat&lt;br /&gt;
   string custom;          // flag for special actions that should not be used in normal automation&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().  Most of these values are set in BatBrain&#039;s set_monster() function.&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
monster m;                 // the monster currently being fought&lt;br /&gt;
record monster_data {&lt;br /&gt;
   int variable;           // the +ML currently being run; if the same, the monster will be reloaded from cache&lt;br /&gt;
   boolean nopotato;       // potatos are useless here&lt;br /&gt;
   boolean nofamiliar;     // your familiar is useless here&lt;br /&gt;
   spread aura;            // passive damage dealt to you every round&lt;br /&gt;
   spread retal;           // damage dealt to you if you hit with a melee attack&lt;br /&gt;
   spread res;             // resistances to each element, expressed as -1.0 (vulnerability) to 1.0 (immunity)&lt;br /&gt;
   spread pen;             // the monster&#039;s penetration ($element[none] for DA penetration)&lt;br /&gt;
   int drpen;              // DR penetration.  The doctor is IN!&lt;br /&gt;
   int howmany;            // group monster size (default 1)&lt;br /&gt;
   int multiattack;        // number of attacks per round (default 1)&lt;br /&gt;
   int maxround;           // combat lasts till this round (default 30)&lt;br /&gt;
   int damagecap;          // damage in amounts beyond this will be reduced...&lt;br /&gt;
   float capexp;           // ...by this exponent&lt;br /&gt;
   float autohit;          // chance of automatically hitting, regardless of moxie&lt;br /&gt;
   float automiss;         // chance of automatically missing&lt;br /&gt;
   float nostagger;        // chance of shrugging staggers.  Usually 1.0 if anything&lt;br /&gt;
   float nostun;           // chance of shrugging multi-round stuns&lt;br /&gt;
   float noitems;          // chance of ignoring combat items&lt;br /&gt;
   float noskills;         // chance of ignoring skills&lt;br /&gt;
   float delevelres;       // percent resistance to deleveling&lt;br /&gt;
   float spellres;         // percent resistance to spells&lt;br /&gt;
   float dodge;            // chance of dodging melee attacks&lt;br /&gt;
   string onlyhurtby;      // can only be damaged by X.  possible: club, pottery, healing&lt;br /&gt;
   string[string] dmgkey;  // normalized damage type(s) vs. this monster (sauce, pasta, perfect)&lt;br /&gt;
};&lt;br /&gt;
monster_data mdata;        // m&#039;s monster_data&lt;br /&gt;
float mvalcache;            // the value of the monster, including substats and meat/item drops&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
spread pres         // your resistances/vulnerabilities&lt;br /&gt;
string page         // the text of the most recent fight.php page load&lt;br /&gt;
int round           // the current/simulated round&lt;br /&gt;
int maxround        // the maximum rounds the combat can extend&lt;br /&gt;
float beatenup      // the cost of getting beaten up&lt;br /&gt;
float meatperhp     // the value of 1 HP&lt;br /&gt;
float meatpermp     // the value of 1 MP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int[item] stolen          // all items you have acquired during this combat&lt;br /&gt;
advevent adj              // all adjustments to the current combat (used when queueing)&lt;br /&gt;
boolean[monster, int, string, int] happenings;  // events that have happened in this fight.  Indices: m, lastCombatStarted, action id, round =&amp;gt; playeraction&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
advevent[int] opts        // all known combat options currently available to you&lt;br /&gt;
advevent[int] custom      // custom actions which SS has determined apply to this combat&lt;br /&gt;
advevent[int] queue       // queued actions (affects round number and uses adj to track adjustments)&lt;br /&gt;
int[string] blacklist     // blacklisted actions to be ignored&lt;br /&gt;
string batround_insert    // empty by default; calling scripts may insert additional macro code to batround (macro called each round between actions), formatted as &amp;quot;commands; &amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be one of: att, def, hp, drpen, howmany, damagecap, capexp, autohit, automiss, nostun, noskills, noitems, nostagger, delevelres, spellres, dodge, or itemres|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.  This function is also used to return any of the special monster attributes listed above (these attributes are specified in [[batfactors]]).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7308</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7308"/>
		<updated>2017-05-14T15:54:47Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: Kmail message now includes items/meat gain&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
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 &amp;quot;, &amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|varname}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p2desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|getvar}}{{Function|&lt;br /&gt;
name=getvar|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|varname}}|&lt;br /&gt;
p1desc={{pspan|name}} is the setting to retrieve the value of|&lt;br /&gt;
}}&lt;br /&gt;
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[].&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them.&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia properties (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* 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&#039;s ZLib settings that have been changed from default are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* 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&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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.&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence in vardefaults[], which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* 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[&amp;quot;propertyToChange&amp;quot;] = newValue, followed by updatevars() to update the map with the new setting.  If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a setting called &amp;quot;threshold&amp;quot; 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 &amp;quot;threshold&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; is used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|qprop}}{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // including items/meat gained&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   return (m.fromname == &amp;quot;Your Pen Pal&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7307</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7307"/>
		<updated>2017-05-14T10:02:31Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: Added getvar() and updated settings description to reflect new behavior regarding defaults&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
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 &amp;quot;, &amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|varname}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p2desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|getvar}}{{Function|&lt;br /&gt;
name=getvar|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|varname}}|&lt;br /&gt;
p1desc={{pspan|name}} is the setting to retrieve the value of|&lt;br /&gt;
}}&lt;br /&gt;
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[].&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them.&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia properties (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* 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&#039;s ZLib settings that have been changed from default are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* 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&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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.&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence in vardefaults[], which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* 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[&amp;quot;propertyToChange&amp;quot;] = newValue, followed by updatevars() to update the map with the new setting.  If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a setting called &amp;quot;threshold&amp;quot; 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 &amp;quot;threshold&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; is used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|qprop}}{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Limit_mode&amp;diff=8492</id>
		<title>Limit mode</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Limit_mode&amp;diff=8492"/>
		<updated>2016-10-04T15:26:56Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&lt;br /&gt;
#vardefine:name|limit_mode}}{{&lt;br /&gt;
#vardefine:return_type|string}}{{&lt;br /&gt;
&lt;br /&gt;
FunctionPage|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
&lt;br /&gt;
function1={{Function|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
aggregate={{#var:aggregate}}|&lt;br /&gt;
return_type={{#var:return_type}}|&lt;br /&gt;
return_also={{#var:return_also}}|&lt;br /&gt;
}}|&lt;br /&gt;
&lt;br /&gt;
function_description=Returns your current limit mode, for example &amp;quot;spelunky&amp;quot; or &amp;quot;batman&amp;quot;.  If you are not limited by a minigame, returns an empty string.|&lt;br /&gt;
&lt;br /&gt;
code1={{CodeSample|&lt;br /&gt;
title=Code Sample|&lt;br /&gt;
description=The following example|&lt;br /&gt;
code=&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7306</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7306"/>
		<updated>2016-08-15T03:11:03Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: a bit more dissuasion for scripts editing settings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
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 &amp;quot;, &amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* 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[&amp;quot;propertyToChange&amp;quot;] = newValue, followed by updatevars() to update the map with the new setting.  If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|qprop}}{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7305</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7305"/>
		<updated>2016-08-15T03:06:33Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: redundant &amp;quot;more information&amp;quot; section removed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
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 &amp;quot;, &amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* To change a setting after setvar() within ash use: vars[&amp;quot;propertyToChange&amp;quot;] = newValue; followed by: updatevars(); to update the map with the new setting. If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|qprop}}{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7304</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7304"/>
		<updated>2016-08-15T02:51:42Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: even here I forget parentheses&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
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 &amp;quot;, &amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* To change a setting after setvar() within ash use: vars[&amp;quot;propertyToChange&amp;quot;] = newValue; followed by: updatevars(); to update the map with the new setting. If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|qprop}}{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7303</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7303"/>
		<updated>2016-08-15T02:48:24Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: optional glue parameter added to normalized()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
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 &amp;quot;, &amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* To change a setting after setvar() within ash use: vars[&amp;quot;propertyToChange&amp;quot;] = newValue; followed by: updatevars(); to update the map with the new setting. If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|qprop}}{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7302</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7302"/>
		<updated>2016-08-15T02:44:27Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* To change a setting after setvar() within ash use: vars[&amp;quot;propertyToChange&amp;quot;] = newValue; followed by: updatevars(); to update the map with the new setting. If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|qprop}}{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7301</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7301"/>
		<updated>2016-08-15T02:43:30Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: added qprop()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
* To change a setting after setvar() within ash use: vars[&amp;quot;propertyToChange&amp;quot;] = newValue; followed by: updatevars(); to update the map with the new setting. If you don&#039;t use updatevars(), the change will not stick.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{Function|&lt;br /&gt;
name=qprop|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|test}}|&lt;br /&gt;
p1desc={{pspan|test}} is a basic logical expression using a quest property|&lt;br /&gt;
}}&lt;br /&gt;
Simplifies checking mafia&#039;s quest tracking properties (&amp;quot;prefref quest&amp;quot; in the CLI will reveal them).  You should supply {{pspan|test}} like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;quest property&amp;gt; &amp;lt;logical operator&amp;gt; &amp;lt;possible property value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
To check that a quest is complete: qprop(&amp;quot;questLXXSomequest == finished&amp;quot;)&lt;br /&gt;
To check that a quest has reached or passed &amp;quot;step2&amp;quot;: qprop(&amp;quot;questLXXSomequest &amp;gt;= step2&amp;quot;)&lt;br /&gt;
To check that a quest is not complete: qprop(&amp;quot;questLXXSomequest != finished&amp;quot;)&lt;br /&gt;
To check that a quest hasn&#039;t reached step3 yet: qprop(&amp;quot;questLXXSomequest &amp;lt; step3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;step3&amp;quot; is 3, &amp;quot;unstarted&amp;quot; is -1, &amp;quot;started&amp;quot; is 0, and &amp;quot;finished&amp;quot; is 999. Thus, the last example above would also work as qprop(&amp;quot;questLXXSomequest &amp;lt; 3&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
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(&amp;quot;questLXXSomequest&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7954</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7954"/>
		<updated>2016-06-13T04:45:52Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* The Format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|cadenza&lt;br /&gt;
|accordion item number&lt;br /&gt;
|The results of Cadenza using the specified accordion.&lt;br /&gt;
|-&lt;br /&gt;
|canhandle&lt;br /&gt;
|beans item number&lt;br /&gt;
|The results of Canhandle when wielding the specified can of beans.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|headbutt&lt;br /&gt;
|hat item number&lt;br /&gt;
|Bonus damage from the specified turtle helmet.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|-&lt;br /&gt;
|thrall&lt;br /&gt;
|thrall ID&lt;br /&gt;
|Per-round results from having the specified pasta thrall active.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname (user-friendly name), exists solely to make the data file human-readable and isn&#039;t even used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7953</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7953"/>
		<updated>2016-06-13T04:44:53Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* The Format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|cadenza&lt;br /&gt;
|accordion item number&lt;br /&gt;
|The results of Cadenza using the specified accordion.&lt;br /&gt;
|-&lt;br /&gt;
|canhandle&lt;br /&gt;
|beans item number&lt;br /&gt;
|The results of Canhandle when wielding the specified can of beans.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|headbutt&lt;br /&gt;
|hat item number&lt;br /&gt;
|Bonus damage from the specified turtle helmet.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|-&lt;br /&gt;
|thrall&lt;br /&gt;
|thrall ID&lt;br /&gt;
|Per-round results from having the specified pasta thrall active.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7952</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7952"/>
		<updated>2016-02-01T10:10:24Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: A few updated monster keywords.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|variable&lt;br /&gt;
|The monster is variable and should not be loaded from cache.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|onlyhurtby X&lt;br /&gt;
|The monster can only be damaged by X.  Currently supported: pottery, healing, club (and all other weapon types)&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Goal_exists&amp;diff=8365</id>
		<title>Goal exists</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Goal_exists&amp;diff=8365"/>
		<updated>2015-10-25T15:42:44Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: &amp;quot;factoid&amp;quot; also works&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&lt;br /&gt;
#vardefine:name|goal_exists}}{{&lt;br /&gt;
#vardefine:return_type|boolean}}{{&lt;br /&gt;
&lt;br /&gt;
FunctionPage|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
&lt;br /&gt;
function1={{Function|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
aggregate={{#var:aggregate}}|&lt;br /&gt;
return_type={{#var:return_type}}|&lt;br /&gt;
return_also={{#var:return_also}}|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc=Valid values for {{pspan|type}} are:&lt;br /&gt;
* choiceadv&lt;br /&gt;
* autostop&lt;br /&gt;
* meat&lt;br /&gt;
* health&lt;br /&gt;
* factoid&lt;br /&gt;
* mana&lt;br /&gt;
* item|&lt;br /&gt;
}}|&lt;br /&gt;
&lt;br /&gt;
function_description=This function returns true if there are any goals that match {{pspan|type}}.|&lt;br /&gt;
code1={{CodeSample|&lt;br /&gt;
title=CodeSample|&lt;br /&gt;
description=You could set your current mood in a preAdventureScript based on goal types.|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
void set_mood() {&lt;br /&gt;
   if( goal_exists( &amp;quot;item&amp;quot; ) )&lt;br /&gt;
      cli_execute( &amp;quot;mood default, item&amp;quot; );&lt;br /&gt;
   else if( goal_exists( &amp;quot;meat&amp;quot; ) )&lt;br /&gt;
      cli_execute( &amp;quot;mood default, meat&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}|&lt;br /&gt;
&lt;br /&gt;
see_also={{SeeAlso|adventure|add_item_condition|get_goals|is_goal}}|&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Adventuring]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Modifier_eval&amp;diff=6421</id>
		<title>Modifier eval</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Modifier_eval&amp;diff=6421"/>
		<updated>2015-06-05T16:01:02Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: updated from documentation in mafia source&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&lt;br /&gt;
#vardefine:name|modifier_eval}}{{&lt;br /&gt;
#vardefine:return_type|float}}{{&lt;br /&gt;
&lt;br /&gt;
FunctionPage|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
&lt;br /&gt;
function1={{Function|&lt;br /&gt;
name={{#var:name}}|&lt;br /&gt;
aggregate={{#var:aggregate}}|&lt;br /&gt;
return_type={{#var:return_type}}|&lt;br /&gt;
return_also={{#var:return_also}}|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
p1desc={{pspan|expression}} is a mathematical expression to be solved.|&lt;br /&gt;
}}|&lt;br /&gt;
&lt;br /&gt;
function_description= Evaluates an expression in the format used by variable modifiers.  The following was copied from http://sourceforge.net/p/kolmafia/code/HEAD/tree/src/data/modifiers.txt :&lt;br /&gt;
&lt;br /&gt;
* No spaces are allowed within the expression, except as part of a zone/location name.&lt;br /&gt;
* + - * / ( ) have their usual mathematical meaning and precedence.&lt;br /&gt;
* ^ is exponentiation, with the highest precedence.&lt;br /&gt;
* Functions available:&lt;br /&gt;
**	ceil(x) floor(x) sqrt(x) min(x,y) max(x,y) abs(x)&lt;br /&gt;
* Location functions: loc(text) zone(text) env(text)&lt;br /&gt;
**	These have a value of 1 if the current adventure location, zone, or environment contains the specified text, 0 elsewhere.&lt;br /&gt;
* Path function: path(text)&lt;br /&gt;
**	This has a value of 1 if the player&#039;s path matches the text.&lt;br /&gt;
* Familiar function: fam(text)&lt;br /&gt;
**	This has a value of 1 if the player&#039;s familiar type contains the text, else 0.&lt;br /&gt;
* Weapon function: mainhand(text)&lt;br /&gt;
**	This has a value of 1 if the player&#039;s mainhand weapon class (sword, club, etc.) contains the text.&lt;br /&gt;
* Preferences function: pref(text)&lt;br /&gt;
**	Returns the value of the specified preference&lt;br /&gt;
*             function: pref(text,compare)&lt;br /&gt;
**	Returns 1 if the specified preference is equal to &amp;quot;compare&amp;quot;, otherwise 0&lt;br /&gt;
* Effect function: effect(text)&lt;br /&gt;
**	This returns the number of turns remaining of the effect uniquely matching text.&lt;br /&gt;
* Resistance function: res(text)&lt;br /&gt;
**	This returns the number of resistance levels for the listed element&lt;br /&gt;
* Class function: class(text)&lt;br /&gt;
**	This has a value of 1 if the player&#039;s class matches the text.&lt;br /&gt;
* Skill function: skill(text)&lt;br /&gt;
**	This has a value of 1 if the player has the skill matching the text.&lt;br /&gt;
* Upper-case letters are varying values:&lt;br /&gt;
**	A - number of Ascensions&lt;br /&gt;
**	B - Blood of Wereseal effect&lt;br /&gt;
**	C - Clancy&#039;s level&lt;br /&gt;
**	D - Drunkenness&lt;br /&gt;
**	E - active (nonintrinsic) Effects&lt;br /&gt;
**	F - Fullness&lt;br /&gt;
**	G - Grimace darkness (0..5)&lt;br /&gt;
**	H - Hobo Power&lt;br /&gt;
**	I - Disco Momentum&lt;br /&gt;
**	J - 1 on Festival of Jarlsberg, 0 otherwise&lt;br /&gt;
**	K - Smithsness&lt;br /&gt;
**	L - player Level&lt;br /&gt;
**	M - total Moonlight (0..9)&lt;br /&gt;
**	N - AudieNce&lt;br /&gt;
**	P - Pasta Thrall level&lt;br /&gt;
**	R - Reagent potion duration&lt;br /&gt;
**	S - Spleenness&lt;br /&gt;
**	T - Turns remaining of this effect&lt;br /&gt;
**	U - telescope Upgrades&lt;br /&gt;
**	W - familiar Weight&lt;br /&gt;
**	X - gender (-1=male, 1=female)&lt;br /&gt;
**	Y - furY&lt;br /&gt;
&lt;br /&gt;
* This wrapper allows user-defined variables to be used as well, which must have names starting with a lower-case letter (or underscore) to distinguish them from built-in variables.  Variables are supplied as a float[string] map.&lt;br /&gt;
&amp;amp;nbsp;|&lt;br /&gt;
&lt;br /&gt;
code1={{CodeSample|&lt;br /&gt;
title=Code Sample|&lt;br /&gt;
description=This script expands modifier_eval() to include support for user-defined variables. It is a bit complex, but it is extremely useful to anyone who wants to use modifier_eval().|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
float eval(string expr, float[string] vars) {&lt;br /&gt;
   buffer b;&lt;br /&gt;
   matcher m = create_matcher( &amp;quot;\\b[a-z_][a-zA-Z0-9_]*\\b&amp;quot;, expr );&lt;br /&gt;
   while (m.find()) {&lt;br /&gt;
      string var = m.group(0);&lt;br /&gt;
      if (vars contains var) {&lt;br /&gt;
         m.append_replacement(b, vars[var].to_string());&lt;br /&gt;
      }&lt;br /&gt;
      // could implement functions, pref access, etc. here&lt;br /&gt;
   }&lt;br /&gt;
   m.append_tail(b);&lt;br /&gt;
   return modifier_eval(b.to_string());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Everything below this line shows how to make use of eval().&lt;br /&gt;
# TESTING:&lt;br /&gt;
&lt;br /&gt;
float[string] v;&lt;br /&gt;
v[&amp;quot;pi&amp;quot;] = 3.14159265;&lt;br /&gt;
v[&amp;quot;ten&amp;quot;] = 10;&lt;br /&gt;
print(eval(&amp;quot;2+3&amp;quot;, v));&lt;br /&gt;
print(eval(&amp;quot;max(pi^ten,ten^pi)&amp;quot;, v));&lt;br /&gt;
print(eval(&amp;quot;sqrt(pi)*L&amp;quot;, v));&lt;br /&gt;
print(eval(&amp;quot;undefined/2&amp;quot;, v));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}|&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Math and Numbers]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7951</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7951"/>
		<updated>2015-05-30T08:24:45Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: Reimplemented &amp;quot;prismatic&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  You may also use &amp;quot;prismatic&amp;quot; as shorthand for specifying all five elements.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 prismatic&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7950</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7950"/>
		<updated>2015-05-30T08:22:48Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|monster ID&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7949</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7949"/>
		<updated>2015-05-30T08:22:11Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: Monsters are now indexed by ID!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is the monster&#039;s ID, which is accessible in the $monster.id proxy field.  Since some monsters&#039; IDs are unknown, and therefore are listed as 0, batfactors uses an arbitrary negative index for those monsters, checking to_monster(ufname) to find a match against the monster name.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, and physical resistance, though it can be specified, is accessible in the physical_resistance proxy field, so you only need to include resistance information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|nopotato&lt;br /&gt;
|Potato-type familiars do not work vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|nofamiliar&lt;br /&gt;
|Your familiar will not act vs. this monster.&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7299</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7299"/>
		<updated>2015-05-07T16:59:24Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: is_goal(stat) no longer defaults to true for primestat&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7298</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7298"/>
		<updated>2015-05-07T16:46:53Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: Split be_good() parameter into four types.  Removed tower_items().&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|familiar|johnny}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &#039;b&#039; 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.  Additionally, the function treats your primestat as a permanent goal until you are level 13.  So for both a level 9 Sauceror or a level 10 Seal Clubber who set &amp;quot;200 mysticality&amp;quot; as a goal, is_goal($stat[mysticality]) would return true.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7948</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7948"/>
		<updated>2015-01-25T13:21:48Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: New keyword &amp;quot;itemcost&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|itemcost&lt;br /&gt;
|An item required and expended by this action.  This event uses up one of the specified item, and will be ignored if you lack it.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  (For now.) Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7947</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7947"/>
		<updated>2015-01-25T13:17:55Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  The vast majority of BatBrain&#039;s knowledge about items, skills, equipment, monsters, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  (For now.) Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7920</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7920"/>
		<updated>2014-10-12T05:54:36Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: new monster attribute system&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready name -- attack/jiggle/skill s/use i&lt;br /&gt;
   spread dmg;             // raw dmg dealt to the monster, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken by the player, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // whether or not this action ends the combat&lt;br /&gt;
   string custom;          // flag for special actions that should not be used in normal automation&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().  Most of these values are set in BatBrain&#039;s set_monster() function.&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
monster m           // the monster currently being fought&lt;br /&gt;
float mvalcache     // the value of the monster, including substats and meat/item drops&lt;br /&gt;
spread mres         // the monster&#039;s resistances/vulnerabilities&lt;br /&gt;
spread mpen         // the monster&#039;s penetrations&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
spread pres         // your resistances/vulnerabilities&lt;br /&gt;
string page         // the text of the most recent fight.php page load&lt;br /&gt;
int round           // the current/simulated round&lt;br /&gt;
int maxround        // the maximum rounds the combat can extend&lt;br /&gt;
float beatenup      // the cost of getting beaten up&lt;br /&gt;
float meatperhp     // the value of 1 HP&lt;br /&gt;
float meatpermp     // the value of 1 MP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int[item] stolen          // all items you have acquired during this combat&lt;br /&gt;
advevent adj              // all adjustments to the current combat (used when queueing)&lt;br /&gt;
record[string] happenings // events that have already happened&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
advevent[int] opts        // all known combat options currently available to you&lt;br /&gt;
advevent[int] custom      // custom actions which SS has determined apply to this combat&lt;br /&gt;
advevent[int] queue       // queued actions (affects round number and uses adj to track adjustments)&lt;br /&gt;
int[string] blacklist     // blacklisted actions to be ignored&lt;br /&gt;
string batround_insert    // macro commands to insert into every round&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be one of: att, def, hp, drpen, howmany, damagecap, capexp, autohit, automiss, nostun, noskills, noitems, nostagger, delevelres, spellres, dodge, or itemres|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.  This function is also used to return any of the special monster attributes listed above (these attributes are specified in [[batfactors]]).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7919</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7919"/>
		<updated>2014-10-12T05:53:14Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* Other Useful Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready name -- attack/jiggle/skill s/use i&lt;br /&gt;
   spread dmg;             // raw dmg dealt to the monster, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken by the player, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // whether or not this action ends the combat&lt;br /&gt;
   string custom;          // flag for special actions that should not be used in normal automation&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().  Most of these values are set in BatBrain&#039;s set_monster() function.&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
monster m           // the monster currently being fought&lt;br /&gt;
boolean isseal      // true if the monster is a seal&lt;br /&gt;
boolean nostun      // true if the monster is immune to stuns and staggers&lt;br /&gt;
boolean nomultistun // true if the monster is only immune to multi-round stuns&lt;br /&gt;
boolean nomiss      // true if the monster never misses (i.e. gremlins)&lt;br /&gt;
boolean nohit       // true if the monster never hits (i.e. crates)&lt;br /&gt;
int howmanyfoes     // the size of the group you are facing (usually 1)&lt;br /&gt;
float mvalcache     // the value of the monster, including substats and meat/item drops&lt;br /&gt;
spread mres         // the monster&#039;s resistances/vulnerabilities&lt;br /&gt;
int damagecap       // the monster&#039;s damage cap&lt;br /&gt;
float capexp        // for damage caps; the exponent by which to reduce the amount over the cap&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
spread pres         // your resistances/vulnerabilities&lt;br /&gt;
string page         // the text of the most recent fight.php page load&lt;br /&gt;
int round           // the current/simulated round&lt;br /&gt;
int maxround        // the maximum rounds the combat can extend&lt;br /&gt;
float beatenup      // the cost of getting beaten up&lt;br /&gt;
float meatperhp     // the value of 1 HP&lt;br /&gt;
float meatpermp     // the value of 1 MP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int[item] stolen          // all items you have acquired during this combat&lt;br /&gt;
advevent adj              // all adjustments to the current combat (used when queueing)&lt;br /&gt;
record[string] happenings // events that have already happened&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
advevent[int] opts        // all known combat options currently available to you&lt;br /&gt;
advevent[int] custom      // custom actions which SS has determined apply to this combat&lt;br /&gt;
advevent[int] queue       // queued actions (affects round number and uses adj to track adjustments)&lt;br /&gt;
int[string] blacklist     // blacklisted actions to be ignored&lt;br /&gt;
string batround_insert    // macro commands to insert into every round&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be one of: att, def, hp, drpen, howmany, damagecap, capexp, autohit, automiss, nostun, noskills, noitems, nostagger, delevelres, spellres, dodge, or itemres|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.  This function is also used to return any of the special monster attributes listed above (these attributes are specified in [[batfactors]]).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7946</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7946"/>
		<updated>2014-10-12T05:49:27Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* The &amp;quot;monster&amp;quot; Category */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  Most of BatBrain&#039;s knowledge about items, skills, equipment, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  (For now.) Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is also re-purposed -- for monsters, it specifies the monster&#039;s &amp;quot;penetration&amp;quot;, also expressed as a spread.  For each element, the monster treats your resistance as being lower by the amount of levels specified.  Since $element[none] is usually used for physical damage, it is used here to specify DA penetration.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7945</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7945"/>
		<updated>2014-10-12T05:45:53Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* The &amp;quot;monster&amp;quot; Category */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  Most of BatBrain&#039;s knowledge about items, skills, equipment, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is unused.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|The monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|The monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7944</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7944"/>
		<updated>2014-10-12T05:45:02Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: all new keywords&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  Most of BatBrain&#039;s knowledge about items, skills, equipment, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is unused.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|aura X&lt;br /&gt;
|The monster has an aura dealing X player damage (specified as a spread) every round.&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|-&lt;br /&gt;
|dodge (X)&lt;br /&gt;
|The monster has an X percent chance to dodge melee attacks.&lt;br /&gt;
|-&lt;br /&gt;
|autohit (X)&lt;br /&gt;
|This monster has an X percent chance to automatically hit you (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|automiss (X)&lt;br /&gt;
|This monster has an X percent chance to automatically miss you (e.g. crates).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster has an X percent chance to ignore staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nostun (X)&lt;br /&gt;
|The monster has an X percent chance to shrug a multi-round stunner each round.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|The monster has an X percent chance of blocking items (e.g. Bonerdagon).&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|The monster has an X percent chance of blocking skills (e.g. Naughty Sorceress).&lt;br /&gt;
|-&lt;br /&gt;
|delevelres (X)&lt;br /&gt;
|The monster resists X percent of delevel effects.&lt;br /&gt;
|-&lt;br /&gt;
|spellres (X)&lt;br /&gt;
|The monster resists X percent of damage from combat spells.&lt;br /&gt;
|-&lt;br /&gt;
|drpenetration X&lt;br /&gt;
|The monster ignores your first X DR.  The Doctor is IN!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Any keyword that expresses a &amp;quot;percent chance&amp;quot; should be specified as a float between 0 and 1.  For any keyword listed with (X) in parentheses, the value is optional and defaults to 1.0.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7943</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7943"/>
		<updated>2014-08-29T02:57:23Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: nostun -&amp;gt; nostagger&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  Most of BatBrain&#039;s knowledge about items, skills, equipment, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is unused.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|nohit&lt;br /&gt;
|This monster never hits.&lt;br /&gt;
|-&lt;br /&gt;
|nomiss&lt;br /&gt;
|This monster never misses (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|nostagger (X)&lt;br /&gt;
|The monster is immune to staggers.  If a value is specified, it should be a float 0-1 representing the monster&#039;s chance of ignoring staggers.&lt;br /&gt;
|-&lt;br /&gt;
|nomultistun&lt;br /&gt;
|The monster is immune to multi-round stunners, such as Entangling Noodles.&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|You cannot use items in combat with this monster.  If a value is specified, it should be a float representing the monster&#039;s chance of blocking item use.&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|As with noitems above, but for skills.&lt;br /&gt;
|-&lt;br /&gt;
|nospells&lt;br /&gt;
|As with noitems above, but if present, means that the monster is immune to spells.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7942</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7942"/>
		<updated>2014-08-19T01:51:16Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* The &amp;quot;monster&amp;quot; Category */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  Most of BatBrain&#039;s knowledge about items, skills, equipment, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is unused.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|nohit&lt;br /&gt;
|This monster never hits.&lt;br /&gt;
|-&lt;br /&gt;
|nomiss&lt;br /&gt;
|This monster never misses (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|nostun&lt;br /&gt;
|The monster is completely immune to stuns and staggers of any duration.&lt;br /&gt;
|-&lt;br /&gt;
|nomultistun&lt;br /&gt;
|The monster is immune to multi-round stunners, such as Entangling Noodles.&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|You cannot use items in combat with this monster.  If a value is specified, it should be a float representing the monster&#039;s chance of blocking item use.&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|As with noitems above, but for skills.&lt;br /&gt;
|-&lt;br /&gt;
|nospells&lt;br /&gt;
|As with noitems above, but if present, means that the monster is immune to spells.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7297</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7297"/>
		<updated>2014-02-13T08:57:44Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* Adventuring Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check -- usually an item or familiar|&lt;br /&gt;
}}&lt;br /&gt;
This function, originally created to check whether items were allowed in the Bees Hate You path, has been expanded to an all-purpose check to see whether something is acceptable in your current path.  For example, in a Trendy path, outdated items would not be_good.  Likewise, during Bees Hate You, a familiar containing a &#039;b&#039; would not be_good.  In Fistcore, anything you hold in your hands is not allowed.  And so forth.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|tower_items}}{{Function|&lt;br /&gt;
name=tower_items|&lt;br /&gt;
aggregate=true|&lt;br /&gt;
return_type=boolean [string]|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=tower_items|&lt;br /&gt;
aggregate=true|&lt;br /&gt;
return_type=boolean [string]|&lt;br /&gt;
parameter1={{Param|boolean|combat_safe}}|&lt;br /&gt;
p1desc={{pspan|combat_safe}} is optional.  Supply it as true if you are in combat.|&lt;br /&gt;
}}&lt;br /&gt;
This handy function returns a map of the items you definitely need (value: true) or might need (value: false) to pass the entryway and climb the tower.  You can check (tower_items() contains X) to determine whether an item has a nonzero chance of being required for the tower, or check tower_items(X) to determine whether an item has a 100% chance of being needed (i.e. it was indicated necessary by your telescope).  If you haven&#039;t yet checked your telescope yet this run, it will also do that to populate the relevant mafia properties, unless you have supplied the optional {{pspan|combat_safe}} parameter as true (you can&#039;t access your telescope during combat).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.  Additionally, the function treats your primestat as a permanent goal until you are level 13.  So for both a level 9 Sauceror or a level 10 Seal Clubber who set &amp;quot;200 mysticality&amp;quot; as a goal, is_goal($stat[mysticality]) would return true.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7296</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7296"/>
		<updated>2014-02-13T08:57:12Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: added braindrop()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check -- usually an item or familiar|&lt;br /&gt;
}}&lt;br /&gt;
This function, originally created to check whether items were allowed in the Bees Hate You path, has been expanded to an all-purpose check to see whether something is acceptable in your current path.  For example, in a Trendy path, outdated items would not be_good.  Likewise, during Bees Hate You, a familiar containing a &#039;b&#039; would not be_good.  In Fistcore, anything you hold in your hands is not allowed.  And so forth.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|tower_items}}{{Function|&lt;br /&gt;
name=tower_items|&lt;br /&gt;
aggregate=true|&lt;br /&gt;
return_type=boolean [string]|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=tower_items|&lt;br /&gt;
aggregate=true|&lt;br /&gt;
return_type=boolean [string]|&lt;br /&gt;
parameter1={{Param|boolean|combat_safe}}|&lt;br /&gt;
p1desc={{pspan|combat_safe}} is optional.  Supply it as true if you are in combat.|&lt;br /&gt;
}}&lt;br /&gt;
This handy function returns a map of the items you definitely need (value: true) or might need (value: false) to pass the entryway and climb the tower.  You can check (tower_items() contains X) to determine whether an item has a nonzero chance of being required for the tower, or check tower_items(X) to determine whether an item has a 100% chance of being needed (i.e. it was indicated necessary by your telescope).  If you haven&#039;t yet checked your telescope yet this run, it will also do that to populate the relevant mafia properties, unless you have supplied the optional {{pspan|combat_safe}} parameter as true (you can&#039;t access your telescope during combat).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|braindrop}}{{Function|&lt;br /&gt;
name=braindrop|&lt;br /&gt;
return_type=item|&lt;br /&gt;
parameter1={{Param|monster|patient}}|&lt;br /&gt;
p1desc={{pspan|patient}} is the monster under inquiry|&lt;br /&gt;
}}&lt;br /&gt;
Returns the brain dropped by {{pspan|combat_safe}} 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.  Additionally, the function treats your primestat as a permanent goal until you are level 13.  So for both a level 9 Sauceror or a level 10 Seal Clubber who set &amp;quot;200 mysticality&amp;quot; as a goal, is_goal($stat[mysticality]) would return true.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|place}} is the location to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7918</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7918"/>
		<updated>2014-01-28T07:52:32Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* Useful Global Variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready name -- attack/jiggle/skill s/use i&lt;br /&gt;
   spread dmg;             // raw dmg dealt to the monster, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken by the player, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // whether or not this action ends the combat&lt;br /&gt;
   string custom;          // flag for special actions that should not be used in normal automation&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().  Most of these values are set in BatBrain&#039;s set_monster() function.&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
monster m           // the monster currently being fought&lt;br /&gt;
boolean isseal      // true if the monster is a seal&lt;br /&gt;
boolean nostun      // true if the monster is immune to stuns and staggers&lt;br /&gt;
boolean nomultistun // true if the monster is only immune to multi-round stuns&lt;br /&gt;
boolean nomiss      // true if the monster never misses (i.e. gremlins)&lt;br /&gt;
boolean nohit       // true if the monster never hits (i.e. crates)&lt;br /&gt;
int howmanyfoes     // the size of the group you are facing (usually 1)&lt;br /&gt;
float mvalcache     // the value of the monster, including substats and meat/item drops&lt;br /&gt;
spread mres         // the monster&#039;s resistances/vulnerabilities&lt;br /&gt;
int damagecap       // the monster&#039;s damage cap&lt;br /&gt;
float capexp        // for damage caps; the exponent by which to reduce the amount over the cap&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
spread pres         // your resistances/vulnerabilities&lt;br /&gt;
string page         // the text of the most recent fight.php page load&lt;br /&gt;
int round           // the current/simulated round&lt;br /&gt;
int maxround        // the maximum rounds the combat can extend&lt;br /&gt;
float beatenup      // the cost of getting beaten up&lt;br /&gt;
float meatperhp     // the value of 1 HP&lt;br /&gt;
float meatpermp     // the value of 1 MP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int[item] stolen          // all items you have acquired during this combat&lt;br /&gt;
advevent adj              // all adjustments to the current combat (used when queueing)&lt;br /&gt;
record[string] happenings // events that have already happened&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
advevent[int] opts        // all known combat options currently available to you&lt;br /&gt;
advevent[int] custom      // custom actions which SS has determined apply to this combat&lt;br /&gt;
advevent[int] queue       // queued actions (affects round number and uses adj to track adjustments)&lt;br /&gt;
int[string] blacklist     // blacklisted actions to be ignored&lt;br /&gt;
string batround_insert    // macro commands to insert into every round&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;att&amp;quot;,&amp;quot;def&amp;quot;. or &amp;quot;hp&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7917</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7917"/>
		<updated>2014-01-28T07:51:35Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* Useful Global Variables */ basic explanations&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready name -- attack/jiggle/skill s/use i&lt;br /&gt;
   spread dmg;             // raw dmg dealt to the monster, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken by the player, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // whether or not this action ends the combat&lt;br /&gt;
   string custom;          // flag for special actions that should not be used in normal automation&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().  Most of these values are set in BatBrain&#039;s set_monster() function.&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
monster m           // the monster currently being fought&lt;br /&gt;
boolean isseal      // true if the monster is a seal&lt;br /&gt;
boolean nostun      // true if the monster is immune to stuns and staggers&lt;br /&gt;
boolean nomultistun // true if the monster is only immune to multi-round stuns&lt;br /&gt;
boolean nomiss      // true if the monster never misses (i.e. gremlins)&lt;br /&gt;
boolean nohit       // true if the monster never hits (i.e. crates)&lt;br /&gt;
int howmanyfoes     // the size of the group you are facing (usually 1)&lt;br /&gt;
float mvalcache     // the value of the monster, including substats and meat/item drops&lt;br /&gt;
spread mres         // the monster&#039;s resistances/vulnerabilities&lt;br /&gt;
int damagecap       // the monster&#039;s damage cap&lt;br /&gt;
float capexp        // for damage caps; the exponent by which to reduce the amount over the cap&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
spread pres         // your resistances/vulnerabilities&lt;br /&gt;
string page         // the text of the most recent fight.php page load&lt;br /&gt;
int round           // the current/simulated round&lt;br /&gt;
int maxround        // the maximum rounds the combat can extend&lt;br /&gt;
float beatenup      // the cost of getting beaten up&lt;br /&gt;
float meatperhp     // the value of 1 HP&lt;br /&gt;
float meatpermp     // the value of 1 MP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int[item] stolen          // all items you have acquired during this combat&lt;br /&gt;
advevent adj              // all adjustments to the current combat (used when queueing)&lt;br /&gt;
record[string] happenings // events that have already happened&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
advevent[int] opts        // all known combat options&lt;br /&gt;
advevent[int] custom      // custom actions which SS has determined apply to this combat&lt;br /&gt;
advevent[int] queue       // queued actions (affects round number and uses adj to track adjustments)&lt;br /&gt;
int[string] blacklist     // blacklisted actions to be ignored&lt;br /&gt;
string batround_insert    // macro commands to insert into every round&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;att&amp;quot;,&amp;quot;def&amp;quot;. or &amp;quot;hp&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7916</id>
		<title>BatBrain</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=BatBrain&amp;diff=7916"/>
		<updated>2013-12-10T05:09:44Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: add global variables; need to format into table later&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:BatBrain (BatBrain.ash)}}&lt;br /&gt;
== About BatBrain ==&lt;br /&gt;
BatBrain is a function library intended to greatly simplify writing a [[Custom_Combat_Script#Consult_Scripts|consult script]].  A general introduction, changelog, download, and forum discussion can be found in the [http://kolmafia.us/showthread.php?6445 BatBrain thread], but this page is the best place for scripters interested in writing a consult script with BatBrain to start.  NOTE: BatBrain is not built into KoLmafia, it is a separate ASH script which you must download and import to make these functions available.&lt;br /&gt;
&lt;br /&gt;
== What It Does ==&lt;br /&gt;
&lt;br /&gt;
yadda yadda&lt;br /&gt;
&lt;br /&gt;
== Spreads ==&lt;br /&gt;
&lt;br /&gt;
BatBrain handles all damage done (both to you and to the monster) as spreads.  In fact, it defines a data type called &amp;quot;spread&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
typedef float[element] spread;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that all damage is a map of floats keyed by element, with positive values for damage and negative values for healing.  We could have just used float[element] everywhere, but it strikes us as cleaner to use the single word &amp;quot;spread&amp;quot;.  You&#039;ll see this datatype occur fairly frequently if you peruse BatBrain and if you&#039;re writing a combat script, you may have to deal with one.  Fortunately, there are some functions for dealing with spreads:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_spread}}{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_spread|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|string|dmg}}|&lt;br /&gt;
parameter2={{Param|float|factor}}|&lt;br /&gt;
p1desc={{pspan|dmg}} is the damage string, in the same format used by batfactors.|&lt;br /&gt;
p2desc={{pspan|factor}} is optional; supply this if you want to factor the supplied damage by an amount other than 1.0|&lt;br /&gt;
}}&lt;br /&gt;
This function creates a spread from a string.  For example, an attack which deals 10 hot damage would deal to_spread(&amp;quot;10 hot&amp;quot;) damage.  The format for {{pspan|dmg}} is flexible and described in greater detail on the [[batfactors]] page.  An optional {{pspan|factor}} parameter is available as shorthand for factor(to_spread()).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|first}}|&lt;br /&gt;
parameter2={{Param|spread|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first spread to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second spread|&lt;br /&gt;
}}&lt;br /&gt;
Basic arithmetic, a + b.  It returns a spread combining the damage in first and second.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=spread|&lt;br /&gt;
parameter1={{Param|spread|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the spread to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
More basic arithmetic, this time multiplication.  This function returns spread f factored by fact.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_html}}{{Function|&lt;br /&gt;
name=to_html|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|spread|src}}|&lt;br /&gt;
p1desc={{pspan|src}} is the spread to convert to HTML|&lt;br /&gt;
}}&lt;br /&gt;
This function returns an HTML string showing a spread the way KoL does, with elemental damage parenthesized and appropriately color-coded.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_dealt}}{{Function|&lt;br /&gt;
name=dmg_dealt|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|action}}|&lt;br /&gt;
p1desc={{pspan|action}} is the damage spread for a given source of monster damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to your current opponent, accounting for the monster&#039;s resistances, vulnerabilities, and damage cap where applicable.  For example, when fighting Groar, any cold damage present in {{pspan|action}} would be reduced to 1, and any damage of his vulnerable elements would be doubled.  Secondly, any damage over Groar&#039;s soft damage cap would be reduced appropriately, and finally the damage would be summed together into a single float and returned.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|dmg_taken}}{{Function|&lt;br /&gt;
name=dmg_taken|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|spread|pain}}|&lt;br /&gt;
p1desc={{pspan|pain}} is the damage spread for a given source of player damage|&lt;br /&gt;
}}&lt;br /&gt;
This function returns the actual damage a given spread would deal to the player, accounting for the player&#039;s elemental resistances and vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
== Advevents ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve discussed spreads, we can really get down to it.  Absolutely everything that happens, every single &amp;quot;adventure event&amp;quot; that takes place, is treated as an advevent.  Your familiar performs an advevent every round, the monster performs an advevent, each action you have available is an advevent, and sometimes even your current gear or running effects contribute an advevent or two.  Your current combat environment could be described with an advevent, and in fact any adjustments made to your current environment when enqueueing actions are tracked in an advevent.  Get the picture?  Advevents make BatBrain&#039;s world turn.  And here&#039;s what they look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record advevent {          // record of changes due to an event&lt;br /&gt;
   string id;              // macro-ready name -- attack/jiggle/skill s/use i&lt;br /&gt;
   spread dmg;             // raw dmg dealt to the monster, before resists/vulns&lt;br /&gt;
   spread pdmg;            // raw dmg taken by the player, before resists/vulns&lt;br /&gt;
   float att;              // monster attack adjustment&lt;br /&gt;
   float def;              // monster defense adjustment&lt;br /&gt;
   float stun;             // stun chance (expressed as average rounds stunned)&lt;br /&gt;
   float mp;               // mp gained/lost&lt;br /&gt;
   float meat;             // meat gained/lost&lt;br /&gt;
   float profit;           // profit cache to avoid recalculating&lt;br /&gt;
   int rounds;             // rounds consumed&lt;br /&gt;
   substats stats;         // substats gained/lost&lt;br /&gt;
   boolean endscombat;     // whether or not this action ends the combat&lt;br /&gt;
   string custom;          // flag for special actions that should not be used in normal automation&lt;br /&gt;
   string note;            // user-friendly name or special note&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each advevent contains two spreads, one for damage to the monster and one for damage to the player.  The rest is mostly self-explanatory, but a few things require clarification.&lt;br /&gt;
&lt;br /&gt;
First, the profit field will contain nothing (0) until to_profit() is called on the advevent in question, at which point the result is cached in this field for further reference, since to_profit() has a fair amount of calculations and is thus much more expensive (in processing terms) than simply checking a.profit.  Keep that in mind if you&#039;re calling to_profit() a lot; chances are you could speed up your script by changing a few of those to check the profit cache instead.&lt;br /&gt;
&lt;br /&gt;
Second, substats is another datatype defined by BatBrain, and it&#039;s simply a float[stat] map.&lt;br /&gt;
&lt;br /&gt;
The custom field will be empty for most actions, so scripts ought to be checking a.custom == &amp;quot;&amp;quot; before using an action in regular automation.  For special actions, the custom field will contain the type of custom action (and sometimes additional information).  Some custom types currently being used are: attract, banish, copy, yellow, and runaway.&lt;br /&gt;
&lt;br /&gt;
Finally, the note field is not really used by BatBrain, but is used by BatMan RE to display extra information about certain actions (such as notices of estimates due to unspaded numbers, or ongoing damage not predicted by BatBrain, etc).&lt;br /&gt;
&lt;br /&gt;
Here are some functions to help you deal with advevents should the need arise:&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_event}}{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
parameter5={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|spread|dmg}}|&lt;br /&gt;
parameter3={{Param|spread|pdmg}}|&lt;br /&gt;
parameter4={{Param|string|special}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
parameter3={{Param|int|howmanyrounds}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=to_event|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|string|id}}|&lt;br /&gt;
parameter2={{Param|string|special}}|&lt;br /&gt;
p1desc={{pspan|id}} is the ID of the event. BALLS-friendly name (will be used in macros)|&lt;br /&gt;
p2desc={{pspan|dmg}} is for damage/healing to the monster.|&lt;br /&gt;
p3desc={{pspan|pdmg}} is for damage/healing to the player.|&lt;br /&gt;
p4desc={{pspan|special}} is for specifying other qualities of the action, such as deleveling, stunning, meat gained/lost, etc.|&lt;br /&gt;
p5desc={{pspan|howmanyrounds}} is optional, default 0.  It specifies the number of rounds this action takes.  Will be 0 for all but actual player actions.|&lt;br /&gt;
}}&lt;br /&gt;
Builds and returns an advevent, used ubiquitously by BatBrain internally but also useful to a scripter for creating custom actions that are not present in opts[].  You may omit both spreads if the event being constructed deals no damage to either monster or player.  The format for the special field is generally a comma-delimited list of &amp;quot;keyword value&amp;quot;, although some keywords lack values.  The format is described in greater detail on the [[batfactors]] page -- quite a few keywords are available.  Note that if you have an elemental form, all damage specified in {{pspan|dmg}} will be converted to that element by this function.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|merge}}{{Function|&lt;br /&gt;
name=merge|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|first}}|&lt;br /&gt;
parameter2={{Param|advevent|second}}|&lt;br /&gt;
p1desc={{pspan|first}} is the first advevent to merge|&lt;br /&gt;
p2desc={{pspan|second}} is the second advevent|&lt;br /&gt;
}}&lt;br /&gt;
As with the spread version, this function combines two advevents into a single advevent by individually combining each field.  It isn&#039;t always just simple addition, however.  First of all, the id field will be merged using a semicolon and a space, so if you were merging &amp;quot;jiggle&amp;quot; with &amp;quot;attack&amp;quot;, the new combined id would be &amp;quot;jiggle; attack&amp;quot;.  This allows merging events to retain a BALLS-friendly ID.  Second, if both first and second are single item actions and you have Funkslinging, the events will be merged into a single funkslinging action &amp;quot;use X,Y&amp;quot;.  The rounds field likewise will be added together unless it&#039;s being auto-funked, in which case 1 + 1 = 1.  Last, the stun field is not simply added together, because if you perform two actions, each with a 50% stun chance, that does not guarantee a 100% stun chance; that&#039;s a 75% stun chance, because you have a 50% chance of stunning 50% of the time when the first action fails to stun.  Merging takes this into account.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|factor}}{{Function|&lt;br /&gt;
name=factor|&lt;br /&gt;
return_type=advevent|&lt;br /&gt;
parameter1={{Param|advevent|f}}|&lt;br /&gt;
parameter2={{Param|float|fact}}|&lt;br /&gt;
p1desc={{pspan|f}} is the advevent to factor|&lt;br /&gt;
p2desc={{pspan|fact}} is the factor|&lt;br /&gt;
}}&lt;br /&gt;
This function multiplies an advevent by {{pspan|fact}}, and is much more straightforward than merge().  All numeric fields are simply multiplied, with one exception: the rounds field is not multiplied since that would be undesirable.  BatBrain uses this function internally to apply the hitchance of an event to the event.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|to_profit}}{{Function|&lt;br /&gt;
name=to_profit|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|advevent|haps}}|&lt;br /&gt;
parameter2={{Param|boolean|nodelevel}}|&lt;br /&gt;
p1desc={{pspan|haps}} is the advevent to evaluate|&lt;br /&gt;
p2desc={{pspan|nodelevel}} is optional, default false. If supplied as true, will ignore profit from deleveling.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the profit of performing the action {{pspan|haps}} at the current point in the combat.  It looks ahead one round (including the monster&#039;s event, your familiar&#039;s event, and any equipment and effects) and determines what you gained and lost, and converts all of that to a single number, which it returns.  This is a very useful function for combining with other criteria and sorting opts[].  HP and MP gain/loss are evaluated based on your _meatpermp and _meatperhp properties, which are set by Bale&#039;s Universal Recovery Script.  If you are not using this script, basic calculations are made using the price of common restoratives.  HP/MP regeneration is also factored into the profit appropriately.  By default, this function includes profit from deleveling (i.e. reducing the monster&#039;s attack by X means it will deal Y less damage, effectively earning you Y HP).  However, this may be undesirable if you intend to stun beforehand, so an optional {{pspan|nodelevel}} flag was included.&lt;br /&gt;
&lt;br /&gt;
== Useful Global Variables ==&lt;br /&gt;
&lt;br /&gt;
BatBrain has a not-small number of global variables which may simplify writing your script.  Most of these variables are automatically populated as soon as your script runs act().&lt;br /&gt;
&lt;br /&gt;
MONSTER&lt;br /&gt;
&lt;br /&gt;
 monster m&lt;br /&gt;
 boolean isseal&lt;br /&gt;
 boolean nostun&lt;br /&gt;
 boolean nomultistun&lt;br /&gt;
 boolean nomiss&lt;br /&gt;
 boolean nohit&lt;br /&gt;
 int howmanyfoes&lt;br /&gt;
 float mvalcache&lt;br /&gt;
 spread mres&lt;br /&gt;
 int damagecap&lt;br /&gt;
 float capexp&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ENVIRONMENT&lt;br /&gt;
&lt;br /&gt;
 spread pres&lt;br /&gt;
 string page&lt;br /&gt;
 int round&lt;br /&gt;
 int maxround&lt;br /&gt;
 float beatenup&lt;br /&gt;
 float meatperhp&lt;br /&gt;
 float meatpermp&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
TRACKING&lt;br /&gt;
&lt;br /&gt;
 int[item] stolen&lt;br /&gt;
 advevent adj&lt;br /&gt;
 record[string] happenings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
YOUR COMBAT OPTIONS&lt;br /&gt;
&lt;br /&gt;
 advevent[int] opts&lt;br /&gt;
 advevent[int] custom&lt;br /&gt;
 advevent[int] queue&lt;br /&gt;
 int[string] blacklist&lt;br /&gt;
 string batround_insert&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== Other Useful Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|monster_stat}}{{Function|&lt;br /&gt;
name=monster_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;att&amp;quot;,&amp;quot;def&amp;quot;. or &amp;quot;hp&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s monster_attack(), monster_defense(), and monster_hp() functions. Please use this function instead of the ASH functions, since the value may differ if you have enqueued actions causing BatBrain to predictively alter the monster&#039;s stats.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_stat}}{{Function|&lt;br /&gt;
name=my_stat|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which}}|&lt;br /&gt;
p1desc={{pspan|which}} can be &amp;quot;hp&amp;quot;,&amp;quot;mp&amp;quot;, &amp;quot;Muscle&amp;quot;, &amp;quot;Mysticality&amp;quot;, or &amp;quot;Moxie&amp;quot;|&lt;br /&gt;
}}&lt;br /&gt;
This function wraps ASH&#039;s my_hp(), my_mp(), and my_buffedstat() functions. Anytime you&#039;re checking any of these five stats, please use this function rather than the ASH functions, for the same reason as above.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|happened}}{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|skill|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|item|occurrence}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=happened|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|advevent|occurrence}}|&lt;br /&gt;
p1desc={{pspan|occurrence}} is the advevent ID you want to check|&lt;br /&gt;
}}&lt;br /&gt;
Use this function to check if an action has already happened during this combat.  For example, if you have already used a seal tooth on a previous round, or you have enqueued a seal tooth, happened(&amp;quot;use 2&amp;quot;) will return true.  In addition to canonical action ID&#039;s (BALLS syntax), BatBrain also gives you a few other handles for special events: crit, shieldcrit, smusted, stolen, icecapstun, hipster_stats, sealwail, and lackstool.&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7941</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7941"/>
		<updated>2013-11-14T16:33:25Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: &amp;#039;retal&amp;#039; keyword&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  Most of BatBrain&#039;s knowledge about items, skills, equipment, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is unused.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|nohit&lt;br /&gt;
|This monster never hits.&lt;br /&gt;
|-&lt;br /&gt;
|nomiss&lt;br /&gt;
|This monster never misses (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|nostun&lt;br /&gt;
|The monster is completely immune to stuns and staggers of any duration.&lt;br /&gt;
|-&lt;br /&gt;
|nomultistun&lt;br /&gt;
|The monster is immune to multi-round stunners, such as Entangling Noodles.&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|You cannot use items in combat with this monster.  If a value is specified, it should be a float representing the monster&#039;s chance of blocking item use.&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|As with noitems above, but for skills.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|retal X&lt;br /&gt;
|Use this to specify retaliation damage (damage dealt to you when you succeed with a melee attack) as a spread.&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7294</id>
		<title>Zlib</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Zlib&amp;diff=7294"/>
		<updated>2013-10-27T06:21:01Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: add list_contains()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:ZLib (zlib.ash)}}&lt;br /&gt;
{{Attention|&lt;br /&gt;
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.&lt;br /&gt;
}}&lt;br /&gt;
== About ZLib ==&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== String Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|excise}}{{Function|&lt;br /&gt;
name=excise|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|source}}|&lt;br /&gt;
parameter2={{Param|string|start}}|&lt;br /&gt;
parameter3={{Param|string|end}}|&lt;br /&gt;
p1desc=The original {{pspan|source}} string|&lt;br /&gt;
p2desc={{pspan|start}} after this string|&lt;br /&gt;
p3desc={{pspan|end}} before this string|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|equals}}{{Function|&lt;br /&gt;
name=equals|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|s1}}|&lt;br /&gt;
parameter2={{Param|string|s2}}|&lt;br /&gt;
p1desc={{pspan|s1}} is a string.|&lt;br /&gt;
p2desc={{pspan|s2}} is the string to compare with {{pspan|s1}}.|&lt;br /&gt;
}}&lt;br /&gt;
Since string comparisons in ASH using == and != are case-insensitive, this function allows you to strictly compare two strings, including case sensitivity.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint}}{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=vprint|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|string|color}}|&lt;br /&gt;
parameter3={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} and {{pspan|color}} are used as in the function {{f|print}}|&lt;br /&gt;
p2desc={{pspan|level}} controls the return value and specifies the verbosity level of the message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Having a boolean return value (as opposed to ASH&#039;s print returning void) allows you to include helpful information in your script easily, without needing to significantly edit your code.  For example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
// add debugging info to an if check:&lt;br /&gt;
if (somevar == 2 &amp;amp;&amp;amp; vprint(&amp;quot;somevar equals 2&amp;quot;,10)) dosomething();&lt;br /&gt;
// add additional info to a return true/false:&lt;br /&gt;
if (everythingsgreat) return vprint(&amp;quot;Everything&#039;s great!&amp;quot;,7);&lt;br /&gt;
   else return vprint(&amp;quot;Everything is not great.&amp;quot;,-7);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Secondly, level represents the verbosity of the message.  ZLib includes a script setting called &amp;quot;verbosity&amp;quot;.  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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations for Verbosity Levels in vprint()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
0: abort error&lt;br /&gt;
&lt;br /&gt;
+/- 1: absolutely essential (and non-cluttering) information -- use very sparingly, since a verbosity of 1 is basically &amp;quot;silent mode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+/- 2: important and useful info -- this should generally be your base level for your most important messages&lt;br /&gt;
&lt;br /&gt;
+/- 4: interesting but non-essential information&lt;br /&gt;
&lt;br /&gt;
+/- 6: info which an overly curious person might like to see on their CLI&lt;br /&gt;
&lt;br /&gt;
+/- 10: details which are only helpful for debugging, such as &amp;quot;begin/end functionname()&amp;quot; or &amp;quot;current value of variable: value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will allow users who want extra levels of detail printed to see that detail without cluttering the CLI for users who don&#039;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.&lt;br /&gt;
&lt;br /&gt;
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&#039;t be calling vprint() with the color parameter, unless you want to specify a different color or override the default colors.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|vprint_html}}{{Function|&lt;br /&gt;
name=vprint_html|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|message}}|&lt;br /&gt;
parameter2={{Param|int|level}}|&lt;br /&gt;
p1desc={{pspan|message}} is used as in the function {{f|print_html}}|&lt;br /&gt;
p2desc={{pspan|level}} is a verbosity reference|&lt;br /&gt;
}}&lt;br /&gt;
Same as vprint() above, but wraps {{f|print_html}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|normalized}}{{Function|&lt;br /&gt;
name=normalized|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|mixvar}}|&lt;br /&gt;
parameter2={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|mixvar}} is the string to normalize|&lt;br /&gt;
p2desc={{pspan|type}} is the datatype to normalize to, which can be any primitive type or any typed constant.  You can also specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot;, for a comma-delimited list of the given type.|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|mixvar}}, normalized to the specified KoLmafia {{pspan|type}}. For example, normalized(&amp;quot;badger&amp;quot;, &amp;quot;familiar&amp;quot;) would return &amp;quot;Astral Badger&amp;quot;.  It can also normalize comma-delimited lists of any of these types if you specify &amp;quot;list of &amp;lt;type&amp;gt;&amp;quot; for {{pspan|type}}.  For example, normalized(&amp;quot;bloop, dair go, possess&amp;quot;, &amp;quot;list of monster&amp;quot;) would return &amp;quot;Blooper, Dairy Goat, Possessed Silverware Drawer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|join}}{{Function|&lt;br /&gt;
name=join|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string [int]|pieces|ag=t}}|&lt;br /&gt;
parameter2={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|pieces}} is a map of strings which you want to join into a single string.|&lt;br /&gt;
p2desc={{pspan|glue}} is the string to put between the pieces.|&lt;br /&gt;
}}&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_contains}}{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_contains|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|needle}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join().|&lt;br /&gt;
p2desc={{pspan|needle}} is the entry to check for.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
Returns true if {{pspan|list}} contains {{pspan|needle}}.  Avoids false positives which could result from using contains_text().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_add}}{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_add|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|add}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|add}} is the entry to add to the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;d&amp;quot;) would return &amp;quot;a, b, c, d&amp;quot;, but list_add(&amp;quot;a, b, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;a, b, c&amp;quot;, since the entry &amp;quot;a&amp;quot; already exists.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|list_remove}}{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=list_remove|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|list}}|&lt;br /&gt;
parameter2={{Param|string|del}}|&lt;br /&gt;
parameter3={{Param|string|glue}}|&lt;br /&gt;
p1desc={{pspan|list}} is a glue-delimited string list such as returned by join() above.|&lt;br /&gt;
p2desc={{pspan|del}} is the entry to remove from the list.|&lt;br /&gt;
p3desc={{pspan|glue}} is optional (defaults to &amp;quot;, &amp;quot;) and represents the delimiter for the list.|&lt;br /&gt;
}}&lt;br /&gt;
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(&amp;quot;a, b, c&amp;quot;,&amp;quot;a&amp;quot;) would return &amp;quot;b, c&amp;quot;, and list_remove(&amp;quot;a, a, b, b, c, c&amp;quot;, &amp;quot;a&amp;quot;) would return &amp;quot;b, b, c, c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|rnum}}{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|int|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=rnum|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
parameter2={{Param|int|place}}|&lt;br /&gt;
p1desc={{pspan|n}} is a number|&lt;br /&gt;
p2desc={{pspan|place}} is the number of decimal places to round to|&lt;br /&gt;
}}&lt;br /&gt;
Returns your number {{pspan|n}} as a human-readable string, appropriate to the user&#039;s computer&#039;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&#039;s. Examples: rnum(12580) =&amp;gt; &amp;quot;12,580&amp;quot;, rnum(3.14152964,3) =&amp;gt; &amp;quot;3.142&amp;quot;, rnum(4.00008) =&amp;gt; &amp;quot;4&amp;quot;, rnum(123456789.87654321) =&amp;gt; &amp;quot;123,456,789.88&amp;quot;.  Recommended as a substitute for to_string(int).&lt;br /&gt;
&lt;br /&gt;
== Number Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|abs}}{{Function|&lt;br /&gt;
name=abs|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|n}}|&lt;br /&gt;
p1desc={{pspan|n}} is any number.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the absolute value of the number {{pspan|n}}.  Don&#039;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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|minmax}}{{Function|&lt;br /&gt;
name=minmax|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|float|a}}|&lt;br /&gt;
parameter2={{Param|float|min}}|&lt;br /&gt;
parameter3={{Param|float|max}}|&lt;br /&gt;
p1desc={{pspan|a}} is the original number|&lt;br /&gt;
p2desc={{pspan|min}} is the minimum return value|&lt;br /&gt;
p3desc={{pspan|max}} is the maximum return value|&lt;br /&gt;
}}&lt;br /&gt;
Returns {{pspan|a}}, but no less than {{pspan|min}} and no more than {{pspan|max}}.  Another function common to many languages.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|set_avg}}{{Function|&lt;br /&gt;
name=set_avg|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|float|to_add}}|&lt;br /&gt;
parameter2={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|to_add}} is the data point to add|&lt;br /&gt;
p2desc={{pspan|which_prop}} is the property to add data to|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;4.0:3&amp;quot;, with 4.0 being the average of the three numbers added and 3 being the amount of numbers averaged.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_avg}}{{Function|&lt;br /&gt;
name=get_avg|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|which_prop}}|&lt;br /&gt;
p1desc={{pspan|which_prop}} is the property to access|&lt;br /&gt;
}}&lt;br /&gt;
Returns an average value set by set_avg().&lt;br /&gt;
&lt;br /&gt;
{{HideLink|eval}}{{Function|&lt;br /&gt;
name=eval|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|string|expression}}|&lt;br /&gt;
parameter2={{Param|float [string]|values|ag=t}}|&lt;br /&gt;
p1desc={{pspan|expression}} is the base expression|&lt;br /&gt;
p2desc={{pspan|values}} is a map of values to replace|&lt;br /&gt;
}}&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
== Script Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|check_version}}{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|proj}}|&lt;br /&gt;
parameter3={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is the script name, which must match the page source of the {{pspan|thread}} being parsed|&lt;br /&gt;
p2desc={{pspan|proj}} is the name of the SVN project name to check.|&lt;br /&gt;
p3desc={{pspan|thread}} is the script&#039;s thread number on kolmafia.us|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=check_version|&lt;br /&gt;
return_type=string|&lt;br /&gt;
parameter1={{Param|string|soft}}|&lt;br /&gt;
parameter2={{Param|string|prop}}|&lt;br /&gt;
parameter3={{Param|string|this_version}}|&lt;br /&gt;
parameter4={{Param|int|thread}}|&lt;br /&gt;
p1desc={{pspan|soft}} is as above.|&lt;br /&gt;
p2desc={{pspan|prop}} is used as part of the name of the property saved to user preferences.|&lt;br /&gt;
p3desc={{pspan|this_version}} is the version of the script currently running|&lt;br /&gt;
p4desc={{pspan|thread}} is as above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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&#039;s kolmafia.us thread -- and if the project is hosted on SourceForge, an additional link to the changelog there.&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;nowiki&amp;gt;&amp;quot;&amp;lt;b&amp;gt;&amp;lt;/nowiki&amp;gt;{{pspan|soft}} {{pspan|version}}&amp;lt;nowiki&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;&amp;lt;/nowiki&amp;gt; for the version info to be successfully parsed. Optionally, you may include &amp;lt;nowiki&amp;gt;&amp;quot;[requires revision XXXX]&amp;quot;&amp;lt;/nowiki&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
The return value of both versions is a blank string unless an update is/was found, in which case it is a &amp;lt;nowiki&amp;gt;&amp;lt;div class=&#039;versioninfo&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; 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 &amp;quot;zversions.txt&amp;quot;.  Example:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
check_version(&amp;quot;Hardcore Checklist&amp;quot;,&amp;quot;checklist&amp;quot;,&amp;quot;1.2.7&amp;quot;,1045);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_current_map}}{{Function|&lt;br /&gt;
name=load_current_map|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|map_name}}|&lt;br /&gt;
parameter2={{Param|aggregate|destination}}|&lt;br /&gt;
p1desc={{pspan|map_name}} is the name of the map, without the file extension|&lt;br /&gt;
p2desc={{pspan|destination}} is a previously-declared map to load with data|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;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 &amp;quot;.txt&amp;quot; in the {{pspan|map_name}} parameter.)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|setvar}}{{Function|&lt;br /&gt;
name=setvar|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|name}}|&lt;br /&gt;
parameter2={{Param|mixed|dfault}}|&lt;br /&gt;
p1desc={{pspan|name}} is the name of the setting|&lt;br /&gt;
p1desc={{pspan|dfault}} can be any primitive or ASH type (e.g. item, effect, coinmaster, etc.), but not an array, map, or record.|&lt;br /&gt;
}}&lt;br /&gt;
This function ensures that a ZLib script setting called {{pspan|name}} exists.  If not, it creates it and sets it to {{pspan|dfault}}.  If the setting already exists, it normalizes it to the same type as {{pspan|dfault}}, but otherwise does nothing.  Note that this function is for initializing settings, not for editing existing settings.  That is done by calling ZLib in the CLI.&lt;br /&gt;
&lt;br /&gt;
==== For Users ====&lt;br /&gt;
&lt;br /&gt;
* Script settings are now all saved in one place, separate from mafia properties. I&#039;ve read more than one post wishing that script-defined settings and mafia properties would be separate. This provides a solution.&lt;br /&gt;
* 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&#039;t need to reset them!&lt;br /&gt;
* To see all of your current settings, type &amp;quot;zlib vars&amp;quot; in the CLI. You can also type &amp;quot;zlib &amp;lt;whatever&amp;gt;&amp;quot; to see a list of current settings and values containing &amp;lt;whatever&amp;gt;.  To change a setting, type &amp;quot;zlib settingname = value&amp;quot;. If you&#039;re adjusting threshold, you can use &amp;quot;up&amp;quot; or &amp;quot;down&amp;quot; as the value to adjust your threshold relatively. This is almost exactly as convenient as mafia settings (possibly more so since you don&#039;t need to open a text file to find setting names!).&lt;br /&gt;
* If for some reason you prefer to open a text file, ZLib settings are stored in a file called vars_myname.txt in your data directory.&lt;br /&gt;
* Scripts that use Zlib script settings will only create these settings when you run them for the first time.  Attempting to edit a nonexisting setting won&#039;t work, so you&#039;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.&lt;br /&gt;
&lt;br /&gt;
==== For Script Authors ====&lt;br /&gt;
&lt;br /&gt;
* 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 (&amp;quot;zlib nonexistentsetting = value&amp;quot; will fail).&lt;br /&gt;
* Settings are only stored if you run a script that defines/uses them. So your settings file will not contain any extraneous unused settings.&lt;br /&gt;
* Script authors can now test for a setting&#039;s existence, which means you can check to see if a user has used a given script. It&#039;s almost as good as a script_exists() function. This can allow scripts to work together with other scripts, if they exist!&lt;br /&gt;
* 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 &amp;quot;threshold&amp;quot; mafia setting. Changing a single setting can now change the behavior of every script that accesses that setting.&lt;br /&gt;
&lt;br /&gt;
==== Functional Details ====&lt;br /&gt;
&lt;br /&gt;
When importing ZLib, it loads a map of your script settings from vars_myname.txt. It is a basic string[string] map called vars. To access a script setting within an ASH script, use vars[varname]. To check if a setting exists you can simply use if (vars contains varname).&lt;br /&gt;
&lt;br /&gt;
When a script calls setvar(&amp;quot;threshold&amp;quot;,4), ZLib checks to see if a variable called &amp;quot;threshold&amp;quot; already exists in vars. 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 &amp;quot;threshold&amp;quot; does not exist in vars, it creates it, sets it to 4, and saves the updated map back to vars_myname.txt.&lt;br /&gt;
&lt;br /&gt;
==== Choosing Setting Names ====&lt;br /&gt;
&lt;br /&gt;
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. &#039;&#039;&#039;Please think carefully about your setting names.&#039;&#039;&#039; If you have a setting named &amp;quot;setting1&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Use a name that clearly identifies what the setting is/does.&lt;br /&gt;
&lt;br /&gt;
2. Prefix your setting names with a script identifier. For example, here are some of my One-Click Wossname script settings:&lt;br /&gt;
&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
setvar(&amp;quot;ocw_warplan&amp;quot;,&amp;quot;optimal&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_change_to_meat&amp;quot;,true);&lt;br /&gt;
setvar(&amp;quot;ocw_nunspeed&amp;quot;,false);&lt;br /&gt;
setvar(&amp;quot;defaultoutfit&amp;quot;,&amp;quot;current&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_f_default&amp;quot;,&amp;quot;zombie&amp;quot;);&lt;br /&gt;
setvar(&amp;quot;ocw_m_default&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
Those settings which are specific to OCW are prefixed with &amp;quot;ocw_&amp;quot; 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 &amp;quot;defaultoutfit&amp;quot; will be used by nearly all of my adventuring scripts that swap outfits, so no prefix is given.&lt;br /&gt;
&lt;br /&gt;
== Adventuring Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|be_good}}{{Function|&lt;br /&gt;
name=be_good|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|johnny}}|&lt;br /&gt;
p1desc={{pspan|johnny}} is the thing you want to check -- usually an item or familiar|&lt;br /&gt;
}}&lt;br /&gt;
This function, originally created to check whether items were allowed in the Bees Hate You path, has been expanded to an all-purpose check to see whether something is acceptable in your current path.  For example, in a Trendy path, outdated items would not be_good.  Likewise, during Bees Hate You, a familiar containing a &#039;b&#039; would not be_good.  In Fistcore, anything you hold in your hands is not allowed.  And so forth.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|mall_val}}{{Function|&lt;br /&gt;
name=mall_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
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.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is optional, default false. If true, the function will avoid calling mall_price and use only historical_price, regardless of age.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;t have mall access).  You&#039;ll generally call this with only one of the two parameters.&lt;br /&gt;
&lt;br /&gt;
If you want to only use historical_price: mall_val(someitem, true)&lt;br /&gt;
If you want to only use mall price: mall_val(someitem,0)&lt;br /&gt;
If you want to use historical prices no more than 2 days old, otherwise use mall price: mall_val(someitem,3)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|sell_val}}{{Function|&lt;br /&gt;
name=sell_val|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|item|it}}|&lt;br /&gt;
parameter2={{Param|float|expirydays}}|&lt;br /&gt;
parameter3={{Param|boolean|combatsafe}}|&lt;br /&gt;
p1desc={{pspan|it}} is the item being valued.|&lt;br /&gt;
p2desc={{pspan|expirydays}} is the same as in mall_val() above.|&lt;br /&gt;
p3desc={{pspan|combatsafe}} is also as in mall_val() above.|&lt;br /&gt;
}}&lt;br /&gt;
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&#039;s junk which probably won&#039;t sell.  In that case it returns the item&#039;s autosell value.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|tower_items}}{{Function|&lt;br /&gt;
name=tower_items|&lt;br /&gt;
aggregate=true|&lt;br /&gt;
return_type=boolean [string]|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=tower_items|&lt;br /&gt;
aggregate=true|&lt;br /&gt;
return_type=boolean [string]|&lt;br /&gt;
parameter1={{Param|boolean|combat_safe}}|&lt;br /&gt;
p1desc={{pspan|combat_safe}} is optional.  Supply it as true if you are in combat.|&lt;br /&gt;
}}&lt;br /&gt;
This handy function returns a map of the items you definitely need (value: true) or might need (value: false) to pass the entryway and climb the tower.  You can check (tower_items() contains X) to determine whether an item has a nonzero chance of being required for the tower, or check tower_items(X) to determine whether an item has a 100% chance of being needed (i.e. it was indicated necessary by your telescope).  If you haven&#039;t yet checked your telescope yet this run, it will also do that to populate the relevant mafia properties, unless you have supplied the optional {{pspan|combat_safe}} parameter as true (you can&#039;t access your telescope during combat).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|have_item}}{{Function|&lt;br /&gt;
name=have_item|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|string|to_lookup}}|&lt;br /&gt;
p1desc={{pspan|to_lookup}} is the item to count|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|is_goal}}{{Function|&lt;br /&gt;
name=is_goal|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|stat|whichstat}}|&lt;br /&gt;
p1desc={{pspan|whichstat}} is the stat to check|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;level X&amp;quot; or &amp;quot;X muscle&amp;quot; as a goal.  Additionally, the function treats your primestat as a permanent goal until you are level 13.  So for both a level 9 Sauceror or a level 10 Seal Clubber who set &amp;quot;200 mysticality&amp;quot; as a goal, is_goal($stat[mysticality]) would return true.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|isxpartof}}{{Function|&lt;br /&gt;
name=isxpartof|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|child}}|&lt;br /&gt;
parameter2={{Param|item|ancestor}}|&lt;br /&gt;
p1desc={{pspan|child}} is the ingredient/component you want to check.|&lt;br /&gt;
p2desc={{pspan|ancestor}} is the concoction you want to check.|&lt;br /&gt;
}}&lt;br /&gt;
In the sentence &amp;quot;child is X part of ancestor&amp;quot;, 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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|has_goal}}{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|item|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=has_goal|&lt;br /&gt;
return_type=float|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the item, monster or locationto check|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
These functions also have an optional boolean parameter, usespec.  If supplied as true, these functions will use speculative values.  (See &amp;quot;whatif&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
{{HideLink|obtain}}{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=obtain|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|string|condition}}|&lt;br /&gt;
parameter3={{Param|location|place}}|&lt;br /&gt;
parameter4={{Param|string|filter}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity of the item or choice adventure desired|&lt;br /&gt;
p2desc={{pspan|condition}} is the item or choice adventure to use as a goal|&lt;br /&gt;
p3desc={{pspan|location}} is the place to adventure to obtain your goal|&lt;br /&gt;
p4desc={{pspan|filter}} is an optional combat filter used the same as in {{f|adventure}}|&lt;br /&gt;
}}&lt;br /&gt;
Attempts to get {{pspan|qty}} (minus existing) of {{pspan|condition}}, either by purchasing (if you have the KoLmafia preference set), pulling from Hangk&#039;s, or adventuring at the specified {{pspan|place}}. It also works with choice adventures.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|use_upto}}{{Function|&lt;br /&gt;
name=use_upto|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|qty}}|&lt;br /&gt;
parameter2={{Param|item|thing}}|&lt;br /&gt;
parameter3={{Param|boolean|purchase}}|&lt;br /&gt;
p1desc={{pspan|qty}} is the quantity to use|&lt;br /&gt;
p2desc={{pspan|thing}} is the item to use|&lt;br /&gt;
p3desc={{pspan|purchase}} is true if KoLmafia should purchase extras if you don&#039;t already have {{pspan|qty}}|&lt;br /&gt;
}}&lt;br /&gt;
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}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|resist}}{{Function|&lt;br /&gt;
name=resist|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|element|resist_it}}|&lt;br /&gt;
parameter2={{Param|boolean|really}}|&lt;br /&gt;
p1desc={{pspan|resist_it}} is the element to resist|&lt;br /&gt;
p2desc={{pspan|really}} is true to actually attemp resistance, false to check only|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|my_defstat}}{{Function|&lt;br /&gt;
name=my_defstat|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|boolean|usespec}}|&lt;br /&gt;
p1desc={{pspan|usespec}} is optional.  If true, uses speculative values rather than real values.|&lt;br /&gt;
}}&lt;br /&gt;
Returns the value of your buffed defense stat, taking into account Hero of the Half-Shell.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|get_safemox}}{{Function|&lt;br /&gt;
name=get_safemox|&lt;br /&gt;
return_type=int|&lt;br /&gt;
parameter1={{Param|location|where}}|&lt;br /&gt;
p1desc={{pspan|where}} is the location to check for safe moxie|&lt;br /&gt;
}}&lt;br /&gt;
Using mafia&#039;s location/monster data, returns the safe moxie of a given zone {{pspan|where}}.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|auto_mcd}}{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|int|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|monster|check_me}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=auto_mcd|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|location|check_me}}|&lt;br /&gt;
p1desc={{pspan|check_me}} is the int, monster or location to check|&lt;br /&gt;
}}&lt;br /&gt;
If your ZLib setting &amp;quot;automcd&amp;quot; is true, automatically adjusts your mind-control device for maximum stat gains based on safe moxie and your ZLib &amp;quot;threshold&amp;quot; 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&#039;t currently access an mcd-changing device).&lt;br /&gt;
&lt;br /&gt;
{{HideLink|best_fam}}{{Function|&lt;br /&gt;
name=best_fam|&lt;br /&gt;
return_type=familiar|&lt;br /&gt;
parameter1={{Param|string|type}}|&lt;br /&gt;
p1desc={{pspan|type}} is the type of familiar ability to check for|&lt;br /&gt;
}}&lt;br /&gt;
Returns your heaviest familiar of a given type (currently possible: items, meat, produce, stat, delevel). If your ZLib &amp;quot;is_100_run&amp;quot; setting is anything other than $familiar[none], returns that familiar (so you don&#039;t have to make the check in your script).&lt;br /&gt;
&lt;br /&gt;
== Kmail Functions ==&lt;br /&gt;
&lt;br /&gt;
{{HideLink|load_kmail}}{{Function|&lt;br /&gt;
name=load_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|calledby}}|&lt;br /&gt;
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 &amp;quot;ZLib-powered-script&amp;quot;.|&lt;br /&gt;
}}&lt;br /&gt;
This function parses your kmail inbox in a single server hit and loads it into the global variable &amp;quot;mail&amp;quot;, which is of type kmessage[int].  A kmessage is a record type, with the following fields:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record kmessage {&lt;br /&gt;
   int id;                   // message id&lt;br /&gt;
   string type;              // possible values observed thus far: normal, giftshop&lt;br /&gt;
   int fromid;               // sender&#039;s playerid (0 for npc&#039;s)&lt;br /&gt;
   int azunixtime;           // KoL server&#039;s unix timestamp&lt;br /&gt;
   string message;           // message (not including items/meat)&lt;br /&gt;
   int[item] items;          // items included in the message&lt;br /&gt;
   int meat;                 // meat included in the message&lt;br /&gt;
   string fromname;          // sender&#039;s playername&lt;br /&gt;
   string localtime;         // your local time according to your KoL account, human-readable string&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|process_kmail}}{{Function|&lt;br /&gt;
name=process_kmail|&lt;br /&gt;
return_type=void|&lt;br /&gt;
parameter1={{Param|string|functionname}}|&lt;br /&gt;
p1desc={{pspan|functionname}} specifies the name of a function designed to parse kmail.|&lt;br /&gt;
}}&lt;br /&gt;
If you liked load_kmail(), you&#039;ll like this even better.  First off, this function loads your kmail into the mail variable if you haven&#039;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.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example which will delete all messages from your lovely Pen Pal:&lt;br /&gt;
{{CodeSample|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
boolean no_penpal(kmessage m) {&lt;br /&gt;
   if (m.fromname == &amp;quot;Your Pen Pal&amp;quot;) return true;&lt;br /&gt;
   return false;&lt;br /&gt;
}&lt;br /&gt;
process_kmail(&amp;quot;no_penpal&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{HideLink|send_gift}}{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=send_gift|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is a map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message|&lt;br /&gt;
}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{HideLink|kmail}}{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|string|recipient}}|&lt;br /&gt;
parameter2={{Param|string|message}}|&lt;br /&gt;
parameter3={{Param|int|meat}}|&lt;br /&gt;
parameter4={{Param|int [item]|goodies|ag=t}}|&lt;br /&gt;
parameter5={{Param|string|inside_note}}|&lt;br /&gt;
p1desc={{pspan|recipient}} is the player to send to|&lt;br /&gt;
p2desc={{pspan|message}} is the outside message|&lt;br /&gt;
p3desc={{pspan|meat}} is the amount of meat to send|&lt;br /&gt;
p4desc={{pspan|goodies}} is an optional map of items &amp;amp; amounts to send|&lt;br /&gt;
p5desc={{pspan|inside_note}} is an optional inside message if sent as a gift|&lt;br /&gt;
}}&lt;br /&gt;
{{Function|&lt;br /&gt;
name=kmail|&lt;br /&gt;
return_type=boolean|&lt;br /&gt;
parameter1={{Param|kmessage|km}}|&lt;br /&gt;
p1desc={{pspan|km}} allows you to send a kmail supplied in kmessage format.  The only thing unusual here is that the &amp;quot;fromname&amp;quot; field will be used as the recipient.  The other fields will be used appropriately to call the above kmail function.|&lt;br /&gt;
}}&lt;br /&gt;
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 &amp;quot;\n&amp;quot; to specify a new line in the {{pspan|message}}.&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&amp;lt;p&amp;gt;See the thread for ZLib on the mafia forum [http://kolmafia.us/showthread.php?2072 here].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]][[Category:ASH Function Libraries]]&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7940</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7940"/>
		<updated>2013-10-08T05:21:33Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: /* Special */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  Most of BatBrain&#039;s knowledge about items, skills, equipment, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|The action is only valid underwater.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is unused.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|nohit&lt;br /&gt;
|This monster never hits.&lt;br /&gt;
|-&lt;br /&gt;
|nomiss&lt;br /&gt;
|This monster never misses (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|nostun&lt;br /&gt;
|The monster is completely immune to stuns and staggers of any duration.&lt;br /&gt;
|-&lt;br /&gt;
|nomultistun&lt;br /&gt;
|The monster is immune to multi-round stunners, such as Entangling Noodles.&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|You cannot use items in combat with this monster.  If a value is specified, it should be a float representing the monster&#039;s chance of blocking item use.&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|As with noitems above, but for skills.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
	<entry>
		<id>https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7939</id>
		<title>Batfactors</title>
		<link rel="alternate" type="text/html" href="https://wiki.kolmafia.us/index.php?title=Batfactors&amp;diff=7939"/>
		<updated>2013-10-08T05:20:46Z</updated>

		<summary type="html">&lt;p&gt;Zarqon: underwater keyword&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}{{DISPLAYTITLE:batfactors (batfactors.txt)}}&lt;br /&gt;
== What is batfactors? ==&lt;br /&gt;
batfactors.txt is a data file used by [[BatBrain]], containing information about all the various factors pertinent to battle.  These are saved in a data-entry-friendly format rather than just saving a map of advevents, which would be bulkier and harder to edit.  Most of BatBrain&#039;s knowledge about items, skills, equipment, etc. is found in this file.  As it is publicly editable on the Map Manager, a guide to understanding the format could be handy for someone looking to either add new content or fix old or previously unspaded content.&lt;br /&gt;
&lt;br /&gt;
== The Format ==&lt;br /&gt;
&lt;br /&gt;
Like all mafia data files, batfactors is a map file, in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
record combat_rec {&lt;br /&gt;
   string ufname;          // user-friendly name, not really used by BatBrain&lt;br /&gt;
   string dmg;             // damage to monster&lt;br /&gt;
   string pdmg;            // damage to player&lt;br /&gt;
   string special;         // comma-delimited list of other action results&lt;br /&gt;
};&lt;br /&gt;
combat_rec [string, int] factors;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the map has two indices.  The first string represents the category.  The second index is the integer identifying the relevant item/skill/familiar.  For example the &amp;quot;bander&amp;quot; category, which contains information about your Bandersnatch&#039;s enhancements to combat skills, is indexed by skill number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Category&lt;br /&gt;
!Indexed by&lt;br /&gt;
!What?&lt;br /&gt;
|-&lt;br /&gt;
|bander&lt;br /&gt;
|skill number&lt;br /&gt;
|Your Bandersnatch&#039;s enhancements to the specified skill.&lt;br /&gt;
|-&lt;br /&gt;
|chef&lt;br /&gt;
|staff item number&lt;br /&gt;
|Jiggle results for the specified chefstaff.&lt;br /&gt;
|-&lt;br /&gt;
|crown&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the Crown of Thrones when the specified familiar is enthroned.&lt;br /&gt;
|-&lt;br /&gt;
|effect&lt;br /&gt;
|effect number&lt;br /&gt;
|Average per-round results when you have the specified effect active (e.g. passive damage).&lt;br /&gt;
|-&lt;br /&gt;
|fam&lt;br /&gt;
|familiar number&lt;br /&gt;
|Results for the specified familiar.&lt;br /&gt;
|-&lt;br /&gt;
|gear&lt;br /&gt;
|equipment item number&lt;br /&gt;
|Average per-round results when you have the specified item equipped.&lt;br /&gt;
|-&lt;br /&gt;
|hatrack&lt;br /&gt;
|hat item number&lt;br /&gt;
|Familiar results for your Mad Hatrack when it has the specified hat equipped.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|item number&lt;br /&gt;
|Results for throwing the specified combat item.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|arbitrary index&lt;br /&gt;
|Special monster attributes such as resistances, damage caps, and immunities.  This category is a bit special (see below).&lt;br /&gt;
|-&lt;br /&gt;
|scare&lt;br /&gt;
|pants item number&lt;br /&gt;
|Familiar results for your Fancypants Scarecrow when it has the specified pants equipped.&lt;br /&gt;
|-&lt;br /&gt;
|skill&lt;br /&gt;
|skill number&lt;br /&gt;
|Results for casting the specified combat skill.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After these important identifiers comes the actual information.  The first field, ufname, is merely to make the data file easy to read and isn&#039;t really used by BatBrain when reading the file.  The remaining three fields contain all the information and need to be formatted in a certain way to be understood, but I believe you&#039;ll find that format both intuitive and easy to edit.&lt;br /&gt;
&lt;br /&gt;
== Spreads in Batfactors ==&lt;br /&gt;
&lt;br /&gt;
The dmg and pdmg fields contain damage information, which is converted to a spread (float[element] map) in BatBrain.  The format is versatile and can include formulas and any of BatBrain&#039;s fvars.  Since this value is handled by ASH&#039;s [[modifier_eval]](), any of those key letters or text functions will also work.  Basically damage is expressed as&lt;br /&gt;
&lt;br /&gt;
 amount elements&lt;br /&gt;
&lt;br /&gt;
where amount is the damage formula and elements is a comma (but not space!)-delimited list of elements, using &amp;quot;none&amp;quot; for physical damage, or &amp;quot;perfect&amp;quot; for always-correctly-tuned damage.  If the action does only physical damage, elements (and the preceding space) may be omitted.  If multiple elements are present, the damage in amount will be equally distributed among those elements.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|deals 10 physical damage&lt;br /&gt;
|-&lt;br /&gt;
| -10&lt;br /&gt;
|heals 10 hit points&lt;br /&gt;
|-&lt;br /&gt;
|10*L&lt;br /&gt;
|deals 10 times your level in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|myhp/2&lt;br /&gt;
|deals half of your current hitpoints in physical damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky&lt;br /&gt;
|deals 10 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|10 spooky,hot&lt;br /&gt;
|deals 5 spooky damage and 5 hot damage&lt;br /&gt;
|-&lt;br /&gt;
|10 hot,cold,spooky,sleaze,stench&lt;br /&gt;
|deals 2 each of hot, cold, spooky, sleaze, and stench damage (2 prismatic damage)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For cases where the damage is not equally distributed among elements, the above pattern may be repeated, separated by a pipe:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Examples&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;3 hot|7 spooky&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 3 hot damage and 7 spooky damage&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;50 hot,cold|4 hot&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|deals 29 hot damage and 25 cold damage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special ==&lt;br /&gt;
&lt;br /&gt;
Of course, events may have many results besides just damage, and that is all contained in the special field.  The special field, quite simply, is a comma (and space)-delimited list of keywords and values, like so:&lt;br /&gt;
&lt;br /&gt;
 keyword1 value1, keyword2 value2, keyword3 value3&lt;br /&gt;
&lt;br /&gt;
As few as 0 keywords and values may be present.  For numeric values such as MP or meat, formulas may be used since (as with the spreads above) these values will be handled by [[modifier_eval]]().  Here are all the keywords BatBrain presently understands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Meaning of Value&lt;br /&gt;
|-&lt;br /&gt;
|aoe&lt;br /&gt;
|For skills with an area of effect, specifies the maximum number of monsters the skill affects.&lt;br /&gt;
|-&lt;br /&gt;
|att&lt;br /&gt;
|Monster attack modifier.&lt;br /&gt;
|-&lt;br /&gt;
|def&lt;br /&gt;
|Monster defense modifier.&lt;br /&gt;
|-&lt;br /&gt;
|stun&lt;br /&gt;
|Number of rounds the monster is stunned by this action, on average.  Defaults to 1 if no value is specified.&lt;br /&gt;
|-&lt;br /&gt;
|mp&lt;br /&gt;
|Amount of MP gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|meat&lt;br /&gt;
|Amount of meat gained/lost.&lt;br /&gt;
|-&lt;br /&gt;
|item&lt;br /&gt;
|A semicolon+space-delimited list of item names.  This action results in one of the items from this list.  Estimated profit averages the value of these items.&lt;br /&gt;
|-&lt;br /&gt;
|monster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event only happens for monsters specified here.&lt;br /&gt;
|-&lt;br /&gt;
|notmonster&lt;br /&gt;
|A monster name, or multiple pipe-delimited names. This event happens for any monster except those specified here.&lt;br /&gt;
|-&lt;br /&gt;
|phylum&lt;br /&gt;
|A phylum name.  This event only applies to monsters of the specified phylum.&lt;br /&gt;
|-&lt;br /&gt;
|stats&lt;br /&gt;
|Substats earned, formatted as &amp;lt;nowiki&amp;gt;Mus|Mys|Mox&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|If specified at all, this action is a custom action and should not be used in regular automation.  The optional value represents the type of custom action (runaway, yellow, attract, banish, copy, etc).&lt;br /&gt;
|-&lt;br /&gt;
|rate&lt;br /&gt;
|For familiars only (which includes hatrack and scare categories).  The action rate of the familiar, expressed as a percent (1.0 = 100%).&lt;br /&gt;
|-&lt;br /&gt;
|!!&lt;br /&gt;
|Note. Usually used to explain something BatBrain is currently unable of knowing or tracking, i.e. unspaded data, ongoing damage, or some other strange mechanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some keywords have no values.  BatBrain merely checks for the presence of the keyword to determine the relevant information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Presence Indicates&lt;br /&gt;
|-&lt;br /&gt;
|once&lt;br /&gt;
|The action can only be used once per combat.&lt;br /&gt;
|-&lt;br /&gt;
|endscombat&lt;br /&gt;
|The action automatically ends combat.&lt;br /&gt;
|-&lt;br /&gt;
|retal&lt;br /&gt;
|The results happen when the monster successfully hits you.&lt;br /&gt;
|-&lt;br /&gt;
|onhit&lt;br /&gt;
|The results happen when you hit the monster with a melee attack.&lt;br /&gt;
|-&lt;br /&gt;
|oncrit&lt;br /&gt;
|The results happen when you get a critical hit.&lt;br /&gt;
|-&lt;br /&gt;
|underwater&lt;br /&gt;
|This item or skill is only valid underwater.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The &amp;quot;monster&amp;quot; Category ==&lt;br /&gt;
&lt;br /&gt;
The monster category is handled differently to the other categories.  The monster attributes are not loaded into an advevent, so it is not handled by to_event() as all the other categories are.  Here are the key differences:&lt;br /&gt;
&lt;br /&gt;
First of all, the integer index is meaningless since ASH has no to_int(monster).  Instead, the ufname field is used, and must be the name of a monster.&lt;br /&gt;
&lt;br /&gt;
Secondly, the dmg field does not contain damage information, but rather monster resistances/vulnerabilities, still expressed as a spread.  For each element, 0 is normal, 1.0 is immunity, and -1.0 is vulnerability.  Normal elemental resistances/vulnerabilities are already calculated by BatBrain, so you only need to include this information if the monster has exceptional resistances.  These resistances will overwrite the existing resistances on a per-element basis.&lt;br /&gt;
&lt;br /&gt;
The pdmg field is unused.&lt;br /&gt;
&lt;br /&gt;
Finally, the special field contains an entirely new set of keywords, which are only for use in the monster category:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Keyword&lt;br /&gt;
!Value/Indicates&lt;br /&gt;
|-&lt;br /&gt;
|nohit&lt;br /&gt;
|This monster never hits.&lt;br /&gt;
|-&lt;br /&gt;
|nomiss&lt;br /&gt;
|This monster never misses (e.g. gremlins).&lt;br /&gt;
|-&lt;br /&gt;
|nostun&lt;br /&gt;
|The monster is completely immune to stuns and staggers of any duration.&lt;br /&gt;
|-&lt;br /&gt;
|nomultistun&lt;br /&gt;
|The monster is immune to multi-round stunners, such as Entangling Noodles.&lt;br /&gt;
|-&lt;br /&gt;
|seal&lt;br /&gt;
|The monster is a seal and can only be damaged by clubs.&lt;br /&gt;
|-&lt;br /&gt;
|noitems (X)&lt;br /&gt;
|You cannot use items in combat with this monster.  If a value is specified, it should be a float representing the monster&#039;s chance of blocking item use.&lt;br /&gt;
|-&lt;br /&gt;
|noskills (X)&lt;br /&gt;
|As with noitems above, but for skills.&lt;br /&gt;
|-&lt;br /&gt;
|maxround X&lt;br /&gt;
|Use this to specify combats of unusual durations (e.g. &amp;quot;maxround 50&amp;quot; for basement monsters).&lt;br /&gt;
|-&lt;br /&gt;
|group X&lt;br /&gt;
|Use this to specify group monsters, where X is the amount of monsters in the group (integer).&lt;br /&gt;
|-&lt;br /&gt;
|damagecap X&lt;br /&gt;
|Use this to specify the monster&#039;s soft damage cap boundary (integer).&lt;br /&gt;
|-&lt;br /&gt;
|capexp X&lt;br /&gt;
|This is only meaningful with a soft damage cap, and specifies the exponent used to reduce damage above the boundary.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zarqon</name></author>
	</entry>
</feed>