<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://gswiki.play.net/index.php?action=history&amp;feed=atom&amp;title=Lich%3AScript_allmine</id>
	<title>Lich:Script allmine - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://gswiki.play.net/index.php?action=history&amp;feed=atom&amp;title=Lich%3AScript_allmine"/>
	<link rel="alternate" type="text/html" href="https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;action=history"/>
	<updated>2026-07-14T04:33:47Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.12</generator>
	<entry>
		<id>https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260490&amp;oldid=prev</id>
		<title>TRIEX: /* Notes */</title>
		<link rel="alternate" type="text/html" href="https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260490&amp;oldid=prev"/>
		<updated>2026-07-13T19:32:05Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Notes&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:32, 13 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 86:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 86:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* The watchdog does not automatically return the character to the item&#039;s location or attempt to retrieve it. This is intentional — the script only alerts.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* The watchdog does not automatically return the character to the item&#039;s location or attempt to retrieve it. This is intentional — the script only alerts.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Whether&lt;/del&gt; &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;script&lt;/del&gt;-generated movement (as opposed to typed commands) &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;is&lt;/del&gt; intercepted by the movement block &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;has not been independently confirmed for every possible calling script; the&lt;/del&gt; watchdog&#039;s left-behind alert serves as a backstop regardless.&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Known&lt;/ins&gt; &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Issue: Script&lt;/ins&gt;-generated movement&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; from scripts like go2&lt;/ins&gt; (as opposed to typed commands) &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;are not&lt;/ins&gt; intercepted by the movement block&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;!&lt;/ins&gt; &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;The&lt;/ins&gt; watchdog&#039;s left-behind alert serves as a backstop regardless.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-added&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Script Source ==&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Script Source ==&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>TRIEX</name></author>
	</entry>
	<entry>
		<id>https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260482&amp;oldid=prev</id>
		<title>HORIBU1: /* Script Source */  switched to syntaxhighlight instead of pre tag for proper code highlights</title>
		<link rel="alternate" type="text/html" href="https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260482&amp;oldid=prev"/>
		<updated>2026-07-13T19:23:08Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Script Source: &lt;/span&gt;  switched to syntaxhighlight instead of pre tag for proper code highlights&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:23, 13 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 91:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 91:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Script Source ==&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Script Source ==&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;syntaxhighlight lang=&quot;ruby&quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-added&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=begin&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=begin&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 537:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 537:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  AllMine.run&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  AllMine.run&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-added&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>HORIBU1</name></author>
	</entry>
	<entry>
		<id>https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260470&amp;oldid=prev</id>
		<title>TRIEX: Adding example screenshot of in-game functionality</title>
		<link rel="alternate" type="text/html" href="https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260470&amp;oldid=prev"/>
		<updated>2026-07-13T16:14:04Z</updated>

		<summary type="html">&lt;p&gt;Adding example screenshot of in-game functionality&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 11:14, 13 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-added&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{3rd-party}}&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{3rd-party}}&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[File:Allmine.jpg|thumb|right|alt=Screenshot of script working in GSIV|Screenshot of script working in GSIV]]&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{script&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{script&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|title = AllMine&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|title = AllMine&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>TRIEX</name></author>
	</entry>
	<entry>
		<id>https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260468&amp;oldid=prev</id>
		<title>TRIEX: Correcting compatibility</title>
		<link rel="alternate" type="text/html" href="https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260468&amp;oldid=prev"/>
		<updated>2026-07-13T16:01:41Z</updated>

		<summary type="html">&lt;p&gt;Correcting compatibility&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 11:01, 13 July 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 4:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 4:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|title = AllMine&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|title = AllMine&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|author = Triex&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|author = Triex&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|compat = WR&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|compat = WR&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/WFE&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}}&lt;/div&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}}&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
  &lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;
  &lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>TRIEX</name></author>
	</entry>
	<entry>
		<id>https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260467&amp;oldid=prev</id>
		<title>TRIEX: &#039;AllMine&#039;&#039;&#039; is a Lich script that guards a placed All Mine item (a basket, bowl, or similar placeable object) against being accidentally left behind.</title>
		<link rel="alternate" type="text/html" href="https://gswiki.play.net/index.php?title=Lich:Script_allmine&amp;diff=260467&amp;oldid=prev"/>
		<updated>2026-07-13T16:00:09Z</updated>

		<summary type="html">&lt;p&gt;&amp;#039;AllMine&amp;#039;&amp;#039;&amp;#039; is a &lt;a href=&quot;/Lich&quot; title=&quot;Lich&quot;&gt;Lich&lt;/a&gt; script that guards a placed &lt;a href=&quot;/index.php?title=All_Mine&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;All Mine (page does not exist)&quot;&gt;All Mine&lt;/a&gt; item (a basket, bowl, or similar placeable object) against being accidentally left behind.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
{{3rd-party}}&lt;br /&gt;
{{script&lt;br /&gt;
|title = AllMine&lt;br /&gt;
|author = Triex&lt;br /&gt;
|compat = WR&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;AllMine&amp;#039;&amp;#039;&amp;#039; is a [[Lich]] script that guards a placed [[All Mine]] item (a basket, bowl, or similar placeable object like Dhu Kittens) against being accidentally left behind. All Mine items can only be picked up by their owner for a set window after being placed, but players who wander off or log out without retrieving one risk losing it once that window lapses. AllMine hard-blocks movement and logoff commands while the item is on the ground, and raises repeating alerts if it is left behind anyway.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Once armed, AllMine intercepts outgoing movement and quit/exit commands and refuses to send them to the game while the configured item remains on the ground in the current room. Sending the identical command a second time within 10 seconds overrides the block, so a deliberate decision to leave the item behind is still possible — the script only guards against accidental departures.&lt;br /&gt;
&lt;br /&gt;
If the item is left behind regardless (for example, if the block is paused, or the player disconnects), a background watchdog raises a repeating alert describing where the item was placed and when. The watchdog never attempts to retrieve the item automatically or move the character — it is alert-only by design.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
* Detects when the configured item is placed or dropped, and arms automatically&lt;br /&gt;
* Also arms if the item is already on the ground when the script starts, or if a held item transitions to the ground without a recognized message&lt;br /&gt;
* Hard-blocks compass movement, all documented GemStone IV movement styles (crawl, limp, march, sashay, skip, sneak, stride, stumble, trudge, prance, and normal walking), and QUIT/EXIT, while the item is on the ground&lt;br /&gt;
* 10-second identical re-send bypass, so a deliberate departure is one extra keystroke rather than a separate confirmation command&lt;br /&gt;
* Repeating alert (default every 15 seconds) if the item is left behind, silenced with a single command once acknowledged&lt;br /&gt;
* Recognizes when the item is recovered and lifts the block automatically&lt;br /&gt;
* Persists its state across a Lich restart, so a crash or disconnect while the item is deployed is not silent — the script announces the item&amp;#039;s last known location on the next launch&lt;br /&gt;
* Works with any All Mine item by noun (bowl, basket, etc.) — not hard-coded to one item&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* [[Lich]] 5, with Ruby-based script support&lt;br /&gt;
* GemStone IV, any supported front end (tested on Wrayth)&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Save the script as &amp;lt;code&amp;gt;allmine.lic&amp;lt;/code&amp;gt; in the Lich scripts directory. No dependencies beyond core Lich5.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Configure the noun of the item once, then start the monitor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre{{log2}}&amp;gt;&lt;br /&gt;
;allmine set bowl&lt;br /&gt;
;allmine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The monitor must be running for the movement block and watchdog to be active. If the item&amp;#039;s noun is changed while the monitor is already running, restart it so the detection patterns rebuild.&lt;br /&gt;
&lt;br /&gt;
== Commands ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine set &amp;lt;noun&amp;gt;&amp;lt;/code&amp;gt; || Configure the item&amp;#039;s noun (for example, &amp;lt;code&amp;gt;bowl&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine&amp;lt;/code&amp;gt; (no arguments) || Start the monitor&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine arm&amp;lt;/code&amp;gt; || Manually arm on a matching item already on the ground in the current room&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine status&amp;lt;/code&amp;gt; || Show current configuration and state&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine ack&amp;lt;/code&amp;gt; || Silence a left-behind alert without clearing the deployed state&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine clear&amp;lt;/code&amp;gt; || Manually clear the deployed state (for example, if the item was recovered by other means)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine pause&amp;lt;/code&amp;gt; || Disable the movement block; the watchdog continues to run&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine resume&amp;lt;/code&amp;gt; || Re-enable the movement block&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine debug&amp;lt;/code&amp;gt; || Toggle echoing of raw upstream command lines, for troubleshooting&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine verb add &amp;lt;verb&amp;gt;&amp;lt;/code&amp;gt; || Add a custom movement verb to the block list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;;allmine verb remove &amp;lt;verb&amp;gt;&amp;lt;/code&amp;gt; || Remove a previously added custom movement verb&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Default Blocked Commands ==&lt;br /&gt;
&lt;br /&gt;
* Compass directions: n, north, s, south, e, east, w, west, ne, northeast, nw, northwest, se, southeast, sw, southwest, u, up, d, down, out&lt;br /&gt;
* Movement verbs: go, climb, swim, jump, leap, dive, vault, enter, board, ride, walk, crawl, limp, march, sashay, skip, sneak, stride, stumble, trudge, prance&lt;br /&gt;
* Logoff: quit, exit&lt;br /&gt;
&lt;br /&gt;
Additional verbs can be added per character with &amp;lt;code&amp;gt;;allmine verb add &amp;lt;verb&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* The watchdog does not automatically return the character to the item&amp;#039;s location or attempt to retrieve it. This is intentional — the script only alerts.&lt;br /&gt;
* Whether script-generated movement (as opposed to typed commands) is intercepted by the movement block has not been independently confirmed for every possible calling script; the watchdog&amp;#039;s left-behind alert serves as a backstop regardless.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Script Source ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
=begin&lt;br /&gt;
&lt;br /&gt;
  allmine.lic - All Mine item guard&lt;br /&gt;
&lt;br /&gt;
  Prevents accidentally leaving a placed All Mine item (basket, bowl, etc.)&lt;br /&gt;
  behind when moving rooms or logging off. Hard-blocks movement/quit while&lt;br /&gt;
  the item is on the ground, with a 10-second re-send bypass. A watchdog&lt;br /&gt;
  thread fires repeating alerts (no auto-return) if the item is left behind&lt;br /&gt;
  anyway.&lt;br /&gt;
&lt;br /&gt;
    ;allmine set &amp;lt;noun&amp;gt;     configure the item noun (e.g. bowl)&lt;br /&gt;
    ;allmine arm            manually arm on an item already on the ground&lt;br /&gt;
    ;allmine status         show current state&lt;br /&gt;
    ;allmine ack            acknowledge/silence a left-behind alert&lt;br /&gt;
    ;allmine clear          manually clear deployed state&lt;br /&gt;
    ;allmine pause          disable the movement block (monitoring continues)&lt;br /&gt;
    ;allmine resume         re-enable the movement block&lt;br /&gt;
    ;allmine verb add &amp;lt;v&amp;gt;   add a custom movement verb to block&lt;br /&gt;
    ;allmine verb remove &amp;lt;v&amp;gt;&lt;br /&gt;
    ;allmine help           show help&lt;br /&gt;
&lt;br /&gt;
  Run with no arguments to start the monitor. Subcommands may be issued&lt;br /&gt;
  while the monitor runs; they modify shared settings and exit.&lt;br /&gt;
&lt;br /&gt;
  NOTE: It is unverified whether script-generated movement (e.g. go2&amp;#039;s&lt;br /&gt;
  fput) passes through UpstreamHook. If it bypasses the block, the&lt;br /&gt;
  watchdog alert still catches the left-behind item. Test live.&lt;br /&gt;
&lt;br /&gt;
        author: Triex&lt;br /&gt;
          game: GSIV&lt;br /&gt;
          tags: utility, allmine&lt;br /&gt;
       version: 0.3.1&lt;br /&gt;
&lt;br /&gt;
  changelog:&lt;br /&gt;
    0.3.1 (2026-07-13):&lt;br /&gt;
      Fix mojibake in bold alert text (replaced em dash with plain hyphen;&lt;br /&gt;
      file is now pure ASCII). Added full GSIV movement style verb list&lt;br /&gt;
      (crawl, limp, march, sashay, skip, sneak, stride, stumble, trudge,&lt;br /&gt;
      prance) plus walk -- previously only compass verbs like sashay&lt;br /&gt;
      passed through unblocked.&lt;br /&gt;
    0.3.0 (2026-07-13):&lt;br /&gt;
      Fix movement block never firing: hooks no longer touch CharSettings&lt;br /&gt;
      (unavailable in hook context); state mirrored into module ivars.&lt;br /&gt;
      Tolerant upstream command parsing (optional &amp;lt;c&amp;gt; prefix). Added&lt;br /&gt;
      ;allmine debug to echo raw upstream lines.&lt;br /&gt;
    0.2.0 (2026-07-13):&lt;br /&gt;
      Arm when the item is already on the ground at monitor start, when a&lt;br /&gt;
      held item transitions to ground loot (missed place message), or via&lt;br /&gt;
      manual ;allmine arm.&lt;br /&gt;
    0.1.0 (2026-07-13):&lt;br /&gt;
      Initial release. Deploy/pickup detection, hard-block with 10s&lt;br /&gt;
      re-send bypass, alert-only watchdog, crash persistence.&lt;br /&gt;
&lt;br /&gt;
=end&lt;br /&gt;
&lt;br /&gt;
module AllMine&lt;br /&gt;
  UP_HOOK   = &amp;#039;AllMine::upstream&amp;#039;&lt;br /&gt;
  DOWN_HOOK = &amp;#039;AllMine::downstream&amp;#039;&lt;br /&gt;
&lt;br /&gt;
  BYPASS_WINDOW  = 10   # seconds: identical re-sent command passes through&lt;br /&gt;
  ALERT_INTERVAL = 15   # seconds between repeating left-behind alerts&lt;br /&gt;
  POLL_INTERVAL  = 1    # watchdog poll rate&lt;br /&gt;
&lt;br /&gt;
  # Single-word directional commands (whole command must match).&lt;br /&gt;
  DIRS = %w[n north s south e east w west&lt;br /&gt;
            ne northeast nw northwest se southeast sw southwest&lt;br /&gt;
            u up d down out].freeze&lt;br /&gt;
&lt;br /&gt;
  # Verbs that take an argument and cause movement (first word must match).&lt;br /&gt;
  # Includes GSIV movement styles (confirmed via in-game MOVEMENT command:&lt;br /&gt;
  # Normal, Crawl, Limp, March, Sashay, Skip, Sneak, Stride, Stumble,&lt;br /&gt;
  # Trudge, Prance) plus other common movement verbs. Extend with&lt;br /&gt;
  # ;allmine verb add &amp;lt;verb&amp;gt;.&lt;br /&gt;
  MOVE_VERBS = %w[go climb swim jump leap dive vault enter board ride walk&lt;br /&gt;
                  crawl limp march sashay skip sneak stride stumble trudge prance].freeze&lt;br /&gt;
&lt;br /&gt;
  # Logoff commands (whole command must match).&lt;br /&gt;
  QUIT_CMDS = %w[quit exit].freeze&lt;br /&gt;
&lt;br /&gt;
  @last_blocked = nil&lt;br /&gt;
  @pending_deploy_at = nil&lt;br /&gt;
  @last_held_id = nil&lt;br /&gt;
  @loot_miss_count = 0&lt;br /&gt;
  @last_alert_at = Time.at(0)&lt;br /&gt;
  @pending_clear_at = nil&lt;br /&gt;
  @hs_noun = @hs_item_id = @hs_extra = nil&lt;br /&gt;
  @hs_deployed = @hs_paused = @hs_debug = false&lt;br /&gt;
&lt;br /&gt;
  def self.settings&lt;br /&gt;
    CharSettings[&amp;#039;allmine&amp;#039;] ||= {}&lt;br /&gt;
    CharSettings[&amp;#039;allmine&amp;#039;]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.bold(msg)&lt;br /&gt;
    _respond Lich::Messaging.monsterbold(msg)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.info(msg)&lt;br /&gt;
    _respond Lich::Messaging.msg_format(&amp;#039;teal&amp;#039;, &amp;quot;[AllMine] #{msg}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.caution(msg)&lt;br /&gt;
    _respond Lich::Messaging.msg_format(&amp;#039;orange&amp;#039;, &amp;quot;[AllMine] #{msg}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # ---------------------------------------------------------------- state&lt;br /&gt;
&lt;br /&gt;
  def self.deployed?&lt;br /&gt;
    settings[&amp;#039;deployed&amp;#039;] == true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.set_deployed(item_id)&lt;br /&gt;
    settings[&amp;#039;deployed&amp;#039;]  = true&lt;br /&gt;
    settings[&amp;#039;item_id&amp;#039;]   = item_id&lt;br /&gt;
    settings[&amp;#039;room_id&amp;#039;]   = (Room.current.id rescue nil)&lt;br /&gt;
    settings[&amp;#039;placed_at&amp;#039;] = Time.now.to_i&lt;br /&gt;
    settings[&amp;#039;acked&amp;#039;]     = false&lt;br /&gt;
    @loot_miss_count = 0&lt;br /&gt;
    sync_hook_state&lt;br /&gt;
    info &amp;quot;Your #{settings[&amp;#039;noun&amp;#039;]} (ID #{item_id || &amp;#039;unknown&amp;#039;}) is now on the ground in room #{settings[&amp;#039;room_id&amp;#039;] || &amp;#039;unmapped&amp;#039;}. Movement is guarded.&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.clear_deployed(reason)&lt;br /&gt;
    settings[&amp;#039;deployed&amp;#039;] = false&lt;br /&gt;
    settings[&amp;#039;item_id&amp;#039;]  = nil&lt;br /&gt;
    settings[&amp;#039;acked&amp;#039;]    = false&lt;br /&gt;
    @loot_miss_count = 0&lt;br /&gt;
    @pending_clear_at = nil&lt;br /&gt;
    sync_hook_state&lt;br /&gt;
    info &amp;quot;Your #{settings[&amp;#039;noun&amp;#039;]} has been recovered (#{reason}). Movement is no longer guarded.&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.item_on_ground?&lt;br /&gt;
    id = settings[&amp;#039;item_id&amp;#039;]&lt;br /&gt;
    if id&lt;br /&gt;
      GameObj.loot.to_a.any? { |o| o.id == id }&lt;br /&gt;
    else&lt;br /&gt;
      noun = settings[&amp;#039;noun&amp;#039;]&lt;br /&gt;
      return false unless noun&lt;br /&gt;
      GameObj.loot.to_a.any? { |o| o.noun == noun }&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.item_in_hands?&lt;br /&gt;
    id = settings[&amp;#039;item_id&amp;#039;]&lt;br /&gt;
    return false unless id&lt;br /&gt;
    [GameObj.right_hand, GameObj.left_hand].any? { |h| h &amp;amp;&amp;amp; h.id == id }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # ------------------------------------------------------------ movement&lt;br /&gt;
&lt;br /&gt;
  def self.blocked_command?(cmd)&lt;br /&gt;
    words = cmd.downcase.split&lt;br /&gt;
    return false if words.empty?&lt;br /&gt;
    first = words.first&lt;br /&gt;
    if words.length == 1&lt;br /&gt;
      return :quit if QUIT_CMDS.include?(first)&lt;br /&gt;
      return :move if DIRS.include?(first)&lt;br /&gt;
    end&lt;br /&gt;
    return :move if MOVE_VERBS.include?(first) || (@hs_extra || []).include?(first)&lt;br /&gt;
    false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # ---------------------------------------------------------------- hooks&lt;br /&gt;
&lt;br /&gt;
  # Hooks execute in Lich&amp;#039;s stream context, not this script&amp;#039;s thread, so&lt;br /&gt;
  # they must never touch CharSettings (script-scoped). All state they&lt;br /&gt;
  # need is mirrored into module ivars by sync_hook_state, which runs in&lt;br /&gt;
  # the script thread. set_deployed/clear_deployed also update the mirror&lt;br /&gt;
  # immediately.&lt;br /&gt;
  def self.sync_hook_state&lt;br /&gt;
    @hs_noun     = settings[&amp;#039;noun&amp;#039;]&lt;br /&gt;
    @hs_deployed = settings[&amp;#039;deployed&amp;#039;] == true&lt;br /&gt;
    @hs_paused   = settings[&amp;#039;paused&amp;#039;] == true&lt;br /&gt;
    @hs_item_id  = settings[&amp;#039;item_id&amp;#039;]&lt;br /&gt;
    @hs_extra    = (settings[&amp;#039;extra_verbs&amp;#039;] || []).dup&lt;br /&gt;
    @hs_debug    = settings[&amp;#039;debug&amp;#039;] == true&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.install_hooks&lt;br /&gt;
    noun = Regexp.escape(settings[&amp;#039;noun&amp;#039;])&lt;br /&gt;
    place_re  = /You carefully place your [^.]*\b#{noun} on the ground\./&lt;br /&gt;
    pickup_re = /You pick up [^.]*\b#{noun}\./&lt;br /&gt;
&lt;br /&gt;
    DownstreamHook.add(DOWN_HOOK, proc { |xml|&lt;br /&gt;
      begin&lt;br /&gt;
        if xml =~ place_re&lt;br /&gt;
          @pending_deploy_at = Time.now&lt;br /&gt;
        elsif xml =~ pickup_re &amp;amp;&amp;amp; @hs_deployed&lt;br /&gt;
          @pending_clear_at = Time.now # watchdog confirms and clears&lt;br /&gt;
        end&lt;br /&gt;
      rescue =&amp;gt; e&lt;br /&gt;
        respond &amp;quot;[AllMine] Downstream hook error: #{e}&amp;quot; rescue nil&lt;br /&gt;
      end&lt;br /&gt;
      xml&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
    UpstreamHook.add(UP_HOOK, proc { |line|&lt;br /&gt;
      begin&lt;br /&gt;
        respond &amp;quot;[AllMine DEBUG] upstream: #{line.inspect}&amp;quot; if @hs_debug&lt;br /&gt;
        next line unless @hs_deployed&lt;br /&gt;
        next line if @hs_paused&lt;br /&gt;
        # Client command framing is not documented; tolerate an optional&lt;br /&gt;
        # &amp;lt;c&amp;gt; prefix anywhere-leading, else take the raw line.&lt;br /&gt;
        cmd = line.sub(/\A\s*(?:&amp;lt;c&amp;gt;)?/, &amp;#039;&amp;#039;).strip&lt;br /&gt;
        next line if cmd.empty?&lt;br /&gt;
        kind = AllMine.blocked_command?(cmd)&lt;br /&gt;
        next line unless kind&lt;br /&gt;
&lt;br /&gt;
        on_ground = begin&lt;br /&gt;
          if @hs_item_id&lt;br /&gt;
            GameObj.loot.to_a.any? { |o| o.id == @hs_item_id }&lt;br /&gt;
          else&lt;br /&gt;
            GameObj.loot.to_a.any? { |o| o.noun == @hs_noun }&lt;br /&gt;
          end&lt;br /&gt;
        rescue&lt;br /&gt;
          true # if the check itself fails, block rather than risk the item&lt;br /&gt;
        end&lt;br /&gt;
        next line unless on_ground&lt;br /&gt;
&lt;br /&gt;
        key = cmd.downcase&lt;br /&gt;
        if @last_blocked &amp;amp;&amp;amp; @last_blocked[:cmd] == key &amp;amp;&amp;amp;&lt;br /&gt;
           (Time.now - @last_blocked[:time]) &amp;lt;= BYPASS_WINDOW&lt;br /&gt;
          @last_blocked = nil&lt;br /&gt;
          next line # intentional: identical command re-sent within window&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        @last_blocked = { cmd: key, time: Time.now }&lt;br /&gt;
        if kind == :quit&lt;br /&gt;
          AllMine.bold &amp;quot;*** YOUR #{@hs_noun.upcase} IS STILL ON THE GROUND - repeat #{cmd.upcase} within #{BYPASS_WINDOW} seconds to log off anyway. ***&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
          AllMine.bold &amp;quot;*** YOUR #{@hs_noun.upcase} IS STILL ON THE GROUND - repeat the command within #{BYPASS_WINDOW} seconds to leave anyway. ***&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        next nil&lt;br /&gt;
      rescue =&amp;gt; e&lt;br /&gt;
        respond &amp;quot;[AllMine] Upstream hook error: #{e}&amp;quot; rescue nil&lt;br /&gt;
        next line&lt;br /&gt;
      end&lt;br /&gt;
    })&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_hooks&lt;br /&gt;
    DownstreamHook.remove(DOWN_HOOK)&lt;br /&gt;
    UpstreamHook.remove(UP_HOOK)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # ------------------------------------------------------------- watchdog&lt;br /&gt;
&lt;br /&gt;
  def self.watchdog_tick&lt;br /&gt;
    sync_hook_state&lt;br /&gt;
    noun = settings[&amp;#039;noun&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
    # Track the id of a held item matching the noun, so a deploy can be&lt;br /&gt;
    # attributed to the exact item that just left our hands.&lt;br /&gt;
    [GameObj.right_hand, GameObj.left_hand].each do |h|&lt;br /&gt;
      @last_held_id = h.id if h &amp;amp;&amp;amp; h.id &amp;amp;&amp;amp; h.noun == noun&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Pickup message seen by the downstream hook: confirm and clear.&lt;br /&gt;
    if @pending_clear_at &amp;amp;&amp;amp; deployed?&lt;br /&gt;
      if settings[&amp;#039;item_id&amp;#039;].nil? || item_in_hands?&lt;br /&gt;
        clear_deployed(&amp;#039;picked up&amp;#039;)&lt;br /&gt;
        return&lt;br /&gt;
      elsif Time.now - @pending_clear_at &amp;gt; 3&lt;br /&gt;
        @pending_clear_at = nil # pickup message was for a different item&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Complete a pending deploy: item should now appear in room loot.&lt;br /&gt;
    if @pending_deploy_at&lt;br /&gt;
      match = nil&lt;br /&gt;
      if @last_held_id&lt;br /&gt;
        match = GameObj.loot.to_a.find { |o| o.id == @last_held_id }&lt;br /&gt;
      end&lt;br /&gt;
      match ||= GameObj.loot.to_a.find { |o| o.noun == noun }&lt;br /&gt;
      if match&lt;br /&gt;
        @pending_deploy_at = nil&lt;br /&gt;
        set_deployed(match.id)&lt;br /&gt;
      elsif Time.now - @pending_deploy_at &amp;gt; 5&lt;br /&gt;
        @pending_deploy_at = nil&lt;br /&gt;
        set_deployed(nil) # deploy seen but id unresolved; guard by noun&lt;br /&gt;
      end&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless deployed?&lt;br /&gt;
      # Backup arm: an item we were holding (matching noun) is now on the&lt;br /&gt;
      # ground - covers missed/unrecognized place messaging.&lt;br /&gt;
      if @last_held_id &amp;amp;&amp;amp; GameObj.loot.to_a.any? { |o| o.id == @last_held_id }&lt;br /&gt;
        set_deployed(@last_held_id)&lt;br /&gt;
      end&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Backup clear: item is back in our hands (missed pickup message).&lt;br /&gt;
    if item_in_hands?&lt;br /&gt;
      clear_deployed(&amp;#039;back in your hands&amp;#039;)&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Left-behind detection.&lt;br /&gt;
    left_behind = false&lt;br /&gt;
    here = (Room.current.id rescue nil)&lt;br /&gt;
    if here &amp;amp;&amp;amp; settings[&amp;#039;room_id&amp;#039;] &amp;amp;&amp;amp; here != settings[&amp;#039;room_id&amp;#039;]&lt;br /&gt;
      left_behind = true&lt;br /&gt;
      @loot_miss_count = 0&lt;br /&gt;
    elsif !item_on_ground?&lt;br /&gt;
      # Could be lag or an unmapped-room move; require persistence.&lt;br /&gt;
      @loot_miss_count += 1&lt;br /&gt;
      left_behind = true if @loot_miss_count &amp;gt;= 3&lt;br /&gt;
    else&lt;br /&gt;
      @loot_miss_count = 0&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if left_behind &amp;amp;&amp;amp; !settings[&amp;#039;acked&amp;#039;]&lt;br /&gt;
      if Time.now - @last_alert_at &amp;gt;= ALERT_INTERVAL&lt;br /&gt;
        @last_alert_at = Time.now&lt;br /&gt;
        where = settings[&amp;#039;room_id&amp;#039;] ? &amp;quot;room #{settings[&amp;#039;room_id&amp;#039;]} (;go2 #{settings[&amp;#039;room_id&amp;#039;]})&amp;quot; : &amp;#039;an unknown room&amp;#039;&lt;br /&gt;
        placed = settings[&amp;#039;placed_at&amp;#039;] ? Time.at(settings[&amp;#039;placed_at&amp;#039;]).strftime(&amp;#039;%H:%M&amp;#039;) : &amp;#039;?&amp;#039;&lt;br /&gt;
        bold &amp;quot;*** ALL MINE ALERT: Your #{settings[&amp;#039;noun&amp;#039;]} was left behind in #{where}, placed at #{placed}. Use ;allmine ack to silence this alert. ***&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # ------------------------------------------------------------- commands&lt;br /&gt;
&lt;br /&gt;
  def self.command(args)&lt;br /&gt;
    case args&lt;br /&gt;
    when /^set\s+(\w+)$/i&lt;br /&gt;
      settings[&amp;#039;noun&amp;#039;] = $1.downcase&lt;br /&gt;
      info &amp;quot;Item noun set to &amp;#039;#{settings[&amp;#039;noun&amp;#039;]}&amp;#039;. If the monitor is already running, restart it so the message patterns rebuild.&amp;quot;&lt;br /&gt;
    when /^status$/i&lt;br /&gt;
      info &amp;quot;Item noun: #{settings[&amp;#039;noun&amp;#039;] || &amp;#039;not set&amp;#039;}&amp;quot;&lt;br /&gt;
      if deployed?&lt;br /&gt;
        placed = settings[&amp;#039;placed_at&amp;#039;] ? Time.at(settings[&amp;#039;placed_at&amp;#039;]).strftime(&amp;#039;%Y-%m-%d %H:%M&amp;#039;) : &amp;#039;unknown&amp;#039;&lt;br /&gt;
        info &amp;quot;Deployed: yes - item ID #{settings[&amp;#039;item_id&amp;#039;] || &amp;#039;unknown&amp;#039;}, room #{settings[&amp;#039;room_id&amp;#039;] || &amp;#039;unknown&amp;#039;}, placed at #{placed}&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        info &amp;#039;Deployed: no&amp;#039;&lt;br /&gt;
      end&lt;br /&gt;
      info &amp;quot;Movement block paused: #{settings[&amp;#039;paused&amp;#039;] ? &amp;#039;yes&amp;#039; : &amp;#039;no&amp;#039;}&amp;quot;&lt;br /&gt;
      info &amp;quot;Custom movement verbs: #{(settings[&amp;#039;extra_verbs&amp;#039;] || []).empty? ? &amp;#039;none&amp;#039; : settings[&amp;#039;extra_verbs&amp;#039;].join(&amp;#039;, &amp;#039;)}&amp;quot;&lt;br /&gt;
      info &amp;quot;Monitor running: #{Script.list.count { |s| s.name == Script.current.name } &amp;gt; 1 ? &amp;#039;yes&amp;#039; : &amp;#039;no&amp;#039;}&amp;quot;&lt;br /&gt;
    when /^arm$/i&lt;br /&gt;
      noun = settings[&amp;#039;noun&amp;#039;]&lt;br /&gt;
      if noun.nil?&lt;br /&gt;
        caution &amp;#039;No item noun configured. Use ;allmine set &amp;lt;noun&amp;gt; first.&amp;#039;&lt;br /&gt;
      elsif (match = GameObj.loot.to_a.find { |o| o.noun == noun })&lt;br /&gt;
        set_deployed(match.id)&lt;br /&gt;
      else&lt;br /&gt;
        caution &amp;quot;No #{noun} was found on the ground in this room.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    when /^ack$/i&lt;br /&gt;
      settings[&amp;#039;acked&amp;#039;] = true&lt;br /&gt;
      info &amp;#039;Alert acknowledged. The deployed state remains until the item is recovered or cleared with ;allmine clear.&amp;#039;&lt;br /&gt;
    when /^clear$/i&lt;br /&gt;
      settings[&amp;#039;deployed&amp;#039;] = false&lt;br /&gt;
      settings[&amp;#039;item_id&amp;#039;]  = nil&lt;br /&gt;
      settings[&amp;#039;acked&amp;#039;]    = false&lt;br /&gt;
      info &amp;#039;Deployed state cleared.&amp;#039;&lt;br /&gt;
    when /^debug$/i&lt;br /&gt;
      settings[&amp;#039;debug&amp;#039;] = !settings[&amp;#039;debug&amp;#039;]&lt;br /&gt;
      if settings[&amp;#039;debug&amp;#039;]&lt;br /&gt;
        caution &amp;#039;Debug mode ON - every upstream line will be echoed in raw form. Toggle off with ;allmine debug.&amp;#039;&lt;br /&gt;
      else&lt;br /&gt;
        info &amp;#039;Debug mode off.&amp;#039;&lt;br /&gt;
      end&lt;br /&gt;
    when /^pause$/i&lt;br /&gt;
      settings[&amp;#039;paused&amp;#039;] = true&lt;br /&gt;
      caution &amp;#039;Movement block PAUSED. Watchdog alerts remain active.&amp;#039;&lt;br /&gt;
    when /^resume$/i&lt;br /&gt;
      settings[&amp;#039;paused&amp;#039;] = false&lt;br /&gt;
      info &amp;#039;Movement block resumed.&amp;#039;&lt;br /&gt;
    when /^verb\s+add\s+(\w+)$/i&lt;br /&gt;
      settings[&amp;#039;extra_verbs&amp;#039;] ||= []&lt;br /&gt;
      v = $1.downcase&lt;br /&gt;
      if settings[&amp;#039;extra_verbs&amp;#039;].include?(v) || MOVE_VERBS.include?(v)&lt;br /&gt;
        info &amp;quot;The verb &amp;#039;#{v}&amp;#039; is already blocked.&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        settings[&amp;#039;extra_verbs&amp;#039;].push(v)&lt;br /&gt;
        info &amp;quot;Added movement verb &amp;#039;#{v}&amp;#039;.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    when /^verb\s+remove\s+(\w+)$/i&lt;br /&gt;
      settings[&amp;#039;extra_verbs&amp;#039;] ||= []&lt;br /&gt;
      v = $1.downcase&lt;br /&gt;
      if settings[&amp;#039;extra_verbs&amp;#039;].delete(v)&lt;br /&gt;
        info &amp;quot;Removed movement verb &amp;#039;#{v}&amp;#039;.&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        caution &amp;quot;The verb &amp;#039;#{v}&amp;#039; is not in the custom verb list.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      info &amp;#039;Usage: set &amp;lt;noun&amp;gt; | arm | status | ack | clear | pause | resume | debug | verb add &amp;lt;verb&amp;gt; | verb remove &amp;lt;verb&amp;gt;&amp;#039;&lt;br /&gt;
      info &amp;quot;Blocked by default: #{DIRS.join(&amp;#039; &amp;#039;)} | #{MOVE_VERBS.join(&amp;#039; &amp;#039;)} | #{QUIT_CMDS.join(&amp;#039; &amp;#039;)}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # ---------------------------------------------------------------- main&lt;br /&gt;
&lt;br /&gt;
  def self.run&lt;br /&gt;
    unless settings[&amp;#039;noun&amp;#039;]&lt;br /&gt;
      caution &amp;quot;No item noun configured. Use ;#{Script.current.name} set &amp;lt;noun&amp;gt; (for example, ;#{Script.current.name} set bowl).&amp;quot;&lt;br /&gt;
      exit&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if Script.list.count { |s| s.name == Script.current.name } &amp;gt; 1 &amp;amp;&amp;amp; Script.current.vars[0].to_s.strip.empty?&lt;br /&gt;
      caution &amp;#039;The monitor is already running.&amp;#039;&lt;br /&gt;
      exit&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Crash/disconnect recovery: stale deployed flag from a prior session.&lt;br /&gt;
    if deployed?&lt;br /&gt;
      where  = settings[&amp;#039;room_id&amp;#039;] ? &amp;quot;room #{settings[&amp;#039;room_id&amp;#039;]} (;go2 #{settings[&amp;#039;room_id&amp;#039;]})&amp;quot; : &amp;#039;an unknown room&amp;#039;&lt;br /&gt;
      placed = settings[&amp;#039;placed_at&amp;#039;] ? Time.at(settings[&amp;#039;placed_at&amp;#039;]).strftime(&amp;#039;%Y-%m-%d %H:%M&amp;#039;) : &amp;#039;an unknown time&amp;#039;&lt;br /&gt;
      bold &amp;quot;*** ALL MINE: A prior session shows your #{settings[&amp;#039;noun&amp;#039;]} may still be on the ground in #{where}, placed at #{placed}. Use ;allmine clear if it has been recovered. ***&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    before_dying {&lt;br /&gt;
      AllMine.remove_hooks&lt;br /&gt;
      if AllMine.deployed?&lt;br /&gt;
        AllMine.bold &amp;quot;*** AllMine is exiting while your #{AllMine.settings[&amp;#039;noun&amp;#039;]} is still on the ground! ***&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    sync_hook_state&lt;br /&gt;
    install_hooks&lt;br /&gt;
    info &amp;quot;Monitoring your #{settings[&amp;#039;noun&amp;#039;]}. The movement block is active with a #{BYPASS_WINDOW}-second re-send bypass, and the watchdog will alert (but never auto-return) if the item is left behind.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Start-time arm: item matching the noun is already on the ground in&lt;br /&gt;
    # this room (placed before the monitor started).&lt;br /&gt;
    if !deployed? &amp;amp;&amp;amp; (match = GameObj.loot.to_a.find { |o| o.noun == settings[&amp;#039;noun&amp;#039;] })&lt;br /&gt;
      set_deployed(match.id)&lt;br /&gt;
      caution &amp;quot;Note: armed from a #{settings[&amp;#039;noun&amp;#039;]} already on the ground here. If it is not yours, use ;#{Script.current.name} clear.&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    loop {&lt;br /&gt;
      watchdog_tick&lt;br /&gt;
      sleep POLL_INTERVAL&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if (args = Script.current.vars[0].to_s.strip) &amp;amp;&amp;amp; !args.empty?&lt;br /&gt;
  AllMine.command(args)&lt;br /&gt;
else&lt;br /&gt;
  AllMine.run&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>TRIEX</name></author>
	</entry>
</feed>