jasonharper
Developer
r7525 introduces an experimental new ASH feature: plural typed constants. These allow you to easily do something with a list of specified objects, without having to replicate code or laboriously build up an array of the objects so that you can iterate over it. Here's a quick example:
The syntax is basically the same as the existing typed constant feature, but with an "s" or "es" after the type name. (The "es" case is there so that you can properly pluralize "class".) The text between the square brackets is interpreted as a comma-separated list of elements, each of which is converted to the specified type as if it were an individual constant. More details:
* The list can span multiple lines.
* Whitespace before or after elements is ignored.
* Completely empty elements are ignored (so that you can leave a comma at the end of the list).
* You can include a comma or closing square bracket in an element by writing it as "\," or "\]".
* All the other escape sequences allowed in strings are possible, such as "\n" (newline), "\t" (tab), and "\uXXXX" (Unicode character value). To put an actual backslash in an element, you have to write it as "\\".
The value generated by a plural constant is of type boolean[type], with the keys being the specified elements, and the boolean value always being true - although you won't normally do anything with the boolean, you'd use a foreach loop to iterate over the keys. You can assign a plural constant to a variable declared as that type, but note that the value differs from a normal map in three important respects:
* Since the expression that generates it is syntactically a constant, the value has to be immutable. If you were allowed to change it in any way, those changes would appear in every future use of the same constant.
* There can be multiple instances of the same key - $ints[1,1,2,3,5,8] is perfectly valid, and will result in the value 1 appearing twice in a foreach loop.
* The keys will appear in the order you wrote them, rather than being sorted alphanumerically as maps usually do.
In addition to being used in a foreach loop, plural constants also efficiently support membership testing via the 'contains' operator. Here's another example:
(Yes, that example could just as easily have been done with a switch statement.)
Iterating over an empty list is rather pointless, so plural constants with no elements are given a different meaning: they represent every value of the specified type, where this is practical. (The 'none' value, if defined for a given type, is omitted.) The biggest benefit here is $items[], which lets you loop over every defined item, more efficiently than you could otherwise write in a script (since the list is generated once per session and then cached), and without having to hard-code a maximum item ID number in your script. Example:
Enumeration of all possible values works with the following types:
* $booleans[] - false and true.
* $items[]
* $locations[]
* $classes[]
* $stats[] - Muscle, Mysticality, Moxie: the substat values are omitted.
* $skills[]
* $effects[]
* $familiars[]
* $slots[] - includes sticker slots and fake hands, which you might not want to consider as normal slots.
* $monsters[]
* $elements[] - includes slime now, and possibly other not-quite-elements like cute in the future.
The remaining types that can be used in plural constants require an explicit list of elements, since there are too many possible values:
* $ints[] - you don't have enough RAM to store a list with 4 billion elements.
* $floats[] - ditto.
* $strings[] - nobody has that much RAM.
Trivia: here are some KoL details that can now be easily determined.
Code:
foreach weapon in $items[star sword, star staff, star crossbow] {
if (available_amount(weapon) > 0) {
equip(weapon);
break;
}
}
The syntax is basically the same as the existing typed constant feature, but with an "s" or "es" after the type name. (The "es" case is there so that you can properly pluralize "class".) The text between the square brackets is interpreted as a comma-separated list of elements, each of which is converted to the specified type as if it were an individual constant. More details:
* The list can span multiple lines.
* Whitespace before or after elements is ignored.
* Completely empty elements are ignored (so that you can leave a comma at the end of the list).
* You can include a comma or closing square bracket in an element by writing it as "\," or "\]".
* All the other escape sequences allowed in strings are possible, such as "\n" (newline), "\t" (tab), and "\uXXXX" (Unicode character value). To put an actual backslash in an element, you have to write it as "\\".
The value generated by a plural constant is of type boolean[type], with the keys being the specified elements, and the boolean value always being true - although you won't normally do anything with the boolean, you'd use a foreach loop to iterate over the keys. You can assign a plural constant to a variable declared as that type, but note that the value differs from a normal map in three important respects:
* Since the expression that generates it is syntactically a constant, the value has to be immutable. If you were allowed to change it in any way, those changes would appear in every future use of the same constant.
* There can be multiple instances of the same key - $ints[1,1,2,3,5,8] is perfectly valid, and will result in the value 1 appearing twice in a foreach loop.
* The keys will appear in the order you wrote them, rather than being sorted alphanumerically as maps usually do.
In addition to being used in a foreach loop, plural constants also efficiently support membership testing via the 'contains' operator. Here's another example:
Code:
for hour from 1 to 12 {
print("It's " + hour + " o'clock.");
if ($ints[10, 2, 4] contains hour) {
print("Time to drink a Dr Pepper!");
}
}
Iterating over an empty list is rather pointless, so plural constants with no elements are given a different meaning: they represent every value of the specified type, where this is practical. (The 'none' value, if defined for a given type, is omitted.) The biggest benefit here is $items[], which lets you loop over every defined item, more efficiently than you could otherwise write in a script (since the list is generated once per session and then cached), and without having to hard-code a maximum item ID number in your script. Example:
Code:
foreach it in $items[] {
if (autosell_price(it) == 42) print(it);
}
Enumeration of all possible values works with the following types:
* $booleans[] - false and true.
* $items[]
* $locations[]
* $classes[]
* $stats[] - Muscle, Mysticality, Moxie: the substat values are omitted.
* $skills[]
* $effects[]
* $familiars[]
* $slots[] - includes sticker slots and fake hands, which you might not want to consider as normal slots.
* $monsters[]
* $elements[] - includes slime now, and possibly other not-quite-elements like cute in the future.
The remaining types that can be used in plural constants require an explicit list of elements, since there are too many possible values:
* $ints[] - you don't have enough RAM to store a list with 4 billion elements.
* $floats[] - ditto.
* $strings[] - nobody has that much RAM.
Trivia: here are some KoL details that can now be easily determined.
(but note that these counts include some historical locations and monsters that probably no longer exist.)> ash count($items[])
Returned: 4003
> ash count($locations[])
Returned: 196
> ash count($skills[])
Returned: 238
> ash count($monsters[])
Returned: 649
Last edited: