<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://gswiki-archive.gs-game.uk/index.php?action=history&amp;feed=atom&amp;title=Lich%3AScript_foreach</id>
	<title>Lich:Script foreach - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://gswiki-archive.gs-game.uk/index.php?action=history&amp;feed=atom&amp;title=Lich%3AScript_foreach"/>
	<link rel="alternate" type="text/html" href="https://gswiki-archive.gs-game.uk/index.php?title=Lich:Script_foreach&amp;action=history"/>
	<updated>2026-11-11T21:19:07Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://gswiki-archive.gs-game.uk/index.php?title=Lich:Script_foreach&amp;diff=9809&amp;oldid=prev</id>
		<title>imported&gt;RINUALDO: /* What is it? */</title>
		<link rel="alternate" type="text/html" href="https://gswiki-archive.gs-game.uk/index.php?title=Lich:Script_foreach&amp;diff=9809&amp;oldid=prev"/>
		<updated>2023-06-03T19:03:51Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;What is it?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{3rd-party}}&lt;br /&gt;
=== What is it? ===&lt;br /&gt;
&lt;br /&gt;
foreach is a script for sending a series of commands for each item that matches its criteria.&lt;br /&gt;
&lt;br /&gt;
While not a full replacement for &amp;quot;proper&amp;quot; purpose-built Lich scripts, it is still frequently useful in its own regard.&lt;br /&gt;
&lt;br /&gt;
=== I don&amp;#039;t want to read docs, can you give me some examples?  ===&lt;br /&gt;
&lt;br /&gt;
 No rogues around?  Move all your boxes to your locker:  &lt;br /&gt;
  `;foreach box in inv; move to locker`&lt;br /&gt;
&lt;br /&gt;
 Own a gemcutter and want to cut all the gems in a container?  &lt;br /&gt;
  `;foreach gem in red sack; move to gemcutter; turn gemcutter; waitrt; move to blue sack`&lt;br /&gt;
&lt;br /&gt;
 Getting boxes picked?  &lt;br /&gt;
  `;foreach box in inv; get item;give item to Rogue;waitfor Rogue offers you;accept item`  &lt;br /&gt;
  *(This&amp;#039;ll only work if you&amp;#039;re fast enough to empty boxes while the rogue is picking)*&lt;br /&gt;
&lt;br /&gt;
 Checking for orb gems?  &lt;br /&gt;
  Sorcerer: `;foreach gem in queue bag;get item;waitmana 4;prep 704;cast item;pause;put item in reject bag`    &lt;br /&gt;
  Bard using `;loresing`: `;foreach gem in queue bag;get item;waitfor You remove;waitmana 20;;loresing purpose noun;pause;waitrt?;put item in reject bag`  &lt;br /&gt;
  While the script is paused, put the gem in the orb bag if it&amp;#039;s an orb.  `;unpause` it will put it in the reject bag if you&amp;#039;re still holding it.  &lt;br /&gt;
&lt;br /&gt;
 Bulk reading scrolls?  &lt;br /&gt;
  `;foreach scroll in inv; read item`&lt;br /&gt;
&lt;br /&gt;
 Accidentally move a bunch of items to the wrong container using foreach?  &lt;br /&gt;
  `;foreach in last;move to container` *(back where they started)*  &lt;br /&gt;
  *or* `;foreach in last;get item;move to correct backpack`&lt;br /&gt;
 &lt;br /&gt;
 Turning in gems or herbs for a bounty?  &lt;br /&gt;
  `;foreach name=uncut diamond in inv;get item;sell item`&lt;br /&gt;
  &lt;br /&gt;
 Don&amp;#039;t want to sell ALL of your diamonds for said bounty?  &lt;br /&gt;
  `;foreach first 7 name=uncut diamond in inv;get item;sell item`&lt;br /&gt;
  &lt;br /&gt;
 Doing a long task and want to be able to resume it later (possibly on the same source container?)  &lt;br /&gt;
  `;foreach unmarked gem in whereever;get item;do lots of things;mark item;return` as many times as needed, followed by  &lt;br /&gt;
  `;foreach marked gem in whereever;get item;unmark item`  &lt;br /&gt;
  (`whereever` must be a container in your inventory or your entire `inv`)&lt;br /&gt;
&lt;br /&gt;
 Need to ditch your sorcerer wands but want the wizard ones?  &lt;br /&gt;
  `;foreach q=/(bloodwood|twisted|yew|bone|glass|thanot) wand/ in inv;sell`  &lt;br /&gt;
  (This uses the new pattern matching introduced in 0.10.5)&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
=== That&amp;#039;s nice.  But what can it REALLY do?  ===&lt;br /&gt;
&lt;br /&gt;
== Usage == &lt;br /&gt;
  ;foreach** _[options]_ _[what]_ **in/on/under/behind** _targets_ [**;** _command1_**;** _command2_**;** ...]  &lt;br /&gt;
  ;foreach** _[options]_ _[what]_ **in/on/under/behind** _targets_ [**/** _command1_**/** _command2_**/** ...]  &lt;br /&gt;
  ;foreach** _[options]_ _[what]_ **in/on/under/behind** _targets_ [**|** _command1_**|** _command2_**|** ...]&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
&lt;br /&gt;
_options_ is a set of optional filters on what matching items `foreach` will operate on.  It can consist of zero or more&lt;br /&gt;
of the following:&lt;br /&gt;
 **registered** _or_ **unregistered**&lt;br /&gt;
  Only filters items that are registered or not registered.  This option is only available if the items in question&lt;br /&gt;
  are in your inventory or your premium locker.  (`locker manifest` is used to determine item status in the latter case,&lt;br /&gt;
  which is not available for standard lockers.)&lt;br /&gt;
 **marked** _or_ **unmarked**&lt;br /&gt;
  Only filters items that are marked or not marked as unsellable.  This has the same restrictions as the above.&lt;br /&gt;
  You can use this in conjunction with MARKing items as pat of your ;foreach script to prevent operating on the same&lt;br /&gt;
  item more than once in situations where you might run ;foreach multiple times.&lt;br /&gt;
 **unique**  &lt;br /&gt;
  Only the first item with any given full name will be matched.  This is global between all containers, so if you have&lt;br /&gt;
  the same item in two different containers only the first item (whichever `foreach` sees first) will be matched.&lt;br /&gt;
 **first _N_**  &lt;br /&gt;
  Stop after _N_ matching items have been encountered.  (The word `first` is optional)&lt;br /&gt;
 **skip _N_** _or_ **after _N_**  &lt;br /&gt;
  Skip the first _N_ matching items.&lt;br /&gt;
 **sort** or **sorted**  &lt;br /&gt;
  Sort items by name within each respective container.  Articles &amp;quot;a&amp;quot;, &amp;quot;an&amp;quot;, &amp;quot;some&amp;quot; and &amp;quot;the&amp;quot; are ignored when sorting.  &lt;br /&gt;
  Containers will still be handled one at a time, and the order of the containers themselves is not affected.&lt;br /&gt;
 **reverse** or **reversed**  &lt;br /&gt;
  Reverse the order of items within each container.  If used alone, this means the last item in each container in&lt;br /&gt;
  processed first and vice versa.  If used with **sorted**, items will be handled in descending alphabetical order&lt;br /&gt;
  rather than ascending.&lt;br /&gt;
  Containers will still be handled one at a time, and the order of the containers themselves is not affected.&lt;br /&gt;
  &lt;br /&gt;
Options are applied roughly in the order listed above.  You can combine **first** with **skip**: &lt;br /&gt;
`;foreach first 5 after 10` will match items 11 through 15.&lt;br /&gt;
&lt;br /&gt;
== What  ==&lt;br /&gt;
&lt;br /&gt;
_what_ allows you to filter the types of items `foreach` acts on.  It can be one of the following :&lt;br /&gt;
&lt;br /&gt;
 **type=**_pattern_   or  **t=**_pattern_  or  simply _pattern_   &lt;br /&gt;
   You can specify any type of item that Lich knows about.  Examples include &amp;#039;gem&amp;#039;, &amp;#039;wand&amp;#039; and &amp;#039;scroll&amp;#039; &lt;br /&gt;
   (which includes things like palimpests and other &amp;#039;alternate names&amp;#039; for scrolls).  `;foreach` by itself will show all&lt;br /&gt;
   the known types.  `;foreach in inv` with no commands will show the types of all items it finds.&lt;br /&gt;
   &lt;br /&gt;
   You can use `type=none` to explicitly find items that have no defined type according to Lich. &lt;br /&gt;
   &lt;br /&gt;
   **Note:** This is only as accurate as Lich&amp;#039;s own type data.  You may be able to get more accurate type data by downloading and running the `gameobjadd` script at startup.&lt;br /&gt;
&lt;br /&gt;
 **noun=**_pattern_   or  **n=**_pattern_   &lt;br /&gt;
   You can specify items that have a specific noun.  This must be an exact match (unless using wildcards).&lt;br /&gt;
   &lt;br /&gt;
 **name=**_pattern_   or  **m=**_pattern_   &lt;br /&gt;
   You can specify items that have a specific name.  This may or may not excludes the article, dpeend&lt;br /&gt;
   &lt;br /&gt;
 **fullname=**_pattern_   or  **f=**_pattern_   &lt;br /&gt;
   You can specify items that have a specific full name.  This is like `name=pattern`, but includes things like long &lt;br /&gt;
   descriptions.  See `;foreach in inv` to get a list of item full names.&lt;br /&gt;
   &lt;br /&gt;
 **quick=**_pattern_   or  **q=**_pattern_  &lt;br /&gt;
   Identical to `fullname`, except the ends of `pattern` are wildcarded.&lt;br /&gt;
   `;foreach q=red,blue ...` is equivalent to `;foreach f=*red*,*blue* ...`      &lt;br /&gt;
   &lt;br /&gt;
_pattern_ can be:&lt;br /&gt;
   `one or more words with including spaces`: Must be an exact match&lt;br /&gt;
   `*use*asterisks*for*wildcards`: Asterisks function as wildcards.  `name=*snowflake-cut*` will find anything with &lt;br /&gt;
    &amp;#039;snowflake-cut&amp;#039; anywhere in the name, for instance.&lt;br /&gt;
   `this,that`: Match any one of the options separated by commas.&lt;br /&gt;
   `blue sapphire,emerald,*diamond,*emerald,uncut ruby`: You can mix the above.&lt;br /&gt;
   `/(blue|white) crystal/`: You can match against a regular expression.  The slashes are required, and matching is &lt;br /&gt;
    always case-insensitive.&lt;br /&gt;
  &lt;br /&gt;
== Targets  ==&lt;br /&gt;
&lt;br /&gt;
_targets_ tells ;foreach where you want to look for the items.  You can specify one or more _target_, separated by commas.&lt;br /&gt;
&lt;br /&gt;
Each target can be the name of an actual container in game (&amp;quot;cloak&amp;quot;, &amp;quot;my backpack&amp;quot;, etc.), or one of the following options:&lt;br /&gt;
&lt;br /&gt;
 **inv** or **inventory**  &lt;br /&gt;
  Examines the contents all containers in your inventory.  Note that containers in your hands are not in your inventory.&lt;br /&gt;
  &lt;br /&gt;
 **floor** or **ground** or **room**  &lt;br /&gt;
  Examines items on the ground.  *The items, not their contents*&lt;br /&gt;
  &lt;br /&gt;
 **loot**  &lt;br /&gt;
  Examines the contents of containers that are on the ground -- boxes, disks, errantly left behind backpacks, etc.&lt;br /&gt;
  &lt;br /&gt;
  **locker**&lt;br /&gt;
  Examines the contents of your locker.  *If your locker is not open, ;foreach will open it and close it when it is done*.&lt;br /&gt;
  &lt;br /&gt;
 **worn**  &lt;br /&gt;
  Examines items in your inventory, *not* their contents.  Want to register everything you are wearing?  &lt;br /&gt;
  `foreach in worn; remove item;register item;wear item`&lt;br /&gt;
  &lt;br /&gt;
 **last** or **previous**  &lt;br /&gt;
  Last is a set of items that matches whatever the last run of foreach found.  You can use this to quickly undo if you&lt;br /&gt;
  manage to flub something up, like accidentally moving all of your inventory to your locker rather than just your boxes.&lt;br /&gt;
  &lt;br /&gt;
  When using **last**, the container items are reported in will be the container they started the previous run in -- not&lt;br /&gt;
  their current location.  So `;foreach in last;move to container` will move all (reachable) items to their original&lt;br /&gt;
  locations.&lt;br /&gt;
  &lt;br /&gt;
 **fastinv** or **qinv**  &lt;br /&gt;
  Similar to **inv**, but this uses container contents as currently known by Lich rather than doing an INV FULL.  This &lt;br /&gt;
  allows for faster startup, but with two caveats:&lt;br /&gt;
  - Item registration/marked status is unavailable.  (If you&amp;#039;re using one of the relevant _options_, this will be&lt;br /&gt;
    automatically converted to `inv`)&lt;br /&gt;
  - Containers that Lich doesn&amp;#039;t know the contents of will be skipped.  Most notably, if you have not LOOKed in a &lt;br /&gt;
    container since you have logged in, that container will be skipped.  Note that `;foreach in inv` does NOT satisfy&lt;br /&gt;
    the &amp;quot;looked in a container&amp;quot; requirement, but `;foreach in worn;look in item` probably will.&lt;br /&gt;
  &lt;br /&gt;
  If you specified a _what_ (above section), it will further restrict the list of what foreach is working on.&lt;br /&gt;
  &lt;br /&gt;
== Commands  ==&lt;br /&gt;
&lt;br /&gt;
Commands are separated by semicolons (`;`), slashes (`/`) or pipes (`|`).  You can only use type of separator in a given&lt;br /&gt;
invocation of Foreach -- it&amp;#039;s determined by the first one Foreach sees.  The examples here all use semicolons, but the other two formats may be useful if one of your commands needs to&lt;br /&gt;
actually include semicolons (aside from Lich scripts) -- say, the lines of `LORESING`.&lt;br /&gt;
&lt;br /&gt;
If you don&amp;#039;t give Foreach any commands to perform, it simply spits out a list of all the matching items and some&lt;br /&gt;
relevant stats.  This is useful, but usually you want to do something with items.&lt;br /&gt;
&lt;br /&gt;
Any command you can send to the game can be used with Foreach.  There&amp;#039;s also a few shortcuts, conveniences, and some&lt;br /&gt;
very basic scripting support (like waiting for a piece of text)&lt;br /&gt;
&lt;br /&gt;
For commands to be worthwhile, there needs to be an option to replace some part of the command with information about&lt;br /&gt;
the item.  For this, there&amp;#039;s some variable replacement rules -- as noted in the list below:&lt;br /&gt;
&lt;br /&gt;
== Replacements  ==&lt;br /&gt;
&lt;br /&gt;
Certain words within a command will be replaced with some detail about the current item.  Here&amp;#039;s a list.&lt;br /&gt;
&lt;br /&gt;
 **item**  &lt;br /&gt;
  The most important replacement.  This is replaced with an exact reference to an item using its unique ID.  It&amp;#039;s good&lt;br /&gt;
  for commands, but not particularly useful if you want to talk about the item in SAY or ECHO&lt;br /&gt;
&lt;br /&gt;
 **container**&lt;br /&gt;
  This is like `item`, but refers to the container the item was found in.  It won&amp;#039;t work properly if the item was not&lt;br /&gt;
  in a container (e.g. when using the `floor` and `worn` targets&lt;br /&gt;
  &lt;br /&gt;
  If you&amp;#039;re using the `last` target, `container` refers to the container the item was *originally* in.  Thus, the &lt;br /&gt;
  following will dump your inventory into your locker and then put it all back exactly how it was before, aside from&lt;br /&gt;
  container orders becoming flipped:&lt;br /&gt;
  &lt;br /&gt;
  `;foreach in inv;move to locker`  &lt;br /&gt;
  `;foreach in inv;move to container`&lt;br /&gt;
  &lt;br /&gt;
 **noun**&lt;br /&gt;
  This will be replaced with the item noun, e.g. `diamond`, `chest`, `scroll`.&lt;br /&gt;
  &lt;br /&gt;
 **name**&lt;br /&gt;
  This will be replaced with the item name, e.g. `uncut diamond`, `enruned mithril chest`, `old scroll`.&lt;br /&gt;
  &lt;br /&gt;
== Shortcuts  ==&lt;br /&gt;
For some normal game commands, typing `command` by itself is equivalent to `command item`.  Also, if one of these commands&lt;br /&gt;
is the first command in the list, an implicit `get item` might be automatically added provided that the command refers to&lt;br /&gt;
the item in some way.  These commands currently are: **drop**, **place**, **sell**, **put**, **appraise**, **read**, &lt;br /&gt;
**look**, **inspect** and **analyze** &lt;br /&gt;
&lt;br /&gt;
In addition, the following convenience shortcuts exist:&lt;br /&gt;
&lt;br /&gt;
 **move** _[what]_ **to** _where_  &lt;br /&gt;
  Shorthand for getting _what_ and then putting it in _where_.  If you omit _what_, &amp;#039;item&amp;#039; is assumed.  If _where_ is&lt;br /&gt;
  your locker, `;foreach` tries to open it (once) and, if successful, will close it when done.&lt;br /&gt;
  &lt;br /&gt;
  **mv** is shorthand for **move**&lt;br /&gt;
  &lt;br /&gt;
  Newer versions of foreach will use `_drag` (mimicking Stormfront drag-and-drop functionality) to reduce this from two&lt;br /&gt;
  commands to one when they think it is safe to do so.&lt;br /&gt;
&lt;br /&gt;
 **fastmove** _[what]_ **to** _where_  &lt;br /&gt;
  This is a somewhat faster version of the above, but it&amp;#039;s more prone to failing if you have oddly scripted containers&lt;br /&gt;
  involved or tasks that involve roundtime.  It utilizes typeahead -- namely sending the GET and PUT portions at the&lt;br /&gt;
  same time.&lt;br /&gt;
  &lt;br /&gt;
  This can be shortened as **fastmv**, **fmove** or **fmv**&lt;br /&gt;
&lt;br /&gt;
  Newer versions of foreach will use `_drag` (mimicking Stormfront drag-and-drop functionality) to reduce this from two&lt;br /&gt;
  commands to one when they think it is safe to do so.&lt;br /&gt;
&lt;br /&gt;
 **stash** _[what]_  &lt;br /&gt;
  This tries to store _what_ in your defined lootsack.  If it is full, it tries lootsack2 and so on.&lt;br /&gt;
  &lt;br /&gt;
  You can setup your lootsacks with `;vars` -- e.g. &lt;br /&gt;
  ```&lt;br /&gt;
  ;vars set lootsack=backpack&lt;br /&gt;
  ;vars set lootsack2=cloak&lt;br /&gt;
  ```&lt;br /&gt;
  &lt;br /&gt;
  Lootsacks that stop being in your inventory while **Foreach** is running will stop having items fed to them.  &lt;br /&gt;
&lt;br /&gt;
 **giveitem** [**to**] _player_&lt;br /&gt;
  If this is the *first* command, foreach adds an implicit `get item` before it.  &lt;br /&gt;
  Offers the item to the specified _player_ and waits for them to accept it before continuing.  &lt;br /&gt;
  &lt;br /&gt;
  This is only for players; NPCs don&amp;#039;t produce the appropriate &amp;#039;has accepted your offer&amp;#039; messaging.  That said, you&lt;br /&gt;
  don&amp;#039;t need to wait for NPCs to accept item offers anyways -- so just use `give` instead of `giveitem` for them.&lt;br /&gt;
  &lt;br /&gt;
 **appraise** or **appraise item**&lt;br /&gt;
  If this is the *first* command, foreach adds an implicit `get item` before it.  &lt;br /&gt;
  If you&amp;#039;re still holding the item at the end of running all of the commands, it will be returned to its parent &lt;br /&gt;
  container.   &lt;br /&gt;
  `appraise` by itself is shorthand for `appraise item`.&lt;br /&gt;
  &lt;br /&gt;
 **return**&lt;br /&gt;
  Equivalent to `put item in container`.  Returns whatever item Foreach is currently processing to whereever it &lt;br /&gt;
  originally found it.  Just like `put item in container`, this only works if the item is still in your hands (which&lt;br /&gt;
  you can take advantage of in your commands)&lt;br /&gt;
  &lt;br /&gt;
== Control  ==&lt;br /&gt;
  &lt;br /&gt;
 **echo** _message_  &lt;br /&gt;
  Echos the specified text to your client.  Not sent to the game.&lt;br /&gt;
  &lt;br /&gt;
 **pause**  &lt;br /&gt;
  Pauses ;foreach.  This is particularly useful if you&amp;#039;re using ;foreach to examine a set of items and making decisions&lt;br /&gt;
  about them.  For instance, you can write a script to test gems for orbs, pause after casting/singing, and then manually&lt;br /&gt;
  move the gem to the correct container based on the result before unpausing foreach to continue to the next gem.&lt;br /&gt;
  &lt;br /&gt;
 **sleep _time_**  &lt;br /&gt;
  Pauses ;foreach.  This is particularly useful if you&amp;#039;re using ;foreach to examine a set of items and making decisions&lt;br /&gt;
  about them.  For instance, you can write a script to test gems for orbs, pause after casting/singing, and then manually&lt;br /&gt;
  move the gem to the correct container based on the result before unpausing foreach to continue to the next gem.&lt;br /&gt;
  &lt;br /&gt;
 **waitrt** or **waitrt?**  &lt;br /&gt;
  Waits for roundtime to finish.  If you are not currently in RT, `waitrt` assumes you are about to be and waits&lt;br /&gt;
  it to happen.  `waitrt?` only waits if you are currently in RT, and might miss RT that you&amp;#039;re about to be in (i.e.&lt;br /&gt;
  due to a command you sent that the server hasn&amp;#039;t received yet.)&lt;br /&gt;
  &lt;br /&gt;
  These function identical to, and are implemented using, the corresponding functions in Lich.&lt;br /&gt;
&lt;br /&gt;
 **waitcastrt** or **waitcastrt?**&lt;br /&gt;
  As above, but waits for cast roundtime instead.  The same limitations and caveats apply.  &lt;br /&gt;
  &lt;br /&gt;
 **waitfor** _text_  &lt;br /&gt;
  Waits to see the specified bit of text.  Just like Lich&amp;#039;s `waitfor`, except only one string of text can be matched.&lt;br /&gt;
  Matching occurs in text mode (e.g. not the raw XML stream)&lt;br /&gt;
 &lt;br /&gt;
 **waitre** _pattern_  &lt;br /&gt;
  Waits for text matching the regular expression _pattern_.  Note that matching currently applies in XML mode.  &lt;br /&gt;
  You can use the `;logxml` or `;showxml` scripts to get an idea of what raw XML is being sent to the client.  &lt;br /&gt;
  [Regex101](https://regex101.com/) is a good resource for testing out patterns against text from the game before trying them for real.     &lt;br /&gt;
  &lt;br /&gt;
 **waitmana** _amount_ or **waitmp** _amount_  &lt;br /&gt;
  Waits until you have at least this much mana.&lt;br /&gt;
  &lt;br /&gt;
 **waithealth** _amount_ or **waithp** _amount_  &lt;br /&gt;
  Waits until you have at least this many health points.&lt;br /&gt;
  &lt;br /&gt;
 **waitspirit** _amount_ or **waitsp** _amount_  &lt;br /&gt;
  Waits until you have at least this much spirit.&lt;br /&gt;
  &lt;br /&gt;
 **waitstamina** _amount_ or **waitst** _amount_  &lt;br /&gt;
  Waits until you have at least this much stamina.&lt;br /&gt;
&lt;br /&gt;
=== Technical Explanation  ===&lt;br /&gt;
&lt;br /&gt;
If you think `;foreach` is doing something funny, here is a rough overview of the entire logic process from start to finish:&lt;br /&gt;
&lt;br /&gt;
Depending on the level of depth you want, either just read the bold parts, just read the first sentences, or read the whole thing.&lt;br /&gt;
&lt;br /&gt;
 **Option Parsing**: All of the options are interpreted, validated, and converted into a usable format&lt;br /&gt;
&lt;br /&gt;
 **Implicit Commands**: The command list is fixed up&lt;br /&gt;
   * Shortened versions of some verbs that Foreach has special handling for are expanded to their full versions.  This&lt;br /&gt;
     includes shortened versions of `drop`, `place`, `sell`, `appraise`, `register`, `get` and `take`.&lt;br /&gt;
   * If `stash` is in the command list, a list of lootsacks is built and the script exits if it can&amp;#039;t find any.&lt;br /&gt;
   * Any `giveitem` commands resolve to an exact player name in the room (and the script fails if no match is found).  &lt;br /&gt;
   * Commands like `place`, `sell`, `stash`, `appraise`, `mark` and `unmark` get the word `item` added to the end unless&lt;br /&gt;
     they already have something after them.  (`sell` becomes `sell item`, `sell emerald` is unchanged.)&lt;br /&gt;
   * *For the first command only:* An implicit `_remget item` (for worn targets) or `get item` (everything else&amp;quot;) is &lt;br /&gt;
     added for commands that are known to only work with an item in hand, such as `giveitem`, `place`, `sell`, `stash`, &lt;br /&gt;
     `appraise`, `register`, `mark` and `unmark`.  This only applies if the command string is `get item`, i.e. &lt;br /&gt;
     `get emerald` skips this check.&lt;br /&gt;
     - `_remget` is a hidden Foreach command equivalent to &amp;quot;remove item if its parent container is `_worn`, otherwise &lt;br /&gt;
       get it.&amp;quot;  &lt;br /&gt;
   * *If there is only one command*: For commands in the above list that don&amp;#039;t dispose of an item (so not `drop` or &lt;br /&gt;
     `sell`), an implicit `return` is added to the end of the list&lt;br /&gt;
     &lt;br /&gt;
 **Item Scanning**: Foreach builds a list of containers and items that are in them.&lt;br /&gt;
   At this point, `foreach` has an empty map of container IDs to names (with fake IDs `_worn` and `_ground` for those&lt;br /&gt;
   two targets), an empty map of container IDs to lists of container contents, and an empty list of containers to scan.&lt;br /&gt;
   Throughout this process, container names are mapped as they&amp;#039;re discovered (mainly for the item listing mode if you&lt;br /&gt;
   `;foreach in ...` with no commands), some container IDs are added to the &amp;quot;to scan&amp;quot; list, and each container along&lt;br /&gt;
   with its items are added to the &amp;quot;to filter&amp;quot; list.  If you&amp;#039;re filtering by status (marked/registered status, e.g. &lt;br /&gt;
   `;foreach unmarked`), a table is made of items and their registration statuses.&lt;br /&gt;
   &lt;br /&gt;
   * `inv` aborts if you specified at least one command but no item types to avoid affecting every single thing you own&lt;br /&gt;
     (unless you did `;foreach ALL in inv`).  Otherwise it reads all of your items (second level results) and their&lt;br /&gt;
     containers (first level results).  If you&amp;#039;re filtering by status, their status data is saved as well.&lt;br /&gt;
   * `last` simply restores the container/item data from the previous ;foreach invocation.  It fails immediately if &lt;br /&gt;
      you&amp;#039;re filtering by status.&lt;br /&gt;
   * `loot` adds each container on the ground to the &amp;quot;to scan&amp;quot; queue.  It fails immediately if you&amp;#039;re filtering by &lt;br /&gt;
      status, as that information cannot be determined for items on the ground.&lt;br /&gt;
   * If you are premium, `locker` determines your location and looks at the appropriate `locker manifest`.  If, for &lt;br /&gt;
     some reason, `;foreach` can&amp;#039;t determine your current location, it fails if you&amp;#039;re filtering by status (only the&lt;br /&gt;
     locker manifest can show marked/registered for contents of a locker), and otherwise adds the locker containers to &lt;br /&gt;
     the &amp;quot;to scan&amp;quot; queue.&lt;br /&gt;
   * `floor` (and synonyms) places all the contents of the room (GameObj.loot) into the `_ground` container.  Like &lt;br /&gt;
     `loot`, it fails immediately if you&amp;#039;re filtering by registration/mark status&lt;br /&gt;
   * `worn` places `GameObj.inv` into the `_worn` container.&lt;br /&gt;
   * Anything else is treated like a single container: If you are filtering by status and your target is `locker`&lt;br /&gt;
     (only possible for non-premium lockers), ;foreach exits immediately with an error.  Otherwise, it LOOKs in the &lt;br /&gt;
     container to get the game to send over its inventory data and determine what its ID and searches for status data&lt;br /&gt;
     (if needed, see the &amp;quot;To Scan&amp;quot; section)&lt;br /&gt;
     &lt;br /&gt;
   Then, if there are any containers to scan:&lt;br /&gt;
   * The `sorter` script is paused, if it is running, to avoid spam.&lt;br /&gt;
   * Each container is looked in (to get or refresh its inventory)&lt;br /&gt;
   * For each container: )&lt;br /&gt;
     * Its contents are added to the &amp;quot;to filter&amp;quot; list&lt;br /&gt;
     * If you are filtering by status and status data is unknown for this container: (The INV commands here are only done once and data saved for subsequent containers)&lt;br /&gt;
       If the container is in your right hand or left hand, an `INV HANDS FULL` to get its registration status&lt;br /&gt;
       Otherwise, an `INV FULL` is done, followed by an `INV HANDS FULL` if the container was not found in your inventory.&lt;br /&gt;
       If, after all of the above, ;foreach doesn&amp;#039;t have status data for the container (meaning it&amp;#039;s probably not in your inventory),&lt;br /&gt;
       it assumes that it won&amp;#039;t have status data for any of its contents either and exits.&lt;br /&gt;
   * The `sorter` script is resumed, if it was paused.&lt;br /&gt;
       &lt;br /&gt;
 **Item Sorting**: If the SORTED or REVERSED options are specified, they are applied to each container inventory. &lt;br /&gt;
&lt;br /&gt;
 **Item Filtering**: For each container and list of items in to_filter, items are filtered based on your criteria, &lt;br /&gt;
   including applying any options (e.g. `UNIQUE`, `MARKED`, `FIRST 5`).  If you&amp;#039;re filtering by status and any item is&lt;br /&gt;
   not found in the the table, `;foreach` complains loudly and exits.  This particular failure should never occur,&lt;br /&gt;
   since of all the related checks should have happened earlier.&lt;br /&gt;
       &lt;br /&gt;
   Any containers that have items left after the filtering phase are removed from the relevant tables.&lt;br /&gt;
   If no remaining items exist, ;foreach exits.&lt;br /&gt;
   &lt;br /&gt;
 **Snapshot**: At this point, ;foreach knows every single item and container it is going to work on.  This information&lt;br /&gt;
   is saved for later usage in `;foreach in last`, and then the execution phase begins&lt;br /&gt;
   &lt;br /&gt;
 **Execution**: For each container:&lt;br /&gt;
   * If there are no commands, pretty-print a list of matching contents in that container.&lt;br /&gt;
   * Otherwise, for each item in the container, for each command:&lt;br /&gt;
     * Replace &amp;quot;item&amp;quot;, &amp;quot;noun&amp;quot;, &amp;quot;name&amp;quot; and &amp;quot;container&amp;quot; with the item ID, item noun, item name and container ID.&lt;br /&gt;
     * If the command starts with `$lich_char` (usually `;`), run it.&lt;br /&gt;
     * If this is any of the convenience shortcuts (i.e. MOVE) or control commands (PAUSE), handle it.  Some noteworthy&lt;br /&gt;
       things:&lt;br /&gt;
       * MOVE/FASTMOVE will try to learn the ID of containers it is moving something to, since `_drag` only works with IDs.&lt;br /&gt;
         and allows movements to be done in one command rather than two.  If the IDs are known, it uses `_drag`.  It also&lt;br /&gt;
         has its own logic for adding an implicit &amp;#039;item&amp;#039; if needed since it is not at the end of the command.&lt;br /&gt;
       * STASH also tries to use _drag when possible, which is almost all the case since lootsack IDs are determined at startup&lt;br /&gt;
         and the IDs of &amp;#039;item&amp;#039; are always known.&lt;br /&gt;
     * Some commands define a &amp;quot;run this before the next command&amp;quot; procedure (usually consisting of &amp;#039;waitrt?&amp;#039; and&lt;br /&gt;
       sometimes waiting for a prompt).  Most commands (including anything sent natively to the game) will execute &lt;br /&gt;
       and clear this, but some control commands (like `waitfor`, `waitre`, `pause` and `sleep`) ignore it and let&lt;br /&gt;
       the next command in the list resolve it.  This prevents various issues like trying to `waitfor` a message that&lt;br /&gt;
       would scroll by while in roundtime, or the script waiting to pause (and thus preventing it from being unpaused&lt;br /&gt;
       until you are out of roundtime)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Third-Party Software}}&lt;br /&gt;
{{top}}&lt;/div&gt;</summary>
		<author><name>imported&gt;RINUALDO</name></author>
	</entry>
</feed>