<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MudletPackage>
<MudletPackage version="1.0">
    <TriggerPackage>
        <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
            <name>Mudlet Mapper</name>
            <script></script>
            <triggerType>0</triggerType>
            <conditonLineDelta>0</conditonLineDelta>
            <mStayOpen>0</mStayOpen>
            <mCommand></mCommand>
            <packageName></packageName>
            <mFgColor>#ff0000</mFgColor>
            <mBgColor>#ffff00</mBgColor>
            <mSoundFile></mSoundFile>
            <colorTriggerFgColor>#000000</colorTriggerFgColor>
            <colorTriggerBgColor>#000000</colorTriggerBgColor>
            <regexCodeList/>
            <regexCodePropertyList/>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Have to swim</name>
                <script>mmp.swim()</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>There's water ahead of you. You'll have to swim in that direction to make it through.</string>
                    <string>There's water ahead of you. You'll have to swim in that direction to make it </string>
                    <string>There's water ahead of you. You'll have to SWIM </string>
                    <string>You'll have to swim to make it through the water in that direction.</string>
                    <string>The water is too deep for you to walk that way, you must swim.</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>3</integer>
                    <integer>3</integer>
                    <integer>2</integer>
                    <integer>3</integer>
                    <integer>3</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Rubble at the exit</name>
                <script>mmp.customwalkdelay(2)</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>You begin to slowly clamber over the rubble that blocks your way.</string>
                    <string>You begin to slowly clamber over a pile of rubble that blocks your way.</string>
                    <string>You start plodding carefully across the constructed trenches.</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>3</integer>
                    <integer>3</integer>
                    <integer>3</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Too quick</name>
                <script>if mmp.autowalking then
  mmp.deleteLineP()
end</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>99</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>Now now, don't be so hasty!</string>
                    <string>You can not move that fast!</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>3</integer>
                    <integer>3</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Hobbling</name>
                <script>mmp.customwalkdelay(2)</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>You slowly hobble</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>2</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Frozen</name>
                <script>mmp.customwalkdelay(2)</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>You begin moving your frozen body slowly</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>2</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>People here</name>
                <script>mmp.pdb_lastupdate = {}</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>1</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>You see the following people here:</string>
                    <string>1</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>3</integer>
                    <integer>5</integer>
                </regexCodePropertyList>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="yes" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Person</name>
                    <script>for i = 1, #matches, 2 do
  mmp.pdb[matches[i]] = mmp.currentroomname
  mmp.pdb_lastupdate[matches[i]] = true
  raiseEvent(&quot;mmapper updated pdb&quot;)
end</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#aaff00</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>([A-Z][a-z]+)</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Retardation/aeon walk delay</name>
                <script>mmp.customwalkdelay(2)</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>You move sluggishly into action.</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>3</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Scent (Achaea+Imperian)</name>
                <script>mmp.roomEcho(matches[2]) </script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>^You detect traces of scent from (.+)\.$</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>1</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Alertness (Achaea+Imperian)</name>
                <script>mmp.alertness = mmp.alertness or {}
local alertness = mmp.alertness
 
local roomexists, getRoomName, anytolong, matches, deleteLine = mmp.roomexists, getRoomName, mmp.anytolong, matches, deleteLine
 
if mmp.debug then
 mmp.alertnessTime = mmp.alertnessTime or createStopWatch()
 startStopWatch(mmp.alertnessTime)
end
 
if matches[4] ~= &quot;location&quot; then
  local longexitname = matches[4]
  alertness[longexitname] = alertness[longexitname] or {}
  alertness[longexitname][#alertness[longexitname]+1] = matches[2]
  deleteLine()
elseif matches[4] == &quot;location&quot; then
  local currentroomname = mmp.cleanroomname(mmp.currentroomname)
  if matches[3] == currentroomname then
    alertness.here = alertness.here or {}
    alertness.here[#alertness.here+1] = matches[2]
    deleteLine()
  end
end


if not mmp.firstAlert then
	mmp.firstAlert = true
	mmp.pdb_lastupdate = {}
end
 
mmp.pdb[matches[2]] = matches[3]
mmp.pdb_lastupdate[matches[2]] = true
 
enableTrigger&quot;Mudlet Mapper prompt trigger&quot;
 
if mmp.debug then mmp.echo(&quot;alertness trigger for &quot;..matches[2]..&quot; took &quot;..stopStopWatch(mmp.alertnessTime)..&quot;s.&quot;) end</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>^Your enhanced senses inform you that (\w+) has entered (.+?)(?:, to the| at your) (\w+)\.$</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>1</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="no" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Mudlet Mapper prompt trigger</name>
                <script>-- to be enabled by functions that need it and disabled after it's done. Sort of like a cheap prompttrigger from Svo.
mmp.firstAlert = false
-- handle alertness
if mmp.alertness and next(mmp.alertness) then

  local dirs = {}
  for direction, _ in pairs(mmp.alertness) do dirs[#dirs+1] = direction end
  local people = select(2, next(mmp.alertness)) or {}

  moveCursor(0, getLineNumber())

  if ndb then
    local getcolor = ndb.getcolor
    for i = 1, #people do
      people[i] = getcolor(people[i])..people[i]
    end
  end

  cinsertText(&quot;&lt;red&gt;[&lt;cyan&gt;&quot; .. table.concat(dirs, ', ') .. &quot; &lt;red&gt;-&quot;..(#dirs &gt; 1 and (&quot;\n  &quot;) or '')..&quot; &lt;white&gt;&quot; .. ((svo and svo.concatand) and svo.concatand(people) or table.concat(people, ', ')) .. &quot;&lt;cyan&gt; (&quot;..#people..&quot;)&lt;red&gt;]\n&quot;)

  moveCursorEnd()

  mmp.alertness = nil

  raiseEvent(&quot;mmapper updated pdb&quot;)
end

-- reset names we last seen, so scripts can be efficient
-- not finished yet
--if next(mmp.pdb_lastupdate) then
--  mmp.pdb_lastupdate = {}
--end

disableTrigger&quot;Mudlet Mapper prompt trigger&quot;</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>return isPrompt()</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>4</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Wormhole</name>
                <script>mmp.customwalkdelay(4)</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>You hurl yourself forwards through the air, and sure enough a swirling vortex of colours springs into existence to swallow you.</string>
                    <string>You reach out with the vibrating stick to probe for a wormhole, and as it connects with one, you are sucked through.</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>3</integer>
                    <integer>3</integer>
                </regexCodePropertyList>
            </Trigger>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>No wormhole</name>
                <script>if mmp.speedWalkDir and mmp.speedWalkDir[speedWalkCounter] and mmp.speedWalkDir[speedWalkCounter]==&quot;worm warp&quot; then
  mmp.echo(&quot;Missing wormhole detected, locking wormhole and trying new path...&quot;)

  lockSpecialExit(mmp.currentroom, mmp.speedWalkPath[speedWalkCounter], &quot;worm warp&quot;, true)

  local destination = mmp.speedWalkPath[#mmp.speedWalkPath]

  mmp.stop()

  mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way

  if not mmp.getPath(mmp.currentroom, destination) then
    mmp.echo(string.format(&quot;Don't know how to get to %d (%s) anymore :( Move into a room we know of to continue&quot;, destination, getRoomName(destination)))
  else
    mmp.gotoRoom(destination)
  end
end</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>There is no wormhole here.</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>3</integer>
                </regexCodePropertyList>
            </Trigger>
            <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Achaea</name>
                <script></script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList/>
                <regexCodePropertyList/>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Login</name>
                    <script>raiseEvent(&quot;mmp logged in&quot;, &quot;Achaea&quot;)
mmp.game = &quot;achaea&quot;
mmp.echo(&quot;We're connected to Achaea.&quot;)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Password correct. Welcome to Achaea.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>0</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Local area farsee</name>
                    <script>mmp.locateAndEchoSide(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You see that </string>
                        <string>^You see that (\w+) is at (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Entering wilderness</name>
                    <script>mmp.customwalkdelay(6)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>99</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You begin to look for that place to enter the wilderness. It's around here somewhere!</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Icon enter/leave</name>
                    <script>mmp.customwalkdelay(10)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>1</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You reach out and touch a powerful Icon. For a moment, nothing happens, but soon you feel a humming deep inside you.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Underworld root</name>
                    <script>mmp.customwalkdelay(2)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>As you touch a huge grey root, you feel dark energies coursing up your hand and throughout your body.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Mindsense</name>
                    <script>mmp.locateAndEchoSide(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You seek out the mind of</string>
                        <string>^You seek out the mind of (\w+) and an image of (.+) appears in your mind\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Destroyed room</name>
                    <script>mmp.customwalkdelay(3)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Your movement is slowed as you move through the decimated remains.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Underworld entry</name>
                    <script>mmp.customwalkdelay(3)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>A huge grey root numbs your fingertips as you reach out to touch it.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Angel sense</name>
                    <script>local t = mmp.getnums(multimatches[2][2], true)
if not t then return end
if #t == 1 then
	cecho(&quot; &lt;orange_red&gt;(&quot;..mmp.cleanAreaName(mmp.areatabler[getRoomArea(t[1])])..&quot;)&quot;)
else
	cecho(&quot; &lt;orange_red&gt;Maybe (&quot;..mmp.cleanAreaName(mmp.areatabler[getRoomArea(t[1])])..&quot;)&quot;)
end
echo &quot; &quot;; mmp.echonums(multimatches[2][2])

mmp.temp_room = multimatches[2][2]</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>100</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Your guardian angel senses </string>
                        <string>^Your guardian angel senses .+? at (.+?),</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Each person</name>
                        <script>mmp.pdb[matches[2]] = mmp.temp_room
mmp.pdb_lastupdate[matches[2]] = true</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string> is with (\w+)\.$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop</name>
                        <script>setTriggerStayOpen(&quot;Angel sense&quot;, 0)
mmp.temp_room = nil
raiseEvent(&quot;mmapper updated pdb&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>99</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Dragonsense</name>
                    <script>mmp.locateAndEchoSide(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>1</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Tapping into the unfathomable depths of your power, you sense that</string>
                        <string>Tapping into the unfathomable depths of your power, you sense that (\w+) is at (.+?), in (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Defilement</name>
                    <script>mmp.locateAndEchoSide(multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>(Order): </string>
                        <string>^\(Order\): \w+'s Herald says, &quot;A shrine is being defiled at (.+)!&quot;$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Defiled</name>
                    <script>mmp.locateAndEcho(multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>(Order):</string>
                        <string>^\(Order\): \w+'s Herald says, &quot;A shrine has been destroyed at (.+)!&quot;$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>View </name>
                    <script>mmp.locateAndEcho(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You see</string>
                        <string>^You see (\w+) at (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Elementalism scry</name>
                    <script>mmp.locateAndEcho(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You create a pool of water in the air in front of you and look through it, sensing</string>
                        <string>You create a pool of water in the air in front of you and look through it, sensing (\w+) at (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="no" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Parse wholist</name>
                    <script>-- this trigger should be off by default. It's inefficient and gets auto-enabled
-- when you check 'who'
mmp.locateAndEcho(matches[3], matches[2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>99</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^(\w+) +\((.+)\)$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Piety on astralform</name>
                    <script>mmp.customwalkdelay(3)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>A rite of piety slows your movement as it pulls at your ephemeral body.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Angel/Demon presences</name>
                    <script>disableTrigger(&quot;Angel sense&quot;)

mmp.pdb_lastupdate = {}</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>100</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You bid your guardian angel to seek out life presences nearby.</string>
                        <string>You bid your Baalzadeen to seek out life presences nearby.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                        <integer>3</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Each person</name>
                        <script>mmp.locateAndEchoSide(matches[3], matches[2])</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^Your guardian angel senses (\w+) at (.+?),</string>
                            <string>^Your Baalzadeen senses (\w+) at (.+?),</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop (angel presences)</name>
                        <script>setTriggerStayOpen(&quot;Angel/Demon presences&quot;, 0)
enableTrigger(&quot;Angel sense&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Demon sense</name>
                    <script>mmp.locateAndEchoSide(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Your Baalzadeen senses </string>
                        <string>^Your Baalzadeen senses (\w+) at (.+), on a health of</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Annwyn circle</name>
                    <script>mmp.customwalkdelay(12)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>The melody of a strange song rises unbidden to your lips as you skip around the circle of mushrooms.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Scrying bowl</name>
                    <script>mmp.locateAndEcho(multimatches[3][2], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>1</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You dip your fingers into the cool water of the bowl, willing it to reveal the location of</string>
                        <string>^You dip your fingers into the cool water of the bowl, willing it to reveal the location of (\w+)\.$</string>
                        <string>^An image of .+? appears reflected within the bowl, shifting with the rippling water to display (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Occultist entities</name>
                    <script></script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>1000</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>The following entities reside on the Prime Material plane:</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Each doppleganger</name>
                        <script>mmp.locateAndEcho(matches[3], matches[2])</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^(\w+) is at (.+)\.$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop</name>
                        <script>setTriggerStayOpen(&quot;Occultist entities&quot;, 0)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Party traces/locaters</name>
                    <script></script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>(Party):</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>regex (party locate)</name>
                        <script>mmp.locateAndEcho(matches[3], matches[2])</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^\(Party\): \w+ says, &quot;(\w+) moved to (.+)\.&quot;$</string>
                            <string>^\(Party\): \w+ says, &quot;(\w+) is at (.+), in .+\.&quot;</string>
                            <string>^\(Party\): \w+ says, &quot;Trace: (\w+) moved to (.+)\.&quot;</string>
                            <string>^\(Party\): \w+ says, &quot;(\w+) - (.+), in .+\.&quot;$</string>
                            <string>^\(Party\): \w+ says, &quot;(\w+) is at (.+) \(.+\)\.&quot;</string>
                            <string>^\(Party\): \w+ says, &quot;Trace: (\w+) entered (.+) in .+\.&quot;</string>
                            <string>^\(Party\): \w+ says, &quot;Trace: (\w+) entered (.+)\.&quot;</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                            <integer>1</integer>
                            <integer>1</integer>
                            <integer>1</integer>
                            <integer>1</integer>
                            <integer>1</integer>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Arena event (Achaea)</name>
                    <script>mmp.pdb_lastupdate = {}</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>3</conditonLineDelta>
                    <mStayOpen>1000</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Current event</string>
                        <string>Player               Location</string>
                        <string>----------------------------------------------------------------------</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>3</integer>
                        <integer>3</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Each person</name>
                        <script>echo((&quot; &quot;):rep(60-#line))
echo&quot;(&quot; mmp.echonums(matches[3]) echo&quot;)&quot;

mmp.pdb[matches[2]] = matches[3]
mmp.pdb_lastupdate[matches[2]] = true</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^(\w+) +(.+)$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop (arena event)</name>
                        <script>setTriggerStayOpen(&quot;Arena event (Achaea)&quot;, 0)

raiseEvent(&quot;mmapper updated pdb&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Angel trace</name>
                    <script>selectCurrentLine() replace(&quot;&quot;)
cecho(&quot;&lt;grey&gt;Angel trace: &lt;a_darkcyan&gt;&quot;..multimatches[2][2]..&quot;&lt;grey&gt; moved to &lt;a_darkcyan&gt;&quot; .. multimatches[2][3])
mmp.locateAndEchoInternal(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Your guardian angel reports that</string>
                        <string>^Your guardian angel reports that (\w+) has moved to (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="no" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>KoTH (mudlet mapper)</name>
                    <script>mmp.pdb_lastupdate = {}</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>5</conditonLineDelta>
                    <mStayOpen>1000</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Current event: King of the Hill</string>
                        <string>5</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                        <integer>5</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Each person</name>
                        <script>echo((&quot; &quot;):rep(60-#line))
echo&quot;(&quot; mmp.echonums(matches[3]) echo&quot;)&quot;

mmp.pdb[matches[2]] = matches[3]
mmp.pdb_lastupdate[matches[2]] = true</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^(\w+) .+? ([A-Z][a-z ]+?)$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop (koth)</name>
                        <script>setTriggerStayOpen(&quot;KoTH (mudlet mapper)&quot;, 0)

raiseEvent(&quot;mmapper updated pdb&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Fullsense (mudlet mapper)</name>
                    <script>mmp.pdb_lastupdate = {}</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>100</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You seek out all mental presences within your reach:</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Each person</name>
                        <script>echo((&quot; &quot;):rep(60-#line))
echo&quot;(&quot; mmp.echonums(matches[3]) echo&quot;)&quot;

mmp.pdb[matches[2]] = matches[3]
mmp.pdb_lastupdate[matches[2]] = true</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^You sense (\w+) at (.+)\.$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop</name>
                        <script>setTriggerStayOpen(&quot;Fullsense (mudlet mapper)&quot;, 0)

raiseEvent(&quot;mmapper updated pdb&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Alchemist ether seek</name>
                    <script>mmp.locateAndEcho(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You reach out into the ether, folding it aside to reveal</string>
                        <string>^You reach out into the ether, folding it aside to reveal (\w+)\. As you peer into the opening, the image of (.+) swims into view, then fades away as the ether seeps back into place\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Allsight</name>
                    <script>mmp.locateAndEcho(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Allsight:</string>
                        <string>^Allsight: (\w+) enters (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Polished skull locater</name>
                    <script>mmp.locateAndEcho(matches[2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^An image of (.*) appears in your mind\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Downed shrine in Order logs</name>
                    <script>local room = multimatches[2][2]

mmp.locateAndEcho(room)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>- A shrine at</string>
                        <string>- A shrine at '(.+)' was destroyed\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>0</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>chrono divine</name>
                    <script>mmp.locateAndEcho(multimatches[3][2], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>1</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Tapping into the timelines, you trace them to locate</string>
                        <string>^Tapping into the timelines, you trace them to locate (\w+)\.$</string>
                        <string>^You determine that s?he is at (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Shadow preeminence</name>
                    <script>mmp.pdb_lastupdate = {}</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>100</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You cast your will out across the land, surveying all that stand within shadow's embrace.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Each person</name>
                        <script>mmp.locateAndEchoSide(matches[3], matches[2])</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^You sense (\w+) at (.+?)\.$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>prompt</name>
                        <script>setTriggerStayOpen(&quot;Shadow preeminence&quot;, 0)
enableTrigger(&quot;Shadow preeminence&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
            </TriggerGroup>
            <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Aetolia</name>
                <script></script>
                <triggerType>0</triggerType>
                <conditonLineDelta>1</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList/>
                <regexCodePropertyList/>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Login</name>
                    <script>raiseEvent(&quot;mmp logged in&quot;, &quot;Aetolia&quot;)
mmp.game = &quot;aetolia&quot;</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>99</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Password correct. Welcome to Aetolia.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
            </TriggerGroup>
            <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Lusternia</name>
                <script></script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList/>
                <regexCodePropertyList/>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Login</name>
                    <script>raiseEvent(&quot;mmp logged in&quot;, &quot;Lusternia&quot;)
mmp.game = &quot;lusternia&quot;</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>5</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>                        A G E  O F  A S C E N S I O N</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>mmp Lusternia Scent</name>
                    <script>mmp.tempscent = {}
mmp.pdb_lastupdate = {}
</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>99</conditonLineDelta>
                    <mStayOpen>100</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You scent at the air, your skilled nose picking up the faint traces of others in the surrounding area.</string>
                        <string>You snort and snuffle at the air, sensing through a ridiculous pig nose upon your face the faint traces of others in the surrounding area.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                        <integer>3</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Got line</name>
                        <script>--deleteLine()

selectString(line, 1) replace&quot;&quot;

-- get the name
cecho(&quot;&lt;green&gt;&quot;..matches[2]..&quot;&lt;reset&gt;: &quot;)

-- ids
mmp.echonums(matches[3])

-- pad spaces so we have aligned roomname
echo(string.rep(&quot; &quot;, 25 - #getCurrentLine()))

-- and finally, the roomname
echo(matches[3])


if mmp.tempscent[matches[3]] then
	mmp.tempscent[matches[3]][#mmp.tempscent[matches[3]]+1] = matches[2]
else
	mmp.tempscent[matches[3]] = {matches[2]}
end

-- save in our person tracking db
mmp.pdb[matches[2]] = matches[3]
mmp.pdb_lastupdate[matches[2]] = true</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^You make out the scent of (\w+) coming from (.+)\.$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop capturing</name>
                        <script>setTriggerStayOpen(&quot;mmp Lusternia Scent&quot;, 0)

--[[for area, names in pairs(mmp.tempscent) do
	for _, name in ipairs(names) do

-- get the name
cecho(&quot;\n&lt;green&gt;&quot;..name..&quot;&lt;reset&gt;: &quot;)

-- ids
mmp.echonums(area)

-- pad spaces so we have aligned roomname
echo(string.rep(&quot; &quot;, 25))

-- and finally, the roomname
echo(area)
end
end]]


raiseEvent(&quot;mmapper updated pdb&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>mmp Lusternia kaleidoscope</name>
                    <script>mmp.tempscent = {}
mmp.pdb_lastupdate = {}

</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>1</conditonLineDelta>
                    <mStayOpen>100</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You hold a kaleidoscopic telescope to your eye, you twist the end and stare intently through its twinkling surfaces.</string>
                        <string>Through the glittering faceted planes, you see:</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                        <integer>3</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Got line</name>
                        <script>local person, room = matches[2], matches[3]:trim()


selectString(line, 1) replace&quot;&quot;

-- get the name
cecho(&quot;&lt;green&gt;&quot;..person..&quot;&lt;reset&gt;: &quot;)

-- ids
--mmp.echonums()

-- pad spaces so we have aligned roomname
echo(string.rep(&quot; &quot;, 13 - #getCurrentLine()))

-- and finally, the roomname
echo(room)

mmp.locateAndEchoSide(room, person)


if mmp.tempscent[room] then
	mmp.tempscent[room][#mmp.tempscent[room]+1] = person
else
	mmp.tempscent[room] = {person}
end

-- save in our person tracking db
mmp.pdb[person] = room
mmp.pdb_lastupdate[person] = true</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^(\w+) - ([^\(]+)</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop capturing</name>
                        <script>setTriggerStayOpen(&quot;mmp Lusternia kaleidoscope&quot;, 0)

--[[for area, names in pairs(mmp.tempscent) do
	for _, name in ipairs(names) do

-- get the name
cecho(&quot;\n&lt;green&gt;&quot;..name..&quot;&lt;reset&gt;: &quot;)

-- ids
mmp.echonums(area)

-- pad spaces so we have aligned roomname
echo(string.rep(&quot; &quot;, 25))

-- and finally, the roomname
echo(area)
end
end]]


raiseEvent(&quot;mmapper updated pdb&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Deathsight</name>
                    <script>mmp.locateAndEcho(multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You see the death occur at</string>
                        <string>^You see the death occur at (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Wildnodes nodes</name>
                    <script>mmp.locateAndEcho(matches[2]:sub(1,1):lower()..string.sub(matches[2], 2))</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>99</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^\(Planted\) Node \d+ - (.*)\.$</string>
                        <string>^ +Node \d+ - (.*)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Window search</name>
                    <script>mmp.locateAndEcho(matches[4], matches[2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>39</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^You open up a window in the cosmic fabric and search out (\w+). Through the cosmic window, you see (\w+) at (.+?)(?: \(.*\))?\.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Scry search</name>
                    <script>mmp.locateAndEcho(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>1</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^You rub .* and it begins to glow with a pulsating light\.$</string>
                        <string>Within the enchanted item, an image forms of (\w+) at (.+?)(?: \(.*\))?\.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Map artefact</name>
                    <script>mmp.gotoRoom(multimatches[4][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>3</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>As you inscribe the name of </string>
                        <string>^As you inscribe the name of \w+ with a flourish, lines crawl across the surface of the map, centered upon (.*)\.$</string>
                        <string>You see the following in detail:</string>
                        <string>v(\d+)</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                        <integer>3</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Masquerade ball snowglobe</name>
                    <script>mmp.gotoRoom(multimatches[3][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>2</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^You trace the name of \w+ on the surface of a splendid masquerade ball snowglobe, and then shake the globe vigorously\. As the swirling particles within clear, you see the vague outline of .+?\.$</string>
                        <string>You see the following in detail:</string>
                        <string>v(\d+)</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                        <integer>3</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>map scry</name>
                    <script>mmp.locateAndEcho(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>As you inscribe the name of</string>
                        <string>^As you inscribe the name of (\w+) with a flourish, lines crawl across the surface of the map, centered upon (.*)\.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>World events</name>
                    <script>mmp.locateAndEcho(matches[1])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^The Staff of Ascension is at (.*)\.$</string>
                        <string>^The Purple Hamster of Chaos is at (.*)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Seeing stone</name>
                    <script>mmp.locateAndEcho(multimatches[3][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>3</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You gaze into a seeing stone.</string>
                        <string>1</string>
                        <string>^(.*)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                        <integer>5</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Birdseye</name>
                    <script>mmp.locateAndEcho(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>From your vantage point in the sky, your crow senses perceive that</string>
                        <string>^From your vantage point in the sky, your crow senses perceive that (\w+) is (.*) within the vicinity of (.*)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Bond look</name>
                    <script>mmp.locateAndEcho(multimatches[3][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>3</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^You look through the mind of (.*)\:$</string>
                        <string>1</string>
                        <string>^(.*)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                        <integer>5</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Pyramid probe #</name>
                    <script>local t = mmp.getnums(multimatches[2][2])
if not t then return end

echo&quot;\n&quot;

if #t == 1 then
	cecho(&quot;&lt;red&gt;From your knowledge, that room is in &lt;orange_red&gt;&quot;..mmp.areatabler[getRoomArea(t[1])]..&quot;&lt;red&gt;.&quot;)
else
	cecho(&quot;&lt;red&gt;From your knowledge, that room might be in &lt;orange_red&gt;&quot;..mmp.areatabler[getRoomArea(t[1])]..&quot;&lt;red&gt;.&quot;)
end</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You lightly caress a button on a paradox puzzle pyramid and suddenly a hazy image of</string>
                        <string>^You lightly caress a button on a paradox puzzle pyramid and suddenly a hazy image of (.*) flashes momentarily in front of you\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Pentagon probe #</name>
                    <script>local t = mmp.getnums(multimatches[2][2])
if not t then return end

echo&quot;\n&quot;

if #t == 1 then
	cecho(&quot;&lt;red&gt;From your knowledge, that room is in &lt;orange_red&gt;&quot;..mmp.areatabler[getRoomArea(t[1])]..&quot;&lt;red&gt;.&quot;)
else
	cecho(&quot;&lt;red&gt;From your knowledge, that room might be in &lt;orange_red&gt;&quot;..mmp.areatabler[getRoomArea(t[1])]..&quot;&lt;red&gt;.&quot;)
end</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You lightly caress a button on a paradox puzzle pentagon and suddenly a hazy image of</string>
                        <string>^You lightly caress a button on a paradox puzzle pentagon and suddenly a hazy image of (.+) \(room \#\d+\) flashes momentarily in front of you\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Pyramid port</name>
                    <script>local t = mmp.getnums(multimatches[2][2])
if not t then return end

echo&quot;\n&quot;

if #t == 1 then
	cecho(&quot;&lt;red&gt;Porting to &lt;orange_red&gt;&quot;..mmp.areatabler[getRoomArea(t[1])]..&quot;&lt;red&gt;.&quot;)
else
	cecho(&quot;&lt;red&gt;Might be porting to &lt;orange_red&gt;&quot;..mmp.areatabler[getRoomArea(t[1])]..&quot;&lt;red&gt;.&quot;)
end	</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Your hands become a blur as you twist and turn a paradox puzzle pyramid until each side is made up of the same colour, solving the puzzle in mere moments. Suddenly the image of</string>
                        <string>^Your hands become a blur as you twist and turn a paradox puzzle pyramid until each side is made up of the same colour, solving the puzzle in mere moments. Suddenly the image of (.*) appears in the back of your mind and you feel drawn towards it\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Pyramid probe</name>
                    <script></script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>99</conditonLineDelta>
                    <mStayOpen>4</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You lightly caress a few buttons on a paradox puzzle pyramid and suddenly a series of hazy images flashes momentarily in front of you.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Each location</name>
                        <script>local t = mmp.getnums(matches[2])
if not t then return end

if #t == 1 then
	cecho(&quot;&lt;red&gt; (in &lt;orange_red&gt;&quot;..mmp.areatabler[getRoomArea(t[1])]..&quot;&lt;red&gt;)&quot;)
else
	cecho(&quot;&lt;red&gt; (might be in &lt;orange_red&gt;&quot;..mmp.areatabler[getRoomArea(t[1])]..&quot;&lt;red&gt;)&quot;)
end</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^Puzzle point \d+ is set to (.+) \(</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Astrology scry</name>
                    <script>mmp.locateAndEcho(multimatches[2][3], multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Gazing up at the sky, you bring the image of</string>
                        <string>^Gazing up at the sky, you bring the image of (\w+) into your mind's eye and overlay it on the constellations\. The power of the stars manifests as an image of (.+?) forms before your eyes\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Tierstone</name>
                    <script>mmp.locateAndEcho(multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>1</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You gaze into a glittering tierstone.</string>
                        <string>^\w+ is at (.+?) in (.*)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Quicksand</name>
                    <script>mmp.customwalkdelay(4)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You struggle slowly through the quicksand as you move</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Gravity</name>
                    <script>mmp.customwalkdelay(4)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>The dragging force of a war shrine of</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Crow spy</name>
                    <script>mmp.locateAndEcho(multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>An image of</string>
                        <string>^An image of \w+ (?:entering|leaving) (.+?) appears in the centre of the nest\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Crow spy remote</name>
                    <script>mmp.locateAndEcho(multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Your nest projects into your head an image</string>
                        <string>^Your nest projects into your head an image of \w+ (?:entering|exiting) (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>City/commune shops menu</name>
                    <script></script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>3</conditonLineDelta>
                    <mStayOpen>500</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>[ Local shops selling</string>
                        <string>3</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>0</integer>
                        <integer>5</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Shop</name>
                        <script>local shop = line:sub(1, 25):trim()
if shop:sub(1,1) == '*' then return end

cecho(&quot;  &lt;orange_red&gt;(&quot;)
mmp.echonums(shop)
cecho(&quot;&lt;orange_red&gt;)&quot;)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Stop (city/commune shops menu)</name>
                        <script>setTriggerStayOpen(&quot;City/commune shops menu&quot;, 0)</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>return isPrompt()</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>4</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
            </TriggerGroup>
            <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Imperian</name>
                <script></script>
                <triggerType>0</triggerType>
                <conditonLineDelta>99</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList/>
                <regexCodePropertyList/>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Login</name>
                    <script>raiseEvent(&quot;mmp logged in&quot;, &quot;Imperian&quot;)
mmp.game = &quot;imperian&quot;</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Password correct. Welcome to Imperian.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Wormholes</name>
                    <script>local room1 = mmp.roomEcho(multimatches[2][2])
local room2 = mmp.roomEcho(multimatches[2][3])
selectCurrentLine()
replace(&quot;&quot;)
mmp.echon(&quot;Stable wormhole between &quot; .. room1)
mmp.roomEcho(room1)
echo(&quot; and &quot; .. room2)
mmp.roomEcho(room2)
echo(&quot;.\n&quot;)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You sense a stable wormhole between</string>
                        <string>^You sense a stable wormhole between (.+?) and (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Personal wormholes</name>
                    <script>selectCurrentLine()
replace(&quot;&quot;)
mmp.echon(&quot;Personal wormhole at &quot; .. multimatches[2][2])
mmp.roomEcho(multimatches[2][2])
echo(&quot;. It is attached to &quot; .. multimatches[2][3] .. &quot;.\n&quot;)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You sense a personal wormhole at</string>
                        <string>^You sense a personal wormhole at (.+). It is attached to (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="no" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Parse wholist</name>
                    <script>selectCaptureGroup(2)
replace(&quot;&quot;)
mmp.roomEcho(matches[3])
 </script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>.+( \- [A-Z].+?\s*?) \- (.+)</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Trap went off</name>
                    <script>selectCurrentLine()
replace(&quot;&quot;)
mmp.echon(&quot;Your trap at &quot; .. multimatches[2][2])
mmp.roomEcho(multimatches[2][2])
echo(&quot; was set off by &quot; .. multimatches[2][3] .. &quot;!!!\n&quot;)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Your alarm at</string>
                        <string>^Your alarm at \'(.+)\' has been set off by (\w+)\!$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Trap List</name>
                    <script>-- the first pattern is not blank, there are spaces there

selectCurrentLine()
replace(&quot;&quot;)
echo(&quot;[&quot; .. multimatches[2][2] .. &quot;] (&quot; .. multimatches[2][3] .. &quot;) at &quot; .. multimatches[2][4])
mmp.roomEcho(multimatches[2][4]) </script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>   </string>
                        <string>^   (\w+) \((\w+)\) at (.+)$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="no" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Scout</name>
                    <script>-- bad, overzealous trigger - the pattern needs to be improved
mmp.roomEcho(multimatches[2][2]) </script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>   </string>
                        <string>^   .+ at (.+)$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Hunt</name>
                    <script>selectCurrentLine()
replace(&quot;&quot;)
cecho(&quot;&lt;chocolate&gt;&quot; .. matches[2] .. &quot;&lt;grey&gt; moved to &lt;sienna&gt;&quot; .. matches[3] .. &quot;, &lt;white&gt;&quot; ..matches[4])
mmp.roomEcho(matches[3]) </script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>^You sense that (\w+) has entered (.+)\, (.+)\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Sewer grate</name>
                    <script>mmp.enterGrate()</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>A sewer grate prevents you from moving down into the sewers.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Caravan</name>
                    <script>mmp.customwalkdelay(15)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You begin leading a caravan</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                    </regexCodePropertyList>
                </Trigger>
            </TriggerGroup>
            <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Midkemia Online</name>
                <script></script>
                <triggerType>0</triggerType>
                <conditonLineDelta>99</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList/>
                <regexCodePropertyList/>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Login</name>
                    <script>raiseEvent(&quot;mmp logged in&quot;, &quot;Midkemia Online&quot;)
mmp.game = &quot;mko&quot;</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Password correct. Welcome to Midkemia Online.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Fording</name>
                    <script>mmp.customwalkdelay(3)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You ford the water towards the </string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                    </regexCodePropertyList>
                </Trigger>
            </TriggerGroup>
            <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Lithmeria</name>
                <script></script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList/>
                <regexCodePropertyList/>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Login</name>
                    <script>raiseEvent(&quot;mmp logged in&quot;, &quot;Lithmeria&quot;)
mmp.game = &quot;lithmeria&quot;
mmp.echo(&quot;We're connected to Lithmeria.&quot;)</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>Welcome to your account!</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
            </TriggerGroup>
            <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Wall</name>
                <script>mmp.failpath()</script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList>
                    <string>A wall blocks your way.</string>
                </regexCodeList>
                <regexCodePropertyList>
                    <integer>3</integer>
                </regexCodePropertyList>
            </Trigger>
            <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Doors</name>
                <script></script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList/>
                <regexCodePropertyList/>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Closing doors</name>
                    <script></script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>1</conditonLineDelta>
                    <mStayOpen>1</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You open the door to the</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                    </regexCodePropertyList>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Lack of piety</name>
                        <script>mmp.failpath()</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^You try to open the door to the (\w+) but find it slams closed in your face, symbolic of your lack of piety\.$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Slam Shut</name>
                        <script>mmp.failpath()</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>1</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>The door slams shut!</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>3</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Denied entry</name>
                        <script>mmp.failpath()</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>The door suddenly slams shut, denying you entry.</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>3</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>CIJ</name>
                        <script>mmp.failpath()</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>A section of the door slides aside, and a rubber-gloved fist on a spring pops out and punches you in the nose!</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>3</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Springs back</name>
                        <script>mmp.failpath()</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>The door budges, and then springs immediately back into place.</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>3</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Bolted</name>
                        <script>mmp.failpath()</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>^The door to the (\w+) is closed forcefully fromthe other side and the sound of a bolt being slammed home makes your lack of admittance clear\.$</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>1</integer>
                        </regexCodePropertyList>
                    </Trigger>
                    <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                        <name>Self-closing door</name>
                        <script>mmp.failpath()</script>
                        <triggerType>0</triggerType>
                        <conditonLineDelta>0</conditonLineDelta>
                        <mStayOpen>0</mStayOpen>
                        <mCommand></mCommand>
                        <packageName></packageName>
                        <mFgColor>#ff0000</mFgColor>
                        <mBgColor>#ffff00</mBgColor>
                        <mSoundFile></mSoundFile>
                        <colorTriggerFgColor>#000000</colorTriggerFgColor>
                        <colorTriggerBgColor>#000000</colorTriggerBgColor>
                        <regexCodeList>
                            <string>The door closes swiftly with a loud 'BANG'!</string>
                        </regexCodeList>
                        <regexCodePropertyList>
                            <integer>3</integer>
                        </regexCodePropertyList>
                    </Trigger>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Door closed</name>
                    <script>mmp.failpath()</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>2</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You open the door to the</string>
                        <string>return isPrompt()</string>
                        <string>^The door to the \w+ closes with a click\.$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>4</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Failed to open door</name>
                    <script>mmp.failpath()</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You are not carrying a key for this door.</string>
                        <string>This door has been magically locked shut.</string>
                        <string>Not recognising you as cast or crew, stagehands firmly close the door on you.</string>
                        <string>You push against the door in vain as you try to open it.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                        <integer>3</integer>
                        <integer>3</integer>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Door Locked</name>
                    <script>mmp.unlockDoor()</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>The door is locked.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Door in the way</name>
                    <script>mmp.openDoor()</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>There is a door in the way, to the</string>
                        <string>There is a door in the way.</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>3</integer>
                    </regexCodePropertyList>
                </Trigger>
            </TriggerGroup>
            <TriggerGroup isActive="yes" isFolder="yes" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                <name>Wormholes</name>
                <script></script>
                <triggerType>0</triggerType>
                <conditonLineDelta>0</conditonLineDelta>
                <mStayOpen>0</mStayOpen>
                <mCommand></mCommand>
                <packageName></packageName>
                <mFgColor>#ff0000</mFgColor>
                <mBgColor>#ffff00</mBgColor>
                <mSoundFile></mSoundFile>
                <colorTriggerFgColor>#000000</colorTriggerFgColor>
                <colorTriggerBgColor>#000000</colorTriggerBgColor>
                <regexCodeList/>
                <regexCodePropertyList/>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Worm sources</name>
                    <script>deleteLine()
local from = multimatches[2][2]
local to = multimatches[2][3]

cecho(&quot;\nYou see connections between &quot;..from..&quot; (&quot;)
mmp.echonums(from)
cecho(&quot;) and &quot;..to..&quot; (&quot;)
mmp.echonums(to)
cecho(&quot;)&quot;)
</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You sense a connection between</string>
                        <string>^You sense a connection between (.*) and (.*).$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="yes" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Worm seek</name>
                    <script>mmp.locateAndEcho(multimatches[2][2])</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You sense a wormhole leading to</string>
                        <string>^You sense a wormhole leading to (.*).$</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>1</integer>
                    </regexCodePropertyList>
                </Trigger>
                <Trigger isActive="yes" isFolder="no" isTempTrigger="no" isMultiline="no" isPerlSlashGOption="no" isColorizerTrigger="no" isFilterTrigger="no" isSoundTrigger="no" isColorTrigger="no" isColorTriggerFg="no" isColorTriggerBg="no">
                    <name>Wormhole Vision™</name>
                    <script>--if not getSpecialExitsSwap or mmp.settings.lockwormholes then return end
if not getSpecialExitsSwap then return end

local exits = getSpecialExitsSwap(mmp.currentroom)
if exits and exits[&quot;worm warp&quot;] then
  cecho(string.format(&quot;\n&lt;DarkSlateGrey&gt;A wormhole is here, leading to: &lt;orange_red&gt;%s (#%d)&lt;DarkSlateGrey&gt; in %s.\n&quot;, getRoomName(exits[&quot;worm warp&quot;]), exits[&quot;worm warp&quot;], mmp.cleanAreaName(mmp.getAreaName(exits[&quot;worm warp&quot;]))))
end</script>
                    <triggerType>0</triggerType>
                    <conditonLineDelta>0</conditonLineDelta>
                    <mStayOpen>0</mStayOpen>
                    <mCommand></mCommand>
                    <packageName></packageName>
                    <mFgColor>#ff0000</mFgColor>
                    <mBgColor>#ffff00</mBgColor>
                    <mSoundFile></mSoundFile>
                    <colorTriggerFgColor>#000000</colorTriggerFgColor>
                    <colorTriggerBgColor>#000000</colorTriggerBgColor>
                    <regexCodeList>
                        <string>You see exits</string>
                        <string>You see a single exit</string>
                    </regexCodeList>
                    <regexCodePropertyList>
                        <integer>2</integer>
                        <integer>2</integer>
                    </regexCodePropertyList>
                </Trigger>
            </TriggerGroup>
        </TriggerGroup>
    </TriggerPackage>
    <TimerPackage>
        <TimerGroup isActive="yes" isFolder="yes" isTempTimer="no" isOffsetTimer="no">
            <name>Mudlet Mapper</name>
            <script></script>
            <command></command>
            <packageName></packageName>
            <time>00:00:00.000</time>
            <Timer isActive="yes" isFolder="no" isTempTimer="no" isOffsetTimer="no">
                <name>Check for updates periodically</name>
                <script>mmp.checkforupdate()</script>
                <command></command>
                <packageName></packageName>
                <time>01:00:00.000</time>
            </Timer>
        </TimerGroup>
    </TimerPackage>
    <AliasPackage>
        <AliasGroup isActive="yes" isFolder="yes">
            <name>Mudlet Mapper</name>
            <script>mudlet = mudlet or {}; mudlet.mapper_script = true</script>
            <command></command>
            <packageName></packageName>
            <regex></regex>
            <Alias isActive="yes" isFolder="no">
                <name>Go to ID or area</name>
                <script>local where = matches[2]:lower()
local gallop
if command:ends(&quot;gallop&quot;) then
  gallop = &quot;gallop&quot;
  where = where:sub(1, -8)
elseif command:ends(&quot;sprint&quot;) then
  gallop = &quot;sprint&quot;
  where = where:sub(1, -8)
elseif command:ends(&quot;dash&quot;) then
  gallop = &quot;dash&quot;
  where = where:sub(1, -6)
elseif command:ends(&quot;runaway&quot;) then
  gallop = &quot;runaway&quot;
  where = where:sub(1, -9)
elseif command:ends(&quot;glide&quot;) then
  gallop = &quot;glide&quot;
  where = where:sub(1, -7)
end

if mmp.debug then
  mmp.gotoPerf = mmp.gotoPerf or createStopWatch()
  startStopWatch(mmp.gotoPerf)
end

-- goto room ID
if tonumber(where) then
	mmp.gotoRoom(where, gallop)
else
	-- goto area
    local split = where:split(&quot; &quot;)
    if tonumber(split[#split]) then
        mmp.gotoArea(where:sub(1, -#(split[#split])-2), tonumber(split[#split]), gallop)
    else
        mmp.gotoArea(where, nil, gallop)
    end
end

if mmp.debug then
  mmp.echo(&quot;goto alias took &quot;..stopStopWatch(mmp.gotoPerf)..&quot;s to run.&quot;)
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^goto (.+)$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>View roomID or area</name>
                <script>local where = matches[2]

if not where then
	centerview(mmp.currentroom)
elseif tonumber(where) then -- view a room ID
	centerview(where)
else -- view an area
	mmp.viewArea (where)
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^mmap ?(.+)?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Toggle pause</name>
                <script>mmp.pause(matches[2])</script>
                <command></command>
                <packageName></packageName>
                <regex>^mpp(?:\s?(on|off))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Stop walking</name>
                <script>mmp.stop()</script>
                <command></command>
                <packageName></packageName>
                <regex>^mstop$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Option</name>
                <script>if not matches[2] then
	mmp.settings:showAllOptions()
	return
end

local val = matches[4]
if val == &quot;true&quot; or val == &quot;yes&quot; or val == &quot;on&quot; then val = true end
if val == &quot;false&quot; or val == &quot;no&quot; or val == &quot;off&quot; then val = false end

mmp.settings:setOption(matches[3], val)</script>
                <command></command>
                <packageName></packageName>
                <regex>^mconfig( (\w+) (.*))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Display area for lock/unlock</name>
                <script>mmp.doLockArea(matches[2])</script>
                <command></command>
                <packageName></packageName>
                <regex>^arealock(?: (.*))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Add a room label</name>
                <script>mmp.roomLabel(matches[2])</script>
                <command></command>
                <packageName></packageName>
                <regex>^room label (.+)$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>View/delete area labels</name>
                <script>mmp.areaLabels(matches[2])</script>
                <command></command>
                <packageName></packageName>
                <regex>^area labels ?(.+)?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Room find</name>
                <script>mmp.roomFind(matches[2])</script>
                <command></command>
                <packageName></packageName>
                <regex>^(?:rf|room find) (.+)$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Room look</name>
                <script>mmp.roomLook(matches[2])</script>
                <command></command>
                <packageName></packageName>
                <regex>^(?:rl|room look)(?: (.+))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Room list</name>
                <script>mmp.echoRoomList(matches[2] or mmp.areatabler[getRoomArea(mmp.currentroom)])</script>
                <command></command>
                <packageName></packageName>
                <regex>^room list(?: (.+))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Area list</name>
                <script>mmp.echoAreaList()</script>
                <command></command>
                <packageName></packageName>
                <regex>^area list$</regex>
            </Alias>
            <AliasGroup isActive="no" isFolder="yes">
                <name>mm Mapping</name>
                <script></script>
                <command></command>
                <packageName></packageName>
                <regex></regex>
                <Alias isActive="yes" isFolder="no">
                    <name>Manually set the room coordinates</name>
                    <script>-- want the current room, but we're lost
if matches[2] == '' and (not mmp.currentroom or not mmp.roomexists(mmp.currentroom)) then mmp.echo(&quot;Don't know where we are at the moment.&quot;) return end

-- want another room, but it doesn't actually exist
if matches[2] ~= '' and not mmp.roomexists(matches[2]) then mmp.echo(&quot;v&quot;..matches[2]..&quot; doesn't exist.&quot;) return end

local m = matches[3]
local rid, rname = (matches[2] ~= &quot;&quot; and matches[2] or mmp.currentroom),
  (matches[2] ~= &quot;&quot; and getRoomName(matches[2]) or mmp.currentroomname)
local x,y,z

local function set() -- small func to set things
  setRoomCoordinates(rid, x, y, z)
  mmp.echo(string.format(&quot;%s (%d) is now at %dx, %dy, %dz.\n&quot;, rname, rid, x,y,z))
  centerview(rid)
end

-- let's be flexible and allow several ways if giving an arg
-- rc x y z
x,y,z = string.match(m, &quot;(%-?%d+) (%-?%d+) (%-?%d+)&quot;)
if x then
  set(); return
end

-- rc xx? yy? zz?
x,y,z = string.match(m, &quot;(%-?%d+)x&quot;), string.match(m, &quot;(%-?%d+)y&quot;), string.match(m, &quot;(%-?%d+)z&quot;)
if x or y or z then
  -- merge w/ old coords if any are missing
  local ox, oy, oz = getRoomCoordinates(rid)
  x = x or ox; y = y or oy; z = z or oz
  set(); return
end

-- rc left/west, right/east, ...
local ox, oy, oz = getRoomCoordinates(rid)
local has = table.contains
for w in string.gmatch(m, &quot;%a+&quot;) do
  if has({&quot;west&quot;, &quot;left&quot;, &quot;w&quot;, &quot;l&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy); z = (z or oz)
  elseif has({&quot;east&quot;, &quot;right&quot;, &quot;e&quot;, &quot;r&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy); z = (z or oz)
  elseif has({&quot;north&quot;, &quot;top&quot;, &quot;n&quot;, &quot;t&quot;}, w) then
    x = (x or ox); y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;south&quot;, &quot;bottom&quot;, &quot;s&quot;, &quot;b&quot;}, w) then
    x = (x or ox); y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;northwest&quot;, &quot;topleft&quot;, &quot;nw&quot;, &quot;tl&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;northeast&quot;, &quot;topright&quot;, &quot;ne&quot;, &quot;tr&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;southeast&quot;, &quot;bottomright&quot;, &quot;se&quot;, &quot;br&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;southwest&quot;, &quot;bottomleft&quot;, &quot;sw&quot;, &quot;bl&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;up&quot;, &quot;u&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) + 1
  elseif has({&quot;down&quot;, &quot;d&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) - 1
  end

end
if x then set(); return end

mmp.echo([[Where do you want to move the room to?
  You can use direct coordinates or relative directions.]])</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^(?:rc|room coords) (?:v(\d+) )?(.+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Add a special exit</name>
                    <script>-- spe clear and spe list match on this
if matches[2] == &quot;clear&quot; or matches[2] == &quot;list&quot; then return end

-- need the current room, but we're lost
if not mmp.currentroom or not mmp.roomexists(mmp.currentroom) then mmp.echo(&quot;Don't know where we are at the moment.&quot;) return end

local otherroom = tonumber(matches[2]) or mmp.relativeroom(mmp.currentroom, matches[2])

-- need the another room, but it doesn't actually exist
if not otherroom or not mmp.roomexists(otherroom) then mmp.echo(matches[2]..&quot; doesn't exist.&quot;) return end

addSpecialExit(mmp.currentroom, tonumber(otherroom), matches[3])
addSpecialExit(mmp.currentroom, tonumber(otherroom), matches[3])
mmp.echo(string.format(&quot;Added special exit with command '%s' to %s (%d).&quot;, matches[3], getRoomName(otherroom), otherroom))
centerview(mmp.currentroom)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^(?:spe|exit special) (\w+) (.+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Add a special exit from one remote room to another</name>
                    <script>local room1, room2 = tonumber(matches[2]), tonumber(matches[3])

if not room1 or not mmp.roomexists(room1) then
  mmp.echo(&quot;Room #&quot;..matches[2]..&quot; doesn't exist - create it first, or make sure you got the room ID right?&quot;)
  return
end

if not room2 or not mmp.roomexists(room2) then
  mmp.echo(&quot;Room #&quot;..matches[3]..&quot; doesn't exist - create it first, or make sure you got the room ID right?&quot;)
  return
end

addSpecialExit(room1, room2, matches[4])
mmp.echo(string.format(&quot;Added special exit with command '%s' to from %s (%d) to %s (%d).&quot;, matches[4], getRoomName(room1), room1, getRoomName(room2), room2))</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^spev (\d+) (\d+) (.+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>List special exits</name>
                    <script>mmp.listSpecialExits(matches[2])</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^spe list(?: (.+))?$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Clear all special exits</name>
                    <script>-- want the current room, but we're lost
if not matches[2] and (not mmp.currentroom or not mmp.roomexists(mmp.currentroom)) then mmp.echo(&quot;Don't know where we are at the moment.&quot;) return end

-- want another room, but it doesn't exist
if matches[2] and tonumber(matches[2]) and not mmp.roomexists(matches[2]) then mmp.echo(&quot;v&quot;..matches[2]..&quot; doesn't exist.&quot;) return end

-- or a relative one
if matches[2] and not tonumber(matches[2]) and not mmp.relativeroom(mmp.currentroom, matches[2]) then mmp.echo(&quot;There is no room &quot;..matches[2].. &quot; of us.&quot;) return end

local rid = (not matches[2] and mmp.currentroom or (tonumber(matches[2]) or mmp.relativeroom(mmp.currentroom, matches[2])))

clearSpecialExits(rid)
mmp.echo(string.format(&quot;Cleared all special exits in %s (%d).\n&quot;, getRoomName(rid), rid))</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^(?:spe clear|exit special clear) ?(\w+)?$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Create a room</name>
                    <script>local m = matches[2]
local rid, rname
if mmp.roomexists(mmp.currentroom) then
  rid, rname = mmp.currentroom, mmp.currentroomname
end
local x,y,z

local function set(newid) -- small func to set things
  local rid = newid or createRoomID()
  addRoom(rid)
  setRoomCoordinates(rid, x, y, z)
  if mmp.roomexists(mmp.currentroom) then setRoomArea(rid, getRoomArea(mmp.currentroom)) end
  if mmp.roomexists(mmp.currentroom) then setRoomEnv(rid, getRoomEnv(mmp.currentroom)) end
  setExit(mmp.currentroom, rid, m)
  mmp.echo(string.format(&quot;Created new room (%d) at %dx, %dy, %dz.\n&quot;, rid, x,y,z))
  centerview(mmp.roomexists(mmp.currentroom) and mmp.currentroom or rid)
  if not mmp.roomexists(mmp.currentroom) then mmp.currentroom = rid; mmp.currentroomname = &quot;&quot; end
end

-- let's be flexible and allow several ways if giving an arg
-- rc v# x y z
newid, x,y,z = string.match(m, &quot;v(%d+) (%-?%d+) (%-?%d+) (%-?%d+)&quot;)
if x then
  set(newid); return
end

-- rc x y z
x,y,z = string.match(m, &quot;(%-?%d+) (%-?%d+) (%-?%d+)&quot;)
if x then
  set(); return
end


if not rid then
  mmp.echo(&quot;Don't know where we are at the moment in order to use relative coordinates.&quot;)
  return
end

-- rc xx? yy? zz?
x,y,z = string.match(m, &quot;(%-?%d+)x&quot;), string.match(m, &quot;(%-?%d+)y&quot;), string.match(m, &quot;(%-?%d+)z&quot;)
if x or y or z then
  -- merge w/ old coords if any are missing
  local ox, oy, oz = getRoomCoordinates(rid)
  x = x or ox; y = y or oy; z = z or oz
  set(); return
end

-- rc left/west, right/east, ...
local ox, oy, oz = getRoomCoordinates(rid)
local has = table.contains
for w in string.gmatch(m, &quot;%a+&quot;) do
  if has({&quot;west&quot;, &quot;left&quot;, &quot;w&quot;, &quot;l&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy); z = (z or oz)
  elseif has({&quot;east&quot;, &quot;right&quot;, &quot;e&quot;, &quot;r&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy); z = (z or oz)
  elseif has({&quot;north&quot;, &quot;top&quot;, &quot;n&quot;, &quot;t&quot;}, w) then
    x = (x or ox); y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;south&quot;, &quot;bottom&quot;, &quot;s&quot;, &quot;b&quot;}, w) then
    x = (x or ox); y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;northwest&quot;, &quot;topleft&quot;, &quot;nw&quot;, &quot;tl&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;northeast&quot;, &quot;topright&quot;, &quot;ne&quot;, &quot;tr&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;southeast&quot;, &quot;bottomright&quot;, &quot;se&quot;, &quot;br&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;southwest&quot;, &quot;bottomleft&quot;, &quot;sw&quot;, &quot;bl&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;up&quot;, &quot;u&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) + 1
  elseif has({&quot;down&quot;, &quot;d&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) - 1
  end

end
if x then set(); return end

mmp.echo([[Where do you want to move the room to?
  You can use direct coordinates or relative directions.]])</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^(?:rlc|room create) (.+)?$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Create a link between two rooms</name>
                    <script>-- need the current room, but we're lost
if not mmp.currentroom or not mmp.roomexists(mmp.currentroom) then mmp.echo(&quot;Don't know where we are at the moment.&quot;) return end

-- make sure the dir is valid
local dir = mmp.anytolong(matches[3])
if not dir then mmp.echo(matches[3]..&quot; isn't a valid normal exit.&quot;) return end

-- if we don't give a room number, then we want to auto-locate an appropriate room nearby.
local otherroom
if matches[2] == &quot;&quot; then
  local w = matches[3]
  local ox, oy, oz, x,y,z = getRoomCoordinates(mmp.currentroom)
  local has = table.contains
  if has({&quot;west&quot;, &quot;left&quot;, &quot;w&quot;, &quot;l&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy); z = (z or oz)
  elseif has({&quot;east&quot;, &quot;right&quot;, &quot;e&quot;, &quot;r&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy); z = (z or oz)
  elseif has({&quot;north&quot;, &quot;top&quot;, &quot;n&quot;, &quot;t&quot;}, w) then
    x = (x or ox); y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;south&quot;, &quot;bottom&quot;, &quot;s&quot;, &quot;b&quot;}, w) then
    x = (x or ox); y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;northwest&quot;, &quot;topleft&quot;, &quot;nw&quot;, &quot;tl&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;northeast&quot;, &quot;topright&quot;, &quot;ne&quot;, &quot;tr&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;southeast&quot;, &quot;bottomright&quot;, &quot;se&quot;, &quot;br&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;southwest&quot;, &quot;bottomleft&quot;, &quot;sw&quot;, &quot;bl&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;up&quot;, &quot;u&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) + 1
  elseif has({&quot;down&quot;, &quot;d&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) - 1
  end

  local carea = getRoomArea(mmp.currentroom)
  if not carea then mmp.echo(&quot;Don't know what area are we in.&quot;) return end

  otherroom = select(2, next(getRoomsByPosition(carea,x,y,z)))

  if not otherroom then
    mmp.echo(&quot;There isn't a room to the &quot;..w..&quot; that I see - try with an exact room id.&quot;) return
  end

else
  if not mmp.roomexists(matches[2]) then -- check that an explicit other room ID is valid
    mmp.echo(&quot;A room with id &quot;..matches[2].. &quot; doesn't exist.&quot;) return
  else
    otherroom = tonumber(matches[2])
  end
end

if setExit(mmp.currentroom, otherroom, matches[3]) then
  if not matches[4] then setExit(otherroom, mmp.currentroom, mmp.ranytolong(matches[3])) end

  mmp.echo(string.format(&quot;Linked %s (%d) to %s (%d) via a %s%s exit.&quot;,
    (getRoomName(mmp.currentroom) ~= &quot;&quot; and getRoomName(mmp.currentroom) or &quot;''&quot;), mmp.currentroom, (getRoomName(otherroom) ~= &quot;&quot; and getRoomName(otherroom) or &quot;''&quot;), otherroom, (matches[4] and &quot;one-way &quot; or ''), matches[3]))
else
  mmp.echo(&quot;Couldn't create an exit.&quot;)
end
centerview(mmp.currentroom)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^(?:rlk|room link) ?(\d+)? (\w+)( one)?$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Delete a room</name>
                    <script>-- want the current room, but we're lost
if not matches[2] and (not mmp.currentroom or not mmp.roomexists(mmp.currentroom)) then mmp.echo(&quot;Don't know where we are at the moment.&quot;) return end

-- want another room, but it doesn't exist
if matches[2] and tonumber(matches[2]) and not mmp.roomexists(matches[2]) then mmp.echo(&quot;v&quot;..matches[2]..&quot; doesn't exist.&quot;) return end

-- or a relative one
if matches[2] and not tonumber(matches[2]) and not mmp.relativeroom(mmp.currentroom, matches[2]) then mmp.echo(&quot;There is no room &quot;..matches[2].. &quot; of us.&quot;) return end

local rid = (not matches[2] and mmp.currentroom or (tonumber(matches[2]) or mmp.relativeroom(mmp.currentroom, matches[2])))

local n = getRoomName(rid)
deleteRoom(rid)
mmp.echo(string.format(&quot;Deleted the %s (%d) room.\n&quot;, (n ~= &quot;&quot; and n or &quot;''&quot;), rid))
centerview(mmp.currentroom)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^(?:rld|room delete) ?(\w+)?$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Delete a link</name>
                    <script>-- need the current room, but we're lost
if not mmp.currentroom or not mmp.roomexists(mmp.currentroom) then mmp.echo(&quot;Don't know where we are at the moment.&quot;) return end

-- make sure the dir is valid
local dir = mmp.anytolong(matches[2])
if not dir then mmp.echo(matches[2]..&quot; isn't a valid normal exit.&quot;) return end

-- gone already?
if not getRoomExits(mmp.currentroom)[dir] then mmp.echo(dir..&quot; link doesn't exist already.&quot;) end

-- locate the room on the other end, so we can unlink it from there as well if necessary
local otherroom
if getRoomExits(getRoomExits(mmp.currentroom)[dir])[mmp.ranytolong(dir)] then
  otherroom = getRoomExits(mmp.currentroom)[dir]
end

if setExit(mmp.currentroom, -1, dir) then
  if otherroom then
    if setExit(otherroom, -1, mmp.ranytolong(dir)) then
      mmp.echo(string.format(&quot;Deleted the %s exit from %s (%d).&quot;,
        dir, getRoomName(mmp.currentroom), mmp.currentroom))
     else mmp.echo(&quot;Couldn't delete the incoming exit.&quot;) end
  else
    mmp.echo(string.format(&quot;Deleted the one-way %s exit from %s (%d).&quot;,
      dir, getRoomName(mmp.currentroom), mmp.currentroom))
  end
else
  mmp.echo(&quot;Couldn't delete the outgoing exit.&quot;)
end
centerview(mmp.currentroom)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^(?:urlk|room unlink) (\w+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Move room to another area</name>
                    <script>mmp.roomArea(matches[2], matches[3])</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^room area (?:v(\d+) )?(.+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Set a room character</name>
                    <script>local room = matches[3] or mmp.currentroom
room = tonumber(room) or mmp.relativeroom(mmp.currentroom, room)
if not room or not mmp.roomexists(room) then
  mmp.echo(&quot;Sorry - which room do you want to put this character in? I don't know where you are at the moment, if you want to do the current room.&quot;)
  return
end

local char = matches[2]

if char == &quot;clear&quot; then
  setRoomChar(room, ' ')
  mmp.echo(&quot;Cleared the character from &quot;..room..&quot; (&quot;..getRoomName(room)..&quot;)&quot;)
else
  setRoomChar(room, char)
  mmp.echo(&quot;Set the &quot;..char:sub(1,1)..&quot; character on &quot;..room..&quot; (&quot;..getRoomName(room)..&quot;)&quot;)
end
centerview(mmp.currentroom)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^rcc ([^ ]+)(?: (\w+))?$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Set room weight</name>
                    <script>local weight = tonumber(matches[3]), room
if matches[2] == '' then room = mmp.currentroom
else
  room = tonumber(matches[2]) or mmp.relativeroom(mmp.currentroom, matches[2])
end

if not room or not mmp.roomexists(room) then
  mmp.echo(&quot;Sorry - which room do you want to set the weight on? I don't know where you are at the moment, if you want to do the current room.&quot;)
  return
end

if not weight then
  mmp.echo(&quot;What weight do you want to set on #&quot;..room..&quot;?&quot;)
end

local oldweight = getRoomWeight(room)
setRoomWeight(room, weight)

if weight &gt; oldweight then
  mmp.echo(&quot;Increased the room weight on #&quot;..room..&quot; (&quot;..getRoomName(room)..&quot;) by &quot;..(weight-oldweight)..&quot; to &quot;..weight..&quot; - making it less desirable to travel through.&quot;)
elseif weight &lt; oldweight then
  mmp.echo(&quot;Decreased the room weight on #&quot;..room..&quot; (&quot;..getRoomName(room)..&quot;) by &quot;..(oldweight-weight)..&quot; to &quot;..weight..&quot; - making it more desirable to travel through.&quot;)
else
  mmp.echo(&quot;The room weight on #&quot;..room..&quot; (&quot;..getRoomName(room)..&quot;) is already &quot;..weight..&quot;.&quot;)
end</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^rw(?: (\w+))? (\d+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Set exit weight</name>
                    <script>local room = (matches[2] ~= &quot;&quot; and tonumber(matches[2]) or mmp.currentroom)

local weight, exit = tonumber(matches[3]), matches[4]

if not roomExists(room) then mmp.echo(&quot;Room &quot;..room..&quot; doesn't exist. It has to before we can set weights on exits.&quot;) return end

setExitWeight(room, exit, weight)

mmp.echo(string.format(&quot;Set the weight on the %d room going %s to %s. If it's a two-way exit, please set the reverse exit as well.&quot;, room, exit, weight))</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^rwe(?: (\d+))? (\d+) (.+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Add/delete doors</name>
                    <script>local room = (matches[2] ~= &quot;&quot; and tonumber(matches[2]) or mmp.currentroom)

local direction, status = matches[3], matches[4]

if not roomExists(room) then mmp.echo(&quot;Room &quot;..room..&quot; doesn't exist. It has to before we can make doors in it.&quot;) return end

local validdirs = {'e', 's', 'w', 'n', 'ne', 'se', 'sw', 'nw', 'in', 'out', 'up', 'down'}

if not table.contains(validdirs, direction) then
  mmp.echo(&quot;Can't make a door in the '&quot;..direction..&quot;' direction - available choices are:\n  &quot;..table.concat(validdirs, ', '))
  return
end

local statusnum

if status == &quot;&quot; or status == &quot;open&quot; or status == &quot;o&quot; then
  statusnum = 1
elseif status == &quot;closed&quot; or status ==  &quot;c&quot; then
  statusnum = 2
elseif status == &quot;locked&quot; or status ==  &quot;l&quot; then
  statusnum = 3
elseif status == &quot;clear&quot; or status == &quot;gone&quot; then
  statusnum = 0
end

if not statusnum then mmp.echo(&quot;Unrecognized option - a door can be open, closed, locked or gone.&quot;) return end

setDoor(room, direction, statusnum)

if statusnum == 0 then
  mmp.echo(&quot;OK, door removed.&quot;)
else
  mmp.echo(&quot;OK, door added/adjusted.&quot;)
end</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^rd(?: (\d+))? (\w+)(?: (\w+))?$</regex>
                </Alias>
                <Alias isActive="no" isFolder="no">
                    <name>-- (area functions)</name>
                    <script></script>
                    <command></command>
                    <packageName></packageName>
                    <regex></regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Create an area</name>
                    <script>local t = getAreaTable(); local tr = {}; for k,v in pairs(t) do tr[v] = k end
local newid = table.maxn(tr) + 1

setAreaName( newid, matches[2] )
mmp.echo(string.format(&quot;Created new area %s (%d)&quot;, matches[2], newid))
centerview(mmp.currentroom)
raiseEvent(&quot;mmp areas changed&quot;)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^area add (.+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Delete an area</name>
                    <script>mmp.deleteArea(matches[2])</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^area delete (.+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Cancel area deletion</name>
                    <script>if not mmp.deletingarea then mmp.echo(&quot;I wasn't deleting any areas already.&quot;) return end

local areaname = mmp.deletingarea.areaname
mmp.deletingarea = nil

mmp.echo(&quot;Stopped deleting rooms in the '&quot;..areaname..&quot;'. The area is partially missing its rooms now, you'll want to restart the process to finish it.&quot;)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^cancel area deletion$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Rename an area</name>
                    <script>mmp.renameArea(matches[2])</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^area rename (.+)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>List continents</name>
                    <script>local continents = mmp.getcontinents()

if not next(continents) then mmp.echo(&quot;No continents known.&quot;)
else
  for continent, areadata in pairs(continents) do
    mmp.echo(continent..&quot; continent:&quot;)

    for _, areaid in ipairs(areadata) do
      cecho(&quot;  &quot;..getRoomAreaName(areaid)..&quot;\n&quot;)
    end
  end
end</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^(?:acl|area continents)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Add area to continent</name>
                    <script>-- ac continent [optional area]

local continent = matches[2]:title()
local area
if not matches[3] then area = getRoomArea(mmp.currentroom)
elseif tonumber(matches[3]) then
  area = tonumber(matches[3])
  if getRoomAreaName(area) == -1 then area = nil end
else
  local areas = getAreaTable()

  for karea, id in pairs(areas) do if karea:lower():find(matches[3]:lower(), 1, true) then area = id break end end
end

if not area then mmp.echo(matches[3]..&quot; isn't a known area. Which one do you want to set?&quot;) return end

local res, error = mmp.addcontinent(area, continent)
if res then
  mmp.echo(&quot;Recorded that &quot;..getRoomAreaName(area)..&quot; is on the &quot;..continent..&quot; continent.&quot;)
else
  mmp.echo(error)
end</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^ac ([\w']+)(?: (.+))?$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>remove area from continent</name>
                    <script>-- acr continent [optional area]

local continent = matches[2]:title()
local area
if not matches[3] then area = getRoomArea(mmp.currentroom)
elseif tonumber(matches[3]) then
  area = tonumber(matches[3])
  if getRoomAreaName(area) == -1 then area = nil end
else
  local areas = getAreaTable()

  for karea, id in pairs(areas) do if karea:lower():find(matches[3]:lower(), 1, true) then area = id break end end
end

if not area then mmp.echo(matches[3]..&quot; isn't a known area. Which one do you want to set?&quot;) return end

local res, error = mmp.removecontinent(area, continent)
if res then
  mmp.echo(&quot;Recorded that &quot;..getRoomAreaName(area)..&quot; is not on the &quot;..continent..&quot; continent.&quot;)
else
  mmp.echo(error)
end</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^acr ([\w']+)(?: (.+))?$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Add/remove a ferry room</name>
                    <script>local room = tonumber(matches[2])

-- load the ferry rooms if they haven't been already
if not mmp.ferry_rooms then
  local tmp = getRoomUserData(1, &quot;ferry rooms&quot;)

  mmp.ferry_rooms = {}
  if tmp ~= &quot;&quot; then
    for _, i in ipairs(yajl.to_value(tmp)) do
      mmp.ferry_rooms[i] = true
    end
  end
end

if matches[3] == &quot;add&quot; then
  if mmp.ferry_rooms[room] then
    mmp.echo(&quot;Ferry room #&quot;..room..&quot; is already recorded as such.&quot;) return
  else
    mmp.ferry_rooms[room] = true; mmp.echo(&quot;Added #&quot;..room..&quot; to be a ferry room.&quot;)
  end
else
  if not mmp.ferry_rooms[room] then
    mmp.echo(&quot;Room #&quot;..room..&quot; isn't a ferry one already.&quot;) return
  else
    mmp.ferry_rooms[room] = nil; mmp.echo(&quot;Removed #&quot;..room..&quot; from being a ferry room.&quot;)
  end
end

local keys = {}; for k,_ in pairs(mmp.ferry_rooms) do keys[#keys+1] = k end

setRoomUserData(1, &quot;ferry rooms&quot;, yajl.to_string(keys))</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^fr (\d+) (add|remove)$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Show ferry rooms</name>
                    <script>if not mmp.ferry_rooms then
  local tmp = getRoomUserData(1, &quot;ferry rooms&quot;)

  mmp.ferry_rooms = {}
  if tmp ~= &quot;&quot; then
    for _, i in ipairs(yajl.to_value(tmp)) do
      mmp.ferry_rooms[i] = true
    end
  end
end

mmp.echo(&quot;Ferry rooms available:&quot;)
if not next(mmp.ferry_rooms) then  mmp.echo(&quot;(none)&quot;) return end

for k, _ in pairs(mmp.ferry_rooms) do
  mmp.echo(string.format(&quot;  (%d) - %s\n&quot;, k, getRoomName(k)))
end</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^fr show$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Weight ferry exits</name>
                    <script>  local c = 0
  local weight = 200
  for area in pairs(mmp.areatabler) do
    local rooms = getAreaRooms(area) or {}
    for i = 0, #rooms do
      local exits = getSpecialExits(rooms[i] or 0)

       if exits and next(exits) then
         for exit, cmd in pairs(exits) do
           if type(cmd) == &quot;table&quot; then cmd = next(cmd) end

           if (cmd:lower():find(&quot;buy passage to&quot;, 1, true)) then
				setExitWeight(rooms[i], cmd, weight)
				mmp.echo(&quot;Weighted &quot;..cmd..&quot; going to &quot;..rooms[i]..&quot; (&quot;..getRoomName(rooms[i])..&quot;).&quot;)
             c = c + 1
           end
         end
       end
    end
  end

  mmp.echo(string.format(&quot;%s ferry exits weighted to %s (so we don't take them over too short distances).&quot;, c, weight))</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^weight ferry exits$</regex>
                </Alias>
                <Alias isActive="no" isFolder="no">
                    <name>-- (dangerous functions)</name>
                    <script></script>
                    <command></command>
                    <packageName></packageName>
                    <regex></regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Clear the map completely</name>
                    <script>if not mmp.map_delete_warning then
  mmp.echo(&quot;Are you really, really, really sure you want to delete all of the map to go to a blank state? Do the command again if you're certain.&quot;)
  mmp.map_delete_warning = true
  return
end

mmp.echo(&quot;Okay, deleting...&quot;)

tempTimer(.1, function()
  for name, id in pairs(getAreaTable()) do
    deleteArea(tonumber(id))
  end

  mmp.echo(&quot;Deleted everything. It's all gone.&quot;)
  mmp.map_delete_warning = nil
  centerview(1)
end)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^map delete all$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Delete shop stockroom exits</name>
                    <script>mmp.echo(&quot;Deleting all known stockroom exits (rooms with $ and a down exit)&quot;)
local c = 0

for area, areaname in pairs(mmp.areatabler) do
  local rooms = getAreaRooms(area) or {}
  for i = 0, #rooms do
    local char = getRoomChar(rooms[i] or 0)
    if char == '$' then
      local exits = getRoomExits(rooms[i] or 0) -- retrieve after $, more efficient

      if exits.down then
        setExit(rooms[i], -1, 'down')
        mmp.echo(string.format(&quot;Deleted the stockroom exit at %s (#%d in %s)&quot;, getRoomName(rooms[i]), rooms[i], mmp.areatabler[getRoomArea(rooms[i])]))
        c = c + 1
      end
    end

  end
end

mmp.echo(string.format(&quot;Deleted %s known stockroom exit%s.&quot;, c, (c ~= 1 and 's' or '')))
centerview(mmp.currentroom)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^delete known stockrooms$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Clear continent data</name>
                    <script>if not mmp.wipingcontinents then
  mmp.wipingcontinents = true
  mmp.echo(&quot;Are you sure you want to wipe all continent data? If yes, do this again.&quot;)
  return
end
mmp.wipingcontinents = nil

local toserialize = yajl.to_string{}
setRoomUserData(1, &quot;areaContinents&quot;, toserialize)
mmp.echo(&quot;Wiped all continents data.&quot;)</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^clear continent data$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Delete suffixed periods</name>
                    <script>mmp.echo(&quot;Deleting removing all periods at the end of room names...&quot;)
local c = 0

for area, areaname in pairs(mmp.areatabler) do
  local rooms = getAreaRooms(area) or {}
  for i = 0, #rooms do
    local name = getRoomName(rooms[i] or 0)
    if string.ends(name, &quot;.&quot;) then
      name = string.sub(name, 1, (#name-1))
      setRoomName(rooms[i], name)
      mmp.echo(string.format(&quot;Patched up room #%s - '%s'&quot;, rooms[i], name))
      c = c + 1
    end
  end
end

mmp.echo(string.format(&quot;Fixed up %s room%s.&quot;, c, (c ~= 1 and 's' or '')))</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^delete suffixed periods$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Find single exits</name>
                    <script>local c = 0

local getAreaRooms, getRoomExits, contains, echoLink, getRoomEnv, envidsr =
  getAreaRooms, getRoomExits, table.contains, echoLink, getRoomEnv, mmp.envidsr

for area, id in pairs(getAreaTable()) do
  for _, roomid in pairs(getAreaRooms(id)) do
    local exits = getRoomExits(roomid)
    for dir, otherroom in pairs(exits) do
      local otherexits = getRoomExits(otherroom) or {}
      if not contains(otherexits, roomid) then
        echoLink(string.format(&quot;%s -&gt; %s is oneway (%s-&gt;%s type)\n&quot;, roomid, otherroom,
          (envidsr and envidsr[getRoomEnv(roomid)] or &quot;?&quot;),
          (envidsr and envidsr[getRoomEnv(otherroom)] or &quot;?&quot;)),
        [[mmp.gotoRoom(]]..roomid..[[)]], &quot;Click to go to the start room &quot;..roomid, true)
        c = c + 1
     end
    end
  end
end

mmp.echo(string.format(&quot;Found %s oneways.%s&quot;, c, (c &gt; 10 and &quot; Have fun. Click on lines to go to the rooms.&quot; or &quot;&quot;)))</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^find single exits$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Show char marks</name>
                    <script>local c = 0
local m = {}
local areas = getAreaTable()
local show_area = table.size(areas) &gt; 1 and true or false

for area, id in pairs(areas) do
  for _, roomid in pairs(getAreaRooms(id)) do
    local c = getRoomChar(roomid)
    if c ~= '' and c ~= ' ' then
      m[c] = m[c] or {}
      m[c][#m[c]+1] = roomid
    end
  end
end

if not next(m) then mmp.echo(&quot;This map has no char marks on it. Do mc on and rcc &lt;mark&gt; in a room to add them!&quot;) return end

for letter, rooms in pairs(m) do
  table.sort(rooms)
  mmp.echo(&quot;Rooms with the &lt;blue&gt;&quot;..letter..&quot;&lt;reset&gt; character on them:&quot;)
  for i = 1, #rooms do
    if not show_area then
      cecho(string.format(&quot;  &lt;sea_green&gt;%-5s&lt;reset&gt; %s\n&quot;, rooms[i], getRoomName(rooms[i])))
    else
      cecho(string.format(&quot;  &lt;sea_green&gt;%-5s&lt;reset&gt; %-35s &lt;dim_grey&gt;(in&lt;reset&gt; %s&lt;dim_grey&gt;)\n&quot;, rooms[i], getRoomName(rooms[i]), mmp.areatabler[getRoomArea(rooms[i])]))
    end
  end
end</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^show char marks$</regex>
                </Alias>
                <Alias isActive="yes" isFolder="no">
                    <name>Delete all special exits across a map</name>
                    <script>mmp.delSpecialExits(matches[2])</script>
                    <command></command>
                    <packageName></packageName>
                    <regex>^spe delete all(?: (.+))?$</regex>
                </Alias>
            </AliasGroup>
            <Alias isActive="yes" isFolder="no">
                <name>Toggle mapping mode</name>
                <script>if (matches[2] and matches[2] == &quot;on&quot;) or (not matches[2] and not mmp.editing) then
  mmp.editing = true
  enableAlias(&quot;mm Mapping&quot;)

  mmp_regenerate_areas()
  mmp.highlight_unfinished_rooms()

  mmp.echo(&quot;Mapping mode enabled. Happy mapping!&quot;)
elseif (matches[2] and matches[2] == &quot;off&quot;) or (not matches[2] and mmp.editing) then
  mmp.editing = false
  disableAlias(&quot;mm Mapping&quot;)
  mmp.echo(&quot;Mapping mode disabled.&quot;)
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^(?:mc|map create) ?(on|off)?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Save a map</name>
                <script>local function s(loc)
    if not saveMap(loc) then
      mmp.echo(&quot;Couldn't save the map :(&quot;)
    else
      if loc ~= &quot;&quot; then mmp.echo(&quot;Map saved.&quot;) else mmp.echo(&quot;Saved the default map.&quot;) end
    end
end

if not saveMap then
  mmp.echo(&quot;Your Mudlet can't save maps. Please upgrade it!&quot;)
else
  if matches[2] and matches[2] == &quot;custom&quot; then
    s(invokeFileDialog(false, &quot;Please select the folder to save the map in and hit Open&quot;)..&quot;/Mudlet map from &quot;..os.date(&quot;%A %d, %b '%y&quot;)..&quot;.dat&quot;)
  elseif matches[2] then
	s(getMudletHomeDir()..&quot;/map/&quot;..matches[2])
  else
    s(&quot;&quot;)
  end
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^map save(?: (.+))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Load a map</name>
                <script>local function s(loc)
    if not loadMap(loc) then
      mmp.echo(&quot;Couldn't load the map :(&quot;)
    else
      mmp.lockWormholes(); mmp.lockSewers(); mmp.lockPebble();
      if mmp.settings.waterwalk then mmp.enableWaterWalk() else mmp.disableWaterWalk() end

      if loc ~= &quot;&quot; then mmp.echo(&quot;Map loaded.&quot;) else mmp.echo(&quot;Loaded the default map.&quot;) end
      raiseEvent(&quot;mmapper updated map&quot;)
    end
end

if not loadMap then
  mmp.echo(&quot;Your Mudlet can't load maps. Please upgrade it!&quot;)
else
  if matches[2] and matches[2] == &quot;custom&quot; then
    s(invokeFileDialog(true, &quot;Please select the map file and click Open to load it&quot;))
  elseif matches[2] then
	s(getMudletHomeDir()..&quot;/map/&quot;..matches[2])
  else
    s(&quot;&quot;)
  end
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^map load(?: (.+))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Get dirs</name>
                <script>if not matches[2] and not matches[3] then
  mmp.echo(&quot;Where do you want to showpath to?&quot;)
elseif matches[2] and not matches[3] then
  mmp.echoPath(mmp.currentroom, matches[2])
else
  mmp.echoPath(matches[2], matches[3])
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^showpath(?: (\d+))?(?: (\d+))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Check wholist</name>
                <script>enableTrigger(&quot;Parse wholist&quot;)
send(&quot;who b&quot;)
tempTimer(10, [[disableTrigger'Parse wholist']])</script>
                <command></command>
                <packageName></packageName>
                <regex>^who b$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Add Room Mark</name>
                <script>local tmp = getRoomUserData(1, &quot;gotoMapping&quot;)
local maptable = {}

if tmp ~= &quot;&quot; then
  maptable = yajl.to_value(tmp)
end

local location, markname
if tonumber(matches[2]) then
  location = matches[2]; markname = matches[3]
else
  location = matches[3]; markname = matches[2]
end

-- can't allow mark name to ne a number - yajl then generates a giant table of null's
if tonumber(markname) then
  mmp.echo(&quot;The mark name can't be a number.&quot;) return
end

maptable[markname] = location
local tmp2 = yajl.to_string(maptable)

if not mmp.roomexists(1) then
  addRoom(1)
end

setRoomUserData(1, &quot;gotoMapping&quot;, tmp2)
mmp.echo(string.format(&quot;Room mark for '%s' set to room %s.&quot;, markname, location))</script>
                <command></command>
                <packageName></packageName>
                <regex>^room mark (\w+) (\w+)$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Remove Room Mark</name>
                <script>local tmp= getRoomUserData(1, &quot;gotoMapping&quot;)
if tmp~=&quot;&quot; then
  local maptable=yajl.to_value(tmp)
  if not maptable[matches[2]] then mmp.echo(&quot;Don't have such a mark in the db.&quot;) return end

  maptable[matches[2]]=nil
  local tmp2=yajl.to_string(maptable)
  setRoomUserData(1, &quot;gotoMapping&quot;, tmp2)
  mmp.echo(&quot;Removed the &quot;..matches[2]..&quot; mark.&quot;)
else
  mmp.echo(&quot;We don't have any marks stored anyway.&quot;)
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^room unmark (\w+)$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Display Room Marks</name>
                <script>local tmp= getRoomUserData(1, &quot;gotoMapping&quot;)
if tmp~=&quot;&quot; then
	local maptable = yajl.to_value(tmp) or {}
    local sortedkeys = {}
    for k in pairs(maptable) do sortedkeys[#sortedkeys+1] = k end
    table.sort(sortedkeys)

    mmp.echo(&quot;Known marks in this map:&quot;)
    if next(maptable) then
      for i = 1, #sortedkeys do echo(string.format(&quot;  %-21s  %s\n&quot;, tostring(sortedkeys[i]), tostring(maptable[sortedkeys[i]]))) end
    else
      echo(&quot;  (none)\n&quot;)
    end
else
	mmp.echo(&quot;No marks are recorded in this map.&quot;)
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^room marks$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Toggle map sizes</name>
                <script>local size = matches[2]

if size == &quot;biggest&quot; then
  mapper = Geyser.Mapper:new({
    name = &quot;mapper&quot;,
    x = 0, y = 0,
    width = &quot;100%&quot;, height = &quot;97%&quot;
  })
  mmp.echo(&quot;Map size set to pretty damn big.&quot;)

elseif size == &quot;small&quot; then
  mapper = Geyser.Mapper:new({
    x = &quot;70%&quot;, y = 0,
    width = &quot;28%&quot;, height = &quot;50%&quot;
  })
  mmp.echo(&quot;Map size set to comfortable.&quot;)

elseif size == &quot;big&quot; then
  local window_width, window_height = getMainWindowSize()
  local used_width = getMainConsoleWidth()

  local available_space = window_width - used_width

  if matches[3] then available_space = available_space - tonumber(matches[3]) end

  mapper = Geyser.Mapper:new({
    x = available_space*-1, y = 0,
    width = available_space, height = &quot;100%&quot;
  })

  mmp.echo(&quot;Set the map size to big - it'll cover all of the space on the right that game text isn't using. You'll want to call this alias again if you resize the window to update.&quot;)
end</script>
                <command></command>
                <packageName></packageName>
                <regex>^(small|big|biggest)map(?: (\d+))?$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>^make maps$</name>
                <script>local c = 0
for _, id in pairs(getAreaTable()) do
  tempTimer(c*.5, [[exportAreaImage(]]..id..[[)]])
  c = c + 1
end
mmp.echo(&quot;Done!&quot;)</script>
                <command></command>
                <packageName></packageName>
                <regex>^make maps$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>Set debug mode</name>
                <script>if matches[2] == &quot;on&quot; then
  mmp.debug = true
else
  mmp.debug = false
end

mmp.echo(&quot;Debug &amp; performance telemetry &quot;..(mmp.debug and &quot;enabled&quot; or &quot;disabled&quot;)..&quot;.&quot;)</script>
                <command></command>
                <packageName></packageName>
                <regex>^(?:mdg|mdebug) (on|off)$</regex>
            </Alias>
            <Alias isActive="yes" isFolder="no">
                <name>measure getPath()</name>
                <script>mmp = mmp or {}

mmp.getPathPerf = mmp.getPathPerf or createStopWatch()
startStopWatch(mmp.getPathPerf)

local from, to = tonumber(matches[2]), tonumber(matches[3])

getPath(from, to)

mmp.echon = mmp.echon or echo
mmp.echon(&quot;a new getPath() from &quot;..from..&quot; to &quot;..to..&quot; took &quot;..stopStopWatch(mmp.getPathPerf)..&quot;s. There are &quot;..#speedWalkPath..&quot; rooms to visit in it.&quot;)
echo(&quot; &quot;)
echoLink(&quot;[unhighlight]&quot;, [[
  for room in pairs(mmp.getpathhighlights) do
    unHighlightRoom(room)
  end
]], &quot;Click me to remove highlighting from getpath&quot;)

mmp.getpathhighlights = mmp.getpathhighlights or {}

for room in pairs(mmp.getpathhighlights) do
  unHighlightRoom(room)
end

mmp.getpathhighlights = {}

local r,g,b = unpack(color_table.yellow)
local br,bg,bb = unpack(color_table.yellow)
-- add the first room to the speedWalkPath, as we'd like it highlighted as well
table.insert(speedWalkPath, 1, from)
for i = 1, #speedWalkPath do
  local room = speedWalkPath[i]
  highlightRoom(room, r,g,b,br,bg,bb, 1, 255, 255)
  mmp.getpathhighlights[room] = true
end

centerview(from)</script>
                <command></command>
                <packageName></packageName>
                <regex>^getpath (?:from )?(\d+) (?:to )?(\d+)$</regex>
            </Alias>
        </AliasGroup>
    </AliasPackage>
    <ActionPackage/>
    <ScriptPackage>
        <ScriptGroup isActive="yes" isFolder="yes">
            <name>Mudlet Mapper</name>
            <packageName></packageName>
            <script>mudlet = mudlet or {}; mudlet.mapper_script = true</script>
            <eventHandlerList/>
            <Script isActive="yes" isFolder="no">
                <name>Create Option Table</name>
                <packageName></packageName>
                <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------

function createOption(startingValue, onChangeFunc, allowedVarTypes, use)
	if allowedVarTypes then -- make sure our starting Value follows type rules
		if not table.contains(allowedVarTypes, type(startingValue)) then
			echo(&quot;Starting type is not of allowed type!\n&quot;)
			display(allowedVarTypes)
			echo(&quot;type: &quot; .. type(startingValue) .. &quot;\n&quot;)
			return
		end
	end

	local option = {
		value = startingValue,
		onChange = onChangeFunc,
		allowedVarTypes = allowedVarTypes,
		use = use or &quot;&quot;
	}

	return option
end

function createOptionsTable(defaultTable)
	local index = {} -- index to store the default table at in our proxy table


	local proxyTable = {} -- This is the table that is returned to the user

	proxyTable.disp = echo

	proxyTable.dispDefaultWriteError = function()
		echo(&quot;Can't overwrite default options. Please use the SetOption function to change the value\n&quot;)
	end

	proxyTable.dispOption = function(opt, val)
		if not opt or not val then return end
		echo(&quot;Name: &quot; .. string.title(opt) .. string.rep(&quot; &quot;, 10 - string.len(opt)))
		echo(&quot;Val: &quot; .. tostring(val.value))
		echo(string.rep(&quot; &quot;, 10 - string.len(tostring(val.value))) ..  &quot;- &quot; .. val.use .. &quot;\n&quot;)
	end

	function proxyTable:showAllOptions()
		proxyTable.disp(&quot;Available options: \n&quot;)
		for k, v in pairs(self[index]) do
			self.dispOption(k, v)
		end
		echo(&quot;\n&quot;)
		for k, v in pairs(self[&quot;_customOptions&quot;]) do
			self.dispOption(k, v)
		end

	end

	function proxyTable:getAllOptions()
		local t = {}
		for k, v in pairs(self[index]) do
			t[k] = v.value
		end

		return t
	end

   function proxyTable:setOption(option, value, silent)
		if self[option] == nil then
			proxyTable.disp(&quot;No such option!\n&quot;)
			return
		end

		-- otherwise, set the option
		if self[&quot;_customOptions&quot;][option] then
			if not table.contains(self[&quot;_customOptions&quot;][option].allowedVarTypes, type(value)) then
				proxyTable.disp(&quot;You can't set '&quot; .. option .. &quot;' to that!\n&quot;)
				return
			end
			self[&quot;_customOptions&quot;][option].value = value
			if self[&quot;_customOptions&quot;][option].onChange then
				self[&quot;_customOptions&quot;][option].onChange(option, value)
			end
		else
			if not table.contains(self[index][option].allowedVarTypes, type(value)) then
				proxyTable.disp(&quot;You can't set '&quot; .. option .. &quot;' to that!\n&quot;)
				return
			end
			rawset(self[index][option], &quot;value&quot;, value)
			local opt = rawget(self[index], option)
			if opt.onChange  and not silent then opt.onChange(option, value) end
		end
		if mmp and mmp.clearpathcache then mmp.clearpathcache() end
	end


	proxyTable._customOptions = {}

	local mt = {
		__index = function(t, k)
			local custOp = rawget(t, &quot;_customOptions&quot;)
			if custOp[k] then
			 	local opt = custOp[k]
				if opt then return opt.value else return nil end
			else
				local opt = t[index][k]
				if opt then return opt.value else return nil end
			end
		end,

		__newindex = function (t, k, v)
			if t[index][k] then
				proxyTable.dispDefaultWriteError()
			else
				t[&quot;_customOptions&quot;][k] = v
			end
		end
	}


	proxyTable[index] = defaultTable

	setmetatable(proxyTable, mt)

	return proxyTable

end</script>
                <eventHandlerList/>
            </Script>
            <Script isActive="yes" isFolder="no">
                <name>Load settings</name>
                <packageName></packageName>
                <script>-- mmp = mudlet mapper namespace
mmp = mmp or {
  paused = false,
  autowalking = false,
  currentroom = 0,
  currentroomname = &quot;(unknown)&quot;,
  firstRun = true,
  specials = {},
  ferry_rooms = {},
  echo_colour = &quot;MediumBlue&quot;
}

speedWalkWatch = createStopWatch()

-- populated by Mudlet from getPath() and gotoRoom()
speedWalkPath = speedWalkPath or {}
speedWalkDir = speedWalkDir or {}
speedWalkCounter = 0

-- actually used by the mapper for walking
mmp.speedWalkPath = mmp.speedWalkPath or {}
mmp.speedWalkDir = mmp.speedWalkDir or {}


local newversion = &quot;17.6.2&quot;
if mmp.version and mmp.version ~= newversion then
  if not mmp.game then mmp.echo(&quot;Mapper script updated - Thanks! I don't know what game are you connected to, though - so please reconnect, if you could.&quot;)
  else mmp.echo(&quot;Mapper script updated - thanks! You don't need to restart.&quot;) end
end
mmp.version = newversion

function mmp.startup()
  if not mmp.firstRun then
    return
  end

  local private_settings = {}
  private_settings[&quot;belt&quot;]          = createOption(false, mmp.setBelt, { &quot;boolean&quot; }, &quot;Make use of your Belt in Lusternia?&quot;)
  private_settings[&quot;blossom&quot;]       = createOption(false, mmp.setBlossom, { &quot;boolean&quot; }, &quot;Make use of your Flame of dae'Seren in Lusternia?&quot;)
  private_settings[&quot;bonecurio&quot;]     = createOption(false, mmp.setBonecurio, { &quot;boolean&quot; }, &quot;Make use of your Bone curios in Lusternia?&quot;)
  private_settings[&quot;caravan&quot;]       = createOption(false, mmp.changeBoolFunc,{ &quot;boolean&quot; }, &quot;Walk caravans?&quot;)
  private_settings[&quot;cookie&quot;]        = createOption(false, mmp.setCookie, { &quot;boolean&quot; }, &quot;Make use of your Cookie in Lusternia?&quot;)
  private_settings[&quot;crowdmap&quot;]      = createOption(false, mmp.chageMapSource, { &quot;boolean&quot; }, &quot;Use a crowd-sourced map instead of IREs default?&quot;)
  private_settings[&quot;cubix&quot;]         = createOption(false, mmp.setCubix, { &quot;boolean&quot; }, &quot;Make use of your Cubix in Lusternia?&quot;)
  private_settings[&quot;dash&quot;]          = createOption(false, mmp.changeBoolFunc, { &quot;boolean&quot; }, &quot;Use Dash?&quot;)
  private_settings[&quot;duanathar&quot;]     = createOption(false, mmp.setDuanathar, { &quot;boolean&quot; }, &quot;Use Eagle Wings in Achaea?&quot;)
  private_settings[&quot;duanatharan&quot;]   = createOption(false, mmp.setDuanatharan, { &quot;boolean&quot; }, &quot;Use Atavian Wings in Achaea?&quot;)
  private_settings[&quot;duantahar&quot;]     = createOption(false, mmp.setDuantahar, { &quot;boolean&quot; }, &quot;Use Chenubian Wings in Achaea?&quot;)
  private_settings[&quot;facecurio&quot;]     = createOption(false, mmp.setFacecurio, { &quot;boolean&quot; }, &quot;Make use of your Face curios in Lusternia?&quot;)
  private_settings[&quot;feathercurio&quot;]  = createOption(false, mmp.setFeathercurio, { &quot;boolean&quot; }, &quot;Make use of your Feather curios in Lusternia?&quot;)
  private_settings[&quot;figurecurio&quot;]   = createOption(false, mmp.setFigurecurio, { &quot;boolean&quot; }, &quot;Make use of your Figure curios in Lusternia?&quot;)
  private_settings[&quot;fingerblade&quot;]   = createOption(false, mmp.setFingerblade, { &quot;boolean&quot; }, &quot;Make use of your Fingerblade in Lusternia?&quot;)
  private_settings[&quot;flowercurio&quot;]   = createOption(false, mmp.setFlowercurio, { &quot;boolean&quot; }, &quot;Make use of your Flower curios in Lusternia?&quot;)
  private_settings[&quot;fluttercurio&quot;]  = createOption(false, mmp.setFluttercurio, { &quot;boolean&quot; }, &quot;Make use of your Flutter curios in Lusternia?&quot;)
  private_settings[&quot;gallop&quot;]        = createOption(false, mmp.changeBoolFunc, { &quot;boolean&quot; }, &quot;Use Gallop?&quot;)
  private_settings[&quot;head&quot;]          = createOption(false, mmp.setHead, { &quot;boolean&quot; }, &quot;Make use of your Doll's Head in Lusternia?&quot;)
  private_settings[&quot;icicle&quot;]        = createOption(false, mmp.setIcicle, { &quot;boolean&quot; }, &quot;Make use of your Icicle in Lusternia?&quot;)
  private_settings[&quot;lockpathways&quot;]  = createOption(true, mmp.lockPathways, { &quot;boolean&quot; }, &quot;Lock pathway exits?&quot;)
  private_settings[&quot;locksewers&quot;]    = createOption(false, mmp.lockSewers, { &quot;boolean&quot; }, &quot;Lock all sewers?&quot;)
  private_settings[&quot;lockspecials&quot;]  = createOption(false, mmp.lockSpecials, { &quot;boolean&quot; }, &quot;Lock all special exits?&quot;)
  private_settings[&quot;lockwormholes&quot;] = createOption(true, mmp.lockWormholes, { &quot;boolean&quot; }, &quot;Lock all wormholes?&quot;)
  private_settings[&quot;mandala&quot;]       = createOption(false, mmp.setMandala, { &quot;boolean&quot; }, &quot;Make use of your Mandala in Lusternia?&quot;)
  private_settings[&quot;medallion&quot;]     = createOption(false, mmp.setMedallion, { &quot;boolean&quot; }, &quot;Make use of your Medallion in Lusternia?&quot;)
  private_settings[&quot;mud&quot;]           = createOption(false, mmp.setMud, { &quot;boolean&quot; }, &quot;Make use of your Mud in Lusternia?&quot;)
  private_settings[&quot;pebble&quot;]        = createOption(false, mmp.lockPebble, { &quot;boolean&quot; }, &quot;Make use of your enchanted pebble in Achaea?&quot;)
  private_settings[&quot;prism&quot;]         = createOption(false, mmp.setPrism, {&quot;boolean&quot;}, &quot;Make use of your transplanar prism in Lusternia&quot;)
  private_settings[&quot;removewings&quot;]   = createOption(true, mmp.setWingsRemoval, { &quot;boolean&quot; }, &quot;Remove Wings after using them?&quot;)
  private_settings[&quot;runaway&quot;]       = createOption(false, mmp.changeBoolFunc, { &quot;boolean&quot; }, &quot;Use Jester Runaway?&quot;)
  private_settings[&quot;screwdriver&quot;]   = createOption(false, mmp.setScrewdriver, { &quot;boolean&quot; }, &quot;Make use of your Screwdriver in Lusternia?&quot;)
  private_settings[&quot;shackle&quot;]       = createOption(false, mmp.changeBoolFunc, { &quot;boolean&quot; }, &quot;Take off shackle?&quot;)
  private_settings[&quot;showcmds&quot;]      = createOption(true, mmp.changeBoolFunc, { &quot;boolean&quot; }, &quot;Show walking commands?&quot;)
  private_settings[&quot;slowwalk&quot;]      = createOption(false, mmp.setSlowWalk, { &quot;boolean&quot; }, &quot;Walk slowly instead of as quick as possible?&quot;)
  private_settings[&quot;snowglobe&quot;]     = createOption(false, mmp.setSnowglobe, { &quot;boolean&quot; }, &quot;Make use of your Snowglobe in Lusternia?&quot;)
  private_settings[&quot;sprint&quot;]        = createOption(false, mmp.changeBoolFunc, { &quot;boolean&quot; }, &quot;Use Sprint?&quot;)
  private_settings[&quot;tibia&quot;]         = createOption(false, mmp.setTibia, { &quot;boolean&quot; }, &quot;Make use of your Tibia in Lusternia?&quot;)
  private_settings[&quot;toolcurio&quot;]     = createOption(false, mmp.setToolcurio, { &quot;boolean&quot; }, &quot;Make use of your Tool curios in Lusternia?&quot;)
  private_settings[&quot;torus&quot;]         = createOption(false, mmp.setTorus, { &quot;boolean&quot; }, &quot;Make use of your Torus in Lusternia?&quot;)
  private_settings[&quot;toycurio&quot;]      = createOption(false, mmp.setToycurio, { &quot;boolean&quot; }, &quot;Make use of your Toy curios in Lusternia?&quot;)
  private_settings[&quot;updatemap&quot;]     = createOption(true, mmp.changeUpdateMap, { &quot;boolean&quot; }, &quot;Check for new maps from your MUD?&quot;)
  private_settings[&quot;utensilcurio&quot;]  = createOption(false, mmp.setUtensilcurio, { &quot;boolean&quot; }, &quot;Make use of your Utensil curios in Lusternia?&quot;)
  private_settings[&quot;vernalcurio&quot;]   = createOption(false, mmp.setVernalcurio, { &quot;boolean&quot; }, &quot;Make use of your Vernal curios in Lusternia?&quot;)
  private_settings[&quot;waterwalk&quot;]     = createOption(true, mmp.setWaterWalk, { &quot;boolean&quot; }, &quot;Have waterwalk (don't avoid water)?&quot;)
  private_settings[&quot;wheel&quot;]         = createOption(false, mmp.setWheel, { &quot;boolean&quot; }, &quot;Make use of your Wheel in Lusternia?&quot;)
  private_settings[&quot;winglanguage&quot;]  = createOption(&quot;&quot;, mmp.setWingsLanguage, { &quot;string&quot; }, &quot;Speak non-default language for wings:&quot;)

  mmp.settings = createOptionsTable(private_settings)
  mmp.settings.disp = mmp.echo

  mmp.game = false

  mmp.settings.dispOption = function(opt, val)
    cecho(&quot;&lt;green&gt;&quot; .. val.use .. &quot;&lt;white&gt; (&quot; ..opt..&quot;) &quot; .. string.rep(&quot; &quot;, 50 - val.use:len() - opt:len()) .. tostring(val.value) .. &quot;\n&quot;)
  end

  mmp.settings.dispDefaultWriteError = function()
    mmp.echo(&quot;Please use the mconfig alias to set options!&quot;)
  end

  local tmp = getRoomUserData(1, &quot;ferry rooms&quot;)
  if tmp ~= &quot;&quot; then
    for _, i in ipairs(yajl.to_value(tmp)) do
      mmp.ferry_rooms[i] = true
    end
  end

  raiseEvent(&quot;mmp areas changed&quot;)
  mmp.firstRun = false
  mmp.echon(&quot;Mudlet Mapper script for IREs (&quot;..tostring(mmp.version)..&quot;) loaded! (&quot;)
  echoLink(&quot;homepage&quot;,&quot;(openUrl or openURL)'http://wiki.mudlet.org/w/IRE_mapping_script'&quot;, &quot;Clicky clicky to read up on what's this about&quot;)
  echo(&quot;)\n&quot;)
end</script>
                <eventHandlerList/>
            </Script>
            <Script isActive="yes" isFolder="no">
                <name>speedwalking</name>
                <packageName></packageName>
                <script>function mmp.gotoRoom(where, dashtype)
  if not where or not tonumber(where) then
    mmp.echo(&quot;Where do you want to go to?&quot;) return end

  if tonumber(where) == mmp.currentroom then
    mmp.echo(&quot;We're already at &quot;..where..&quot;!&quot;)
   raiseEvent(&quot;mmapper arrived&quot;)
   return
  end

  local madeduanathar, madeduanatharan, madeduantahar, mademedallion, madefingerblade, madeblossom, madebelt, madecubix, madeprism, madescrewdriver, madewheel, mademud, madesnowglobe, madecookie, madehead, madeicicle, madetibia, madebonecurio, madeflowercurio, madetorus, madeutensilcurio, madefluttercurio, madetoolcurio, madefacecurio, madetoycurio, madefeathercurio, madefigurecurio, mademandala, madevernalcurio

  local function getcmd(word)
		if mmp.game == &quot;achaea&quot; then
    		return mmp.settings.removewings and
      			[[script:sendAll(&quot;wear wings&quot;, &quot;say *]]..(mmp.settings.winglanguage)..[[ ]]..word..[[&quot;, &quot;remove wings&quot;, false)]]
      		or
      			[[script:send(&quot;say *]]..(mmp.settings.winglanguage)..[[ ]]..word..[[&quot;, false)]]
		elseif mmp.game == &quot;lusternia&quot; then
			if word == &quot;snowglobe&quot; then
				return [[script:send(&quot;shake snowglobe&quot;,false)]]
			elseif word == &quot;bonecurio&quot; then
				return [[script:send(&quot;curio collection activate bone&quot;,false)]]
			elseif word == &quot;flowercurio&quot; then
				return [[script:send(&quot;curio collection activate flower&quot;,false)]]
			elseif word == &quot;utensilcurio&quot; then
				return [[script:send(&quot;curio collection activate utensil&quot;,false)]]
			elseif word == &quot;fluttercurio&quot; then
				return [[script:send(&quot;curio collection activate flutter&quot;,false)]]
			elseif word == &quot;toolcurio&quot; then
				return [[script:send(&quot;curio collection activate tool&quot;,false)]]
			elseif word == &quot;facecurio&quot; then
				return [[script:send(&quot;curio collection activate face&quot;,false)]]
			elseif word == &quot;toycurio&quot; then
				return [[script:send(&quot;curio collection activate toy&quot;,false)]]
			elseif word == &quot;feathercurio&quot; then
				return [[script:send(&quot;curio collection activate feather&quot;,false)]]
			elseif word == &quot;figurecurio&quot; then
				return [[script:send(&quot;curio collection activate figure&quot;,false)]]
			elseif word == &quot;vernalcurio&quot; then
				return [[script:send(&quot;curio collection activate vernal&quot;,false)]]
			else
				return [[script:send(&quot;touch ]]..word..[[&quot;, false)]]
			end
		end
  end

  -- allow mapper 'addons' to link their own exits in
  raiseEvent(&quot;mmp link externals&quot;)

  if mmp.game == &quot;achaea&quot; and (mmp.settings.duanathar or mmp.settings.duanatharan or mmp.settings.duantahar) and gmcp.Room and not table.contains(gmcp.Room.Info.details, &quot;indoors&quot;) and mmp.oncontinent(getRoomArea(mmp.currentroom), &quot;Main&quot;) then
    if mmp.settings.duanatharan then
      addSpecialExit(mmp.currentroom, 4882, getcmd(&quot;duanatharan&quot;))
      addSpecialExit(mmp.currentroom, 3885, getcmd(&quot;duanathar&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeduanatharan = true
    elseif mmp.settings.duantahar then
      addSpecialExit(mmp.currentroom, 42319, getcmd(&quot;duanathar&quot;))
      addSpecialExit(mmp.currentroom, 4882, getcmd(&quot;duanatharan&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeduantahar = true
    else
      addSpecialExit(mmp.currentroom, 3885, getcmd(&quot;duanathar&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeduanathar = true
    end
  elseif mmp.game == &quot;lusternia&quot; and (mmp.settings.medallion or mmp.settings.fingerblade or mmp.settings.blossom or mmp.settings.mandala or mmp.settings.belt or mmp.settings.cubix or mmp.settings.screwdriver or mmp.settings.wheel or mmp.settings.mud or mmp.settings.snowglobe or mmp.settings.cookie or mmp.settings.head or mmp.settings.icicle or mmp.settings.tibia or mmp.settings.bonecurio or mmp.settings.flowercurio or mmp.settings.torus or mmp.settings.vernalcurio) and gmcp.Room and (not table.contains(gmcp.Room.Info.details,&quot;indoors&quot;) or table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;)) then
	if mmp.settings.medallion and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 13367, getcmd(&quot;medallion&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      mademedallion = true
	end
	if mmp.settings.fingerblade and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 18777, getcmd(&quot;fingerblade&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefingerblade = true
	end
	if mmp.settings.blossom and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 18730, getcmd(&quot;blossom&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeblossom = true
	end
	if mmp.settings.mandala and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 19563, getcmd(&quot;mandala&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      mademandala = true
	end
	if mmp.settings.belt and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 19627, getcmd(&quot;belt&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madebelt = true
	end
	if mmp.settings.cubix and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 6184, getcmd(&quot;cubix&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madecubix = true
	end
	if mmp.settings.screwdriver and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Facility&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;screwdriver&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 10185, getcmd(&quot;screwdriver&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madescrewdriver = true
	end
	if mmp.settings.wheel and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Dramube Triangle&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;wheel&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 10509, getcmd(&quot;wheel&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madewheel = true
	end
	if mmp.settings.mud and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;Mucklemarsh&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;mud&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 9985, getcmd(&quot;mud&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      mademud = true
	end
	if mmp.settings.snowglobe and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Great Spirit Tree&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;snowglobe&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 10992, getcmd(&quot;snowglobe&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madesnowglobe = true
	end
	if mmp.settings.cookie and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;Crumkindivia&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;cookie&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 9888, getcmd(&quot;cookie&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madecookie = true
	end
	if mmp.settings.head and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Bubble of Bottledowns&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;doll&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 11811, getcmd(&quot;doll&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madedoll = true
	end
	if mmp.settings.icicle and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;Frosticia&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;icicle&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 10457, getcmd(&quot;icicle&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeicicle = true
	end
	if mmp.settings.tibia and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Cankermore Battlegrounds&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;tibia&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 11600, getcmd(&quot;tibia&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madetibia = true
	end
	if mmp.settings.bonecurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28613, getcmd(&quot;bonecurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madebonecurio = true
	end
	if mmp.settings.flowercurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28624, getcmd(&quot;flowercurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeflowercurio = true
	end
	if mmp.settings.torus and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28548, getcmd(&quot;torus&quot;))		-- room number will vary for each torus
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madetorus = true
	end
	if mmp.settings.utensilcurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28617, getcmd(&quot;utensilcurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeutensilcurio = true
	end
	if mmp.settings.fluttercurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28622, getcmd(&quot;fluttercurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefluttercurio = true
	end
	if mmp.settings.toolcurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28586, getcmd(&quot;toolcurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madetoolcurio = true
	end
	if mmp.settings.facecurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28433, getcmd(&quot;facecurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefacecurio = true
	end
	if mmp.settings.toycurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 21548, getcmd(&quot;toycurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madetoycurio = true
	end
	if mmp.settings.feathercurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28591, getcmd(&quot;feathercurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefeathercurio = true
	end
	if mmp.settings.figurecurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28312, getcmd(&quot;figurecurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefigurecurio = true
	end
   if mmp.settings.prism and mmp.useprism() then
		addSpecialExit(mmp.currentroom, 6182, getcmd(&quot;prism&quot;))
		mmp.clearpathcache()
		madeprism = true
	end
	if mmp.settings.vernalcurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 29908, getcmd(&quot;vernalcurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madevernalcurio = true
	end
  end

  -- if getPath worked, then the dirs and room #'s tables were populated for us
  if not mmp.getPath(mmp.currentroom, tonumber(where)) then
    mmp.echo(&quot;Don't know how to get there (&quot;..tostring(where)..&quot;) from here :(&quot;)
    mmp.speedWalkPath = {}
    mmp.speedWalkDir = {}
    speedWalkCounter = 0
    raiseEvent(&quot;mmapper failed path&quot;)
    if mmp.settings.shackle then expandAlias(&quot;wear shackle&quot;) end
    if madeduanatharan then mmp.clearspecials{4882, 3885}
    elseif madeduanathar then mmp.clearspecials{3885}
    elseif madeduantahar then mmp.clearspecials{42319, 4882}
    end
  	 if mademedallion then mmp.clearspecials{13367} end
  	 if madefingerblade then mmp.clearspecials{18777} end
     if madeblossom then mmp.clearspecials{18730} end
  	 if mademandala then mmp.clearspecials{19563} end
  	 if madebelt then mmp.clearspecials{19627} end
 	 if madecubix then mmp.clearspecials{6184} end
  	 if madescrewdriver then mmp.clearspecials{6831, 10185} end
 	 if madewheel then mmp.clearspecials{6831, 10509} end
 	 if mademud then mmp.clearspecials{6831, 9985} end
 	 if madesnowglobe then mmp.clearspecials{6831, 10992} end
     if madecookie then mmp.clearspecials{6831, 9888} end
 	 if madehead then mmp.clearspecials{6831, 11811} end
 	 if madeicicle then mmp.clearspecials{6831, 10457} end
 	 if madetibia then mmp.clearspecials{6831, 11600} end
 	 if madebonecurio then mmp.clearspecials{28613} end
 	 if madeflowercurio then mmp.clearspecials{28624} end
 	 if madetorus then mmp.clearspecials{28548} end
 	 if madeutensilcurio then mmp.clearspecials{28617} end
 	 if madefluttercurio then mmp.clearspecials{28622} end
 	 if madetoolcurio then mmp.clearspecials{28586} end
 	 if madefacecurio then mmp.clearspecials{28433} end
 	 if madetoycurio then mmp.clearspecials{21548} end
 	 if madefeathercurio then mmp.clearspecials{28591} end
 	 if madefigurecurio then mmp.clearspecials{28312} end
     if madeprism then mmp.clearspecials{6182} end
 	 if madevernalcurio then mmp.clearspecials{29908} end

    -- allow mapper 'addons' to unlink their special exits
    raiseEvent(&quot;mmp clear externals&quot;)
    return
  end

  doSpeedWalk(dashtype)
    if madeduanatharan then mmp.clearspecials{4882, 3885}
    elseif madeduanathar then mmp.clearspecials{3885}
    elseif madeduantahar then mmp.clearspecials{42319, 4882}
    end
  if mademedallion then mmp.clearspecials{13367} end
  if madefingerblade then mmp.clearspecials{18777} end
  if madeblossom then mmp.clearspecials{18730} end
  if mademandala then mmp.clearspecials{19563} end
  if madebelt then mmp.clearspecials{19627} end
  if madecubix then mmp.clearspecials{6184} end
  if madescrewdriver then mmp.clearspecials{6831, 10185} end
  if madewheel then mmp.clearspecials{6831, 10509} end
  if mademud then mmp.clearspecials{6831, 9985} end
  if madesnowglobe then mmp.clearspecials{6831, 10992} end
  if madecookie then mmp.clearspecials{6831, 9888} end
  if madehead then mmp.clearspecials{6831, 11811} end
  if madeicicle then mmp.clearspecials{6831, 10457} end
  if madetibia then mmp.clearspecials{6831, 11600} end
  if madebonecurio then mmp.clearspecials{28613} end
  if madeflowercurio then mmp.clearspecials{28624} end
  if madetorus then mmp.clearspecials{28548} end
  if madeutensilcurio then mmp.clearspecials{28617} end
  if madefluttercurio then mmp.clearspecials{28622} end
  if madetoolcurio then mmp.clearspecials{28586} end
  if madefacecurio then mmp.clearspecials{28433} end
  if madetoycurio then mmp.clearspecials{21548} end
  if madefeathercurio then mmp.clearspecials{28591} end
  if madefigurecurio then mmp.clearspecials{28312} end
  if madeprism then mmp.clearspecials{6182} end
  if madevernalcurio then mmp.clearspecials{29908} end

  -- allow mapper 'addons' to unlink their special exits
  raiseEvent(&quot;mmp clear externals&quot;)
end

function mmp.gotoArea (where, number, dashtype, exact)
  if not where or type(where) ~= &quot;string&quot; then
    mmp.echo(&quot;Where do you want to go to?&quot;) return end

  local where = where:lower()

  number = tonumber(number)
  local tmp = getRoomUserData(1, &quot;gotoMapping&quot;)
  if not tmp or tmp == '' then tmp = &quot;[]&quot; end

  local temp, maptable = yajl.to_value(tmp), {}
  for k,v in pairs(temp) do maptable[k:lower()] = v end

  local goto = maptable[where]
  if goto then
  	mmp.gotoRoom(goto, dashtype)
  	return
  end

  local possibleRooms, shortestPath, shortestBorder = {}, {}, 0

  mmp.computeShortestWatch = mmp.computeShortestWatch or createStopWatch()
  startStopWatch(mmp.computeShortestWatch)

  local areaid, msg, multiples = mmp.findAreaID(where, exact)
  if areaid then
     possibleRooms = mmp.getAreaBorders(areaid)

  elseif not areaid and #multiples &gt; 0 then
    if number and number&lt;=#multiples then
        mmp.gotoArea(multiples[number], nil, dashtype, true)
        return
    end
    mmp.echo(&quot;Which area would you like to go to?&quot;)
    fg(&quot;DimGrey&quot;)
    for key, areaname in ipairs(multiples) do
      echo&quot;  &quot;; echoLink(key .. &quot;) &quot;, 'mmp.gotoArea(&quot;'..areaname..'&quot;, nil, '..(dashtype and '&quot;'..dashtype..'&quot;' or &quot;nil&quot;)..', true)', &quot;Click to go to &quot;..areaname, true)
        setUnderline(true) echoLink(areaname, 'mmp.gotoArea(&quot;'..areaname..'&quot;, nil, '..(dashtype and '&quot;'..dashtype..'&quot;' or &quot;nil&quot;)..', true)', &quot;Click to go to &quot;..areaname, true) setUnderline(false) echo&quot;\n&quot;
    end
    resetFormat()
    return
  else
    mmp.echo(string.format(&quot;Don't know of any area named '%s'.&quot;, where))
    return
  end

  local getStopWatchTime, tonumber, getPath = getStopWatchTime, tonumber, mmp.getPath

--mmp.echo(string.format(&quot;Have %s area edge nodes, %ss taken so far...&quot;, table.size(possibleRooms), getStopWatchTime(mmp.computeShortestWatch)))

  -- allocate only 500ms to finding the shortest path, or more if we failed to find anything
  local checkedsofar, outoftime = 0
  for id, _ in pairs(possibleRooms) do
    if mmp.getPath(mmp.currentroom, tonumber(id)) then
      if shortestBorder==0 or #shortestPath &gt; #speedWalkPath then
        shortestPath = speedWalkPath
        shortestBorder = tonumber(id)
      end
    end
    checkedsofar = checkedsofar + 1

    if (getStopWatchTime(mmp.computeShortestWatch) &gt;= .5) then outoftime = true break end
   -- mmp.echo(string.format(&quot;pathed from %s to %s, running time so far: %s&quot;, mmp.currentroom, id, getStopWatchTime(mmp.computeShortestWatch)))
  end

  --mmp.echo(string.format(&quot;total time took: %s&quot;, getStopWatchTime(mmp.computeShortestWatch)))
  stopStopWatch(mmp.computeShortestWatch)

  if shortestBorder == 0 then
    if outoftime then
      mmp.echo(string.format(
        &quot;I checked %d of the %d possible exits \&quot;%s\&quot; has, but none of the ways there worked and it was taking too long :( try doing this again?&quot;,
        checkedsofar, table.size(possibleRooms), where
      ))
    else
      mmp.echo(&quot;Checked &quot;..table.size(possibleRooms)..&quot; exits in that area, and none of them worked :( I Don't know how to get you there.&quot;)
    end
    mmp.speedWalkPath = {}
    mmp.speedWalkDir = {}
    speedWalkCounter = 0
    raiseEvent(&quot;mmapper failed path&quot;)
    return
  end

  mmp.gotoRoom(shortestBorder, dashtype)
end

--- DOES NOT ACCOUNT FOR CHANGING THE MAP YET (within a profile load), because we don't know when it happens
local getpathcache = {}
--setmetatable(getpathcache, {__mode = &quot;kv&quot;}) -- weak keys/values = it'll periodically get cleaned up by gc

function mmp.getPath(from, to)
  assert(tonumber(from) and tonumber(to), &quot;mmp.getPath: both from and to have to be room IDs&quot;)

  local key = string.format(&quot;%s_%s&quot;, from, to)
  local resulttbl = getpathcache[key]

  -- not in cache?
  if not resulttbl then
    mmp.computeGetPath = mmp.computeGetPath or createStopWatch()
    startStopWatch(mmp.computeGetPath)
    local boolean = getPath(from, to)
    if mmp.debug then mmp.echo(&quot;a new getPath() from &quot;..from..&quot; to &quot;..to..&quot; took &quot;..stopStopWatch(mmp.computeGetPath)..&quot;s.&quot;) end
    -- save it into the cache &amp; send away
    getpathcache[key] = {boolean, speedWalkDir, speedWalkPath}
    return boolean
  end

  -- or if it is, retrieve &amp; send away
  speedWalkDir = resulttbl[2]
  speedWalkPath = resulttbl[3]
  return resulttbl[1]
end

function mmp.clearpathcache()
  if mmp.debug then mmp.echo(&quot;path cache cleared&quot;) end
  getpathcache = {}
end
function mmp.showpathcache() return getpathcache end

function mmp.setmovetimer(time)
  if mmp.movetimer then killTimer(mmp.movetimer) end
  if mmp.settings.slowwalk then return end

  mmp.movetimer = tempTimer(getNetworkLatency()+(time or 0.5), function ()
    mmp.movetimer = false
    mmp.move()
  end)
end

-- moves to the next room we need to.
function mmp.move()
  if mmp.paused or not mmp.autowalking or mmp.movetimer or not mmp.canmove() then return end
  -- sometimes it's 0 - default to 1
  if speedWalkCounter == 0 then speedWalkCounter = 1 end

  local cmd
  if mmp.settings[&quot;caravan&quot;] then cmd = &quot;lead caravan &quot;..mmp.speedWalkDir[speedWalkCounter]
  else
    cmd = mmp.speedWalkDir[speedWalkCounter]
  end

  cmd = cmd or ''

  -- timeout before loadstring, so it can set its own if it would like to.
  mmp.setmovetimer()

  if string.starts(cmd, &quot;script:&quot;) then
    cmd = string.gsub( cmd, &quot;script:&quot;, &quot;&quot; ) loadstring(cmd)()
    if mmp.settings.showcmds then cecho(string.format(&quot;&lt;red&gt;(&lt;maroon&gt;%d - &lt;dark_slate_grey&gt;%s&lt;red&gt;)&quot;, #mmp.speedWalkDir - speedWalkCounter + 1, &quot;&lt;script&gt;&quot;)) end
  else
    send(cmd, false)
    if mmp.settings.showcmds then cecho(string.format(&quot;&lt;red&gt;(&lt;maroon&gt;%d - &lt;dark_slate_grey&gt;%s&lt;red&gt;)&quot;, #mmp.speedWalkDir - speedWalkCounter + 1, cmd)) end
  end
end

function mmp.swim()
  -- not going anywhere? don't do anything
  if not mmp.speedWalkDir[speedWalkCounter] then return end

  send(&quot;swim &quot; .. mmp.speedWalkDir[speedWalkCounter]:gsub(&quot;sprint &quot;, &quot;&quot;):gsub(&quot;dash &quot;, &quot;&quot;):gsub(&quot;gallop &quot;, &quot;&quot;):gsub(&quot;runaway &quot;, &quot;&quot;), false)
  if mmp.settings.showcmds then cecho(string.format(&quot;&lt;red&gt;(&lt;maroon&gt;%d - &lt;dark_slate_grey&gt;swim %s&lt;red&gt;)&quot;, #mmp.speedWalkDir - speedWalkCounter + 1, mmp.speedWalkDir[speedWalkCounter]:gsub(&quot;sprint &quot;, &quot;&quot;):gsub(&quot;dash &quot;, &quot;&quot;):gsub(&quot;gallop &quot;, &quot;&quot;):gsub(&quot;runaway &quot;, &quot;&quot;))) end

  mmp.setmovetimer(2.5)
end

function mmp.enterGrate()
  -- not going anywhere? don't do anything
  if not mmp.speedWalkDir[speedWalkCounter] then return end

  send(&quot;enter grate &quot; .. mmp.speedWalkDir[speedWalkCounter], false)
  if mmp.settings.showcmds then cecho(string.format(&quot;&lt;red&gt;(&lt;maroon&gt;%d - &lt;dark_slate_grey&gt;enter grate %s&lt;red&gt;)&quot;, #mmp.speedWalkDir - speedWalkCounter + 1, mmp.speedWalkDir[speedWalkCounter])) end

  mmp.setmovetimer(2.5)
end

function mmp.openDoor()
  -- not going anywhere? don't do anything
  if not mmp.speedWalkDir[speedWalkCounter] then return end

  send(&quot;open door &quot; .. mmp.speedWalkDir[speedWalkCounter]:gsub(&quot;sprint &quot;, &quot;&quot;):gsub(&quot;dash &quot;, &quot;&quot;):gsub(&quot;gallop &quot;, &quot;&quot;):gsub(&quot;runaway &quot;, &quot;&quot;), false)
  if mmp.settings.showcmds then cecho(string.format(&quot;&lt;red&gt;(&lt;maroon&gt;%d - &lt;dark_slate_grey&gt;open door %s&lt;red&gt;)&quot;, #mmp.speedWalkDir - speedWalkCounter + 1, mmp.speedWalkDir[speedWalkCounter]:gsub(&quot;sprint &quot;, &quot;&quot;):gsub(&quot;dash &quot;, &quot;&quot;):gsub(&quot;gallop &quot;, &quot;&quot;):gsub(&quot;runaway &quot;, &quot;&quot;))) end

  mmp.setmovetimer(getNetworkLatency())
end

function mmp.unlockDoor()
  -- not going anywhere? don't do anything
  if not mmp.speedWalkDir[speedWalkCounter] then return end

  send(&quot;unlock door &quot; .. mmp.speedWalkDir[speedWalkCounter]:gsub(&quot;sprint &quot;, &quot;&quot;):gsub(&quot;dash &quot;, &quot;&quot;):gsub(&quot;gallop &quot;, &quot;&quot;):gsub(&quot;runaway &quot;, &quot;&quot;), false)
  if mmp.settings.showcmds then cecho(string.format(&quot;&lt;red&gt;(&lt;maroon&gt;%d - &lt;dark_slate_grey&gt;unlock door %s&lt;red&gt;)&quot;, #mmp.speedWalkDir - speedWalkCounter, mmp.speedWalkDir[speedWalkCounter]:gsub(&quot;sprint &quot;, &quot;&quot;):gsub(&quot;dash &quot;, &quot;&quot;):gsub(&quot;gallop &quot;, &quot;&quot;):gsub(&quot;runaway &quot;, &quot;&quot;))) end

  mmp.setmovetimer(getNetworkLatency())
end

function mmp.customwalkdelay(delay)
  mmp.setmovetimer(getNetworkLatency()+delay)
end

function mmp.stop()
  mmp.speedWalkPath = {}
  mmp.speedWalkDir = {}
  speedWalkCounter = 0
  stopStopWatch(speedWalkWatch)
  --if mmp.movetimer then killTimer( mmp.movetimer ) end
  mmp.autowalking = false

  -- clear all the temps we've got
  for trigger, ID in pairs(mmp.specials) do
    killTrigger(ID)
  end
  mmp.specials = {}

  mmp.echo(&quot;Stopped walking.&quot;)
  raiseEvent(&quot;mmapper stopped&quot;)
  if mmp.settings.shackle then expandAlias(&quot;wear shackle&quot;) end
end

-- Aetolia and Lusternia support showing balances in GMCP. This is easy to support, so we do!
-- if we can't move, setup a polling timer to prompt walking when we can again.
-- popular systems that expose balance &amp; equilibrium values can be added here as well, perhaps though a similarly-named function.
function mmp.canmove(fromtimer)
  if mapper_can_move and mapper_can_move() then
	if fromtimer then
      mmp.move()
    else return true end
  elseif mapper_can_move then
    tempTimer(0.2, [[mmp.canmove(true)]])
    return false
  end

  if not gmcp.Char then return true end

  if (gmcp.Char and
    -- Achaea
    (not gmcp.Char.Vitals.bal or gmcp.Char.Vitals.bal == &quot;1&quot;) and
    (not gmcp.Char.Vitals.eq or gmcp.Char.Vitals.eq == &quot;1&quot;) and
    -- Lusternia
    (not gmcp.Char.Vitals.balance or gmcp.Char.Vitals.balance == &quot;1&quot;) and
    (not gmcp.Char.Vitals.equilibrium or gmcp.Char.Vitals.equilibrium == &quot;1&quot;) and
    (not gmcp.Char.Vitals.right_arm or gmcp.Char.Vitals.right_arm == &quot;1&quot;) and
    (not gmcp.Char.Vitals.left_arm or gmcp.Char.Vitals.left_arm == &quot;1&quot;) and
    (not gmcp.Char.Vitals.right_leg or gmcp.Char.Vitals.right_leg == &quot;1&quot;) and
    (not gmcp.Char.Vitals.left_leg or gmcp.Char.Vitals.left_leg == &quot;1&quot;) and
    (not gmcp.Char.Vitals.psisuper or gmcp.Char.Vitals.psisuper ~= &quot;0&quot;) and
    (not gmcp.Char.Vitals.psisub or gmcp.Char.Vitals.psisub ~= &quot;0&quot;) and
    (not gmcp.Char.Vitals.psiid or gmcp.Char.Vitals.psiid ~= &quot;0&quot;) and
    (not gmcp.Char.Balance or gmcp.Char.Balance.List.balance == &quot;1&quot;) and
    (not gmcp.Char.Balance or gmcp.Char.Balance.List.equilibrium == &quot;1&quot;) and
    (not gmcp.Char.Balance or gmcp.Char.Balance.List.rarm == &quot;1&quot;) and
    (not gmcp.Char.Balance or gmcp.Char.Balance.List.larm == &quot;1&quot;) and
    (not gmcp.Char.Balance or gmcp.Char.Balance.List.legs == &quot;1&quot;) and
    (not gmcp.Char.Vitals.prone or (gmcp.Char.Vitals.prone == &quot;0&quot; or gmcp.Char.Vitals.prone == 0))
  ) then
	if fromtimer then
      mmp.move()
    else return true end
  else
    tempTimer(0.2, [[mmp.canmove(true)]])
    return false
  end
end

local oldnum
function speedwalking( event, num )
  local num = tonumber(num) or tonumber(gmcp.Room.Info.num)
  if num ~= mmp.currentroom then mmp.previousroom = mmp.currentroom end
  mmp.currentroom = num
  mmp.currentroomname = getRoomName(num)

  -- track if we're inside or outside, if possible
  if gmcp.Room then
    if mmp.inside and not table.contains(gmcp.Room.Info.details, &quot;indoors&quot;) then
      mmp.inside = false
      raiseEvent(&quot;mmapper went outside&quot;)
    elseif not mmp.inside and table.contains(gmcp.Room.Info.details, &quot;indoors&quot;) then
      mmp.inside = true
      raiseEvent(&quot;mmapper went inside&quot;)
    end
    if #table.n_union(mmp.getareacontinents(getRoomArea(mmp.previousroom)), mmp.getareacontinents(getRoomArea(num))) ~= #mmp.getareacontinents(getRoomArea(num)) then
      raiseEvent(&quot;mmapper changed continent&quot;)
    end
    -- the event could cancel speedwalking - in this case quit
    if mmp.ignore_speedwalking then
      mmp.ignore_speedwalking = nil
      return
    end
  end
  if oldnum == num then return else oldnum = num end

  if not mmp.autowalking then return end

  if mmp.movetimer then killTimer(mmp.movetimer); mmp.movetimer = false end

  if num == mmp.speedWalkPath[#mmp.speedWalkPath] then
    local walktime = stopStopWatch(speedWalkWatch)
    mmp.echo(string.format(&quot;We've arrived! Took us %.1fs.\n&quot;, walktime))
    raiseEvent(&quot;mmapper arrived&quot;)
    if mmp.settings.shackle then expandAlias(&quot;wear shackle&quot;) end
    mmp.speedWalkPath = {}
    mmp.speedWalkDir = {}
    speedWalkCounter = 0
    mmp.autowalking = false
  elseif mmp.speedWalkPath[speedWalkCounter] == num then
    speedWalkCounter = speedWalkCounter + 1
    mmp.move()
  elseif #mmp.speedWalkPath&gt; 0 and not mmp.ferry_rooms[num] and not (gmcp.Room.Info.details and table.contains(gmcp.Room.Info.details, &quot;ferry&quot;)) then -- ended up somewhere we didn't want to be, and this isn't a ferry room?
    speedWalkMoved = false
    -- re-calculate path then
    mmp.echo(&quot;Ended up off the path, recalculating a new path...&quot;)
    local destination = mmp.speedWalkPath[#mmp.speedWalkPath]
    if not mmp.getPath(num, destination) then
      mmp.echo(string.format(&quot;Don't know how to get to %d (%s) anymore :( Move into a room we know of to continue&quot;,
        destination, getRoomName(destination)))
    else
      mmp.gotoRoom (destination)
    end
  end
end

function doSpeedWalk(dashtype)
  mmp.speedWalkDir = mmp.deepcopy(speedWalkDir)
  mmp.speedWalkPath = mmp.deepcopy(speedWalkPath)
  speedWalkDir, speedWalkPath = {}, {}

  resetStopWatch(speedWalkWatch)
  startStopWatch(speedWalkWatch)
  if mmp.settings[&quot;gallop&quot;] or mmp.settings[&quot;dash&quot;] or mmp.settings.sprint or mmp.settings.runaway or dashtype then
    mmp.fixPath(mmp.currentroom, mmp.speedWalkPath[#mmp.speedWalkPath],
      (mmp.settings[&quot;gallop&quot;] and &quot;gallop&quot;) or (mmp.settings[&quot;dash&quot;] and &quot;dash&quot;) or (mmp.settings.sprint and &quot;sprint&quot;) or (mmp.settings.runaway and &quot;runaway&quot;) or dashtype)
  end

  mmp.fixSpecialExits(mmp.speedWalkDir)

  if #mmp.speedWalkPath == 0 then
    mmp.autowalking = false
    mmp.echo(&quot;Couldn't find a path to the destination :(&quot;)
    raiseEvent(&quot;mmapper failed path&quot;)
    if mmp.settings.shackle then expandAlias(&quot;wear shackle&quot;) end
    return
  end


  -- this is a fix: convert nums to actual numbers
  for i = 1, #mmp.speedWalkPath do
    mmp.speedWalkPath[i] = tonumber(mmp.speedWalkPath[i])
  end

  mmp.autowalking = true
  raiseEvent(&quot;s&quot;)

  if mmp.settings.shackle then expandAlias(&quot;remove shackle&quot;) end
  if not mmp.paused then
    mmp.echon(&quot;Starting speedwalk from &quot;..(atcp.RoomNum or gmcp.Room.Info.num)..&quot; to &quot;) echoLink(mmp.speedWalkPath[#mmp.speedWalkPath], 'mmp.gotoRoom &quot;' .. mmp.speedWalkPath[#mmp.speedWalkPath].. '&quot;', 'Go to ' .. mmp.speedWalkPath[#mmp.speedWalkPath]) echo(&quot;: &quot;)
    speedWalkCounter = 1
    if mmp.canmove() then mmp.move() else echo(&quot;(when we get balance back / aren't hindered)&quot;) end
  else
    mmp.echo(&quot;Will go to &quot;..mmp.speedWalkPath[#mmp.speedWalkPath]..&quot; as soon as the mapper is unpaused.&quot;)
  end
end

function mmp.failpath()
  if mmp.movetimer then
    local walktime = stopStopWatch(speedWalkWatch)
    mmp.echo(string.format(&quot;Can't continue further! Took us %.1fs to get here.\n&quot;, walktime))
  end

  mmp.autowalking = false

  if mmp.settings.shackle then expandAlias(&quot;wear shackle&quot;) end
  mmp.speedWalkPath = {}
  mmp.speedWalkDir = {}
  speedWalkCounter = 0
  if mmp.movetimer then killTimer( mmp.movetimer ); mmp.movetimer = nil end
  raiseEvent(&quot;mmapper failed path&quot;)
end

function mmp.changeBoolFunc(name, option)
  local en
  if option then en = &quot;will now use&quot; else en = &quot;will no longer use&quot; end
  mmp.echo(&quot;&lt;green&gt;Okay, the mapper &quot; .. en .. &quot; &lt;white&gt;&quot; .. name .. &quot;&lt;green&gt;!&quot;)
end

function mmp.fixPath(rFrom,rTo,dashtype)
  local currentPath, currentIds = {}, {}
  local dRef = {[&quot;n&quot;] = &quot;north&quot;, [&quot;e&quot;] = &quot;east&quot;, [&quot;s&quot;] = &quot;south&quot;, [&quot;w&quot;] = &quot;west&quot;}
  if not getPath(rFrom,rTo) then return false end

  -- Logic: Look for a direction repeated at least two times.
  -- count the number of times it repeats, then look that many rooms ahead.
  -- if that room also contains the direction we're headed, just travel that many directions.
  -- otherwise, dash.

  local repCount = 1
  local index = 1
  local dashExaust = false
  while mmp.speedWalkDir[index] do
    dashExaust = false
    repCount = 1
    while mmp.speedWalkDir[index+repCount] == mmp.speedWalkDir[index] do
      repCount = repCount + 1
      if repCount == 11 then
        dashExaust = true
        break
      end
    end
    if repCount &gt; 1 then
      -- Found direction repitition. Calculate dash path.
      local exits = getRoomExits(mmp.speedWalkPath[index+(repCount-1)])
      local pname = &quot;&quot;
      for word in mmp.speedWalkDir[index]:gmatch(&quot;%w&quot;) do pname = pname .. (dRef[word] or word) end
      if not exits[pname] or dashExaust then
        -- Final room in this direction does not continue, dash!
        table.insert(currentPath,string.format(&quot;%s %s&quot;,dashtype,mmp.speedWalkDir[index]))
        currentIds[#currentIds+1] = mmp.speedWalkPath[index+repCount-1]
      else
        -- Final room in this direction continues onwards, don't dash unless on achaea
        if mmp.game == &quot;achaea&quot; then
          table.insert(currentPath,string.format(&quot;%s %s %s&quot;,dashtype,mmp.speedWalkDir[index],repCount))
          currentIds[#currentIds+1] = mmp.speedWalkPath[index+repCount-1]
        else
          for i = 1,repCount do
            table.insert(currentPath,mmp.speedWalkDir[index])
            currentIds[#currentIds+1] = mmp.speedWalkPath[index+i-1]
          end
        end
      end
      index = index + repCount
    else
      -- No repetition, just add the direction.
      table.insert(currentPath,mmp.speedWalkDir[index])
      currentIds[#currentIds+1] = mmp.speedWalkPath[index]
      index = index + 1
    end
  end

  mmp.speedWalkDir = currentPath
  mmp.speedWalkPath = currentIds
  return true
end

-- a certain version of the mapper gave us special exits prepended with 0 or 1 in the command
-- depending on if it was locked. Need to remove these before we can use them
function mmp.fixSpecialExits(directions)
  for i = 1, #directions do
    if directions[i]:match(&quot;^%d&quot;) then directions[i] = directions[i]:sub(2) end
  end
end

-- cleanup function to remove the temp special exit we made - only way to remove specials in Mudlet atm is by clearing them all
function mmp.clearspecials(ignorerooms)
  local t = getSpecialExits(mmp.currentroom)
  clearSpecialExits(mmp.currentroom)

  for connectingroom, exits in pairs(t) do
    if not table.contains(ignorerooms,connectingroom) then -- don't re-add this one back as it's our temp
      for command, locked in pairs(exits) do
        --debug echo: mmp.echo(&quot;need to re-link this room to &quot;..connectingroom..&quot; with &quot;..command..&quot; that is &quot;..(locked == &quot;1&quot; and &quot;locked&quot; or &quot;unlocked&quot;)..&quot;.&quot;)
        addSpecialExit(mmp.currentroom, connectingroom, command)
        if locked == &quot;1&quot; then lockSpecialExit(mmp.currentroom, connectingroom, command, true) end
      end
    end
  end
end</script>
                <eventHandlerList>
                    <string>RoomNum</string>
                    <string>gmcp.Room.Info</string>
                </eventHandlerList>
            </Script>
            <Script isActive="yes" isFolder="no">
                <name>Utilities</name>
                <packageName></packageName>
                <script>-- functions internal to the mapper

function mmp.highlight_unfinished_rooms()
	if not mmp.areatable then return end
	for a,b in pairs (mmp.areatable) do
		local roomList = getAreaRooms(b) or {}
		for c,d in pairs (roomList) do
			if (getRoomName(d) == &quot;&quot;) then
				local fgr,fgg,fgb = unpack(color_table.red)
				local bgr,bgg,bgb = unpack(color_table.blue)
				highlightRoom(d, fgr,fgg,fgb,bgr,bgg,bgb, 1, 100, 100)
			end
		end
	end
end

function mmp.usebix()
	if mmp.game ~= &quot;lusternia&quot; then return end

	if (table.contains(gmcp.Room.Info.details, &quot;the Prime Material Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Ethereal Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Water Elemental Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Air Elemental Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Fire Elemental Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Earth Elemental Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;Celestia, Plane of Light&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Tainted Plane of Nil&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Cosmic Plane of Continuum&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Cosmic Plane of Vortex&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Astral Plane&quot;)) and
        gmcp.Room.Info.area ~= &quot;the City of Climanti&quot; and
		table.contains(gmcp.Room.Info.details, &quot;outdoors&quot;) then
		return true
	end
	return false
end

function mmp.useprism()
	if mmp.game ~= &quot;lusternia&quot; then return end
	if (table.contains(gmcp.Room.Info.details, &quot;the Prime Material Plane&quot;) or
	table.contains(gmcp.Room.Info.details, &quot;the Ethereal Plane&quot;) or
	table.contains(gmcp.Room.Info.details, &quot;the Water Elemental Plane&quot;) or
	table.contains(gmcp.Room.Info.details, &quot;the Air Elemental Plane&quot;) or
	table.contains(gmcp.Room.Info.details, &quot;the Fire Elemental Plane&quot;) or
	table.contains(gmcp.Room.Info.details, &quot;the Earth Elemental Plane&quot;)) and
    gmcp.Room.Info.area ~= &quot;the City of Climanti&quot; and
	table.contains(gmcp.Room.Info.details, &quot;outdoors&quot;) then
		return true
	end
	return false
end
function mmp.usebubblix()
	if mmp.game ~= &quot;lusternia&quot; then return end

	if ((table.contains(gmcp.Room.Info.details, &quot;the Prime Material Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Ethereal Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Water Elemental Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Air Elemental Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Fire Elemental Plane&quot;) or
		table.contains(gmcp.Room.Info.details, &quot;the Earth Elemental Plane&quot;)) and
        gmcp.Room.Info.area ~= &quot;the City of Climanti&quot; and
		table.contains(gmcp.Room.Info.details, &quot;outdoors&quot;)) or
		table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
		return true
	end
	return false
end</script>
                <eventHandlerList/>
                <Script isActive="yes" isFolder="no">
                    <name>Locating &amp; echoing functions</name>
                    <packageName></packageName>
                    <script>-- for a given room name, we'll echo all the vnums
function mmp.echonums(roomname)
  local t = mmp.searchRoomExact(roomname)

  if not next(t) then
    echo &quot;?&quot; return nil end

  -- transform the kv table into a table of tables for cleaner code.
    -- + perhaps Mudlet in future will give this us anyway, sorted by relevancy
  local dt = {}
  for roomid,room in pairs(t) do
    dt[#dt+1] = {name = room, id = roomid}
  end

  -- we can have nothing if we asked for exact match
  if not dt[1] then echo &quot;?---&quot; return end

  -- display first three ids. Can't really nicely table.concat them.
  cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..dt[1].id, 'mmp.gotoRoom('..dt[1].id..')', string.format(&quot;Go to %s (%s)&quot;, dt[1].id, dt[1].name), true)
  if not dt[2] then return end

  echo&quot;, &quot;
  cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..dt[2].id, 'mmp.gotoRoom('..dt[2].id..')', string.format(&quot;Go to %s (%s)&quot;, dt[2].id, dt[2].name), true)
  if not dt[3] then return end

  echo&quot;, &quot;
  cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..dt[3].id, 'mmp.gotoRoom('..dt[3].id..')', string.format(&quot;Go to %s (%s)&quot;, dt[3].id, dt[3].name), true)
  if not dt[4] then return end

  echo&quot;, ...&quot;
end

function mmp.roomEcho(query)
  local result = mmp.searchRoom(query)

  if not tonumber(select(2, next(result))) then
    for roomid, roomname in pairs(result) do roomid = tonumber(roomid)
      cecho(&quot;&lt;DarkSlateGrey&gt; (&lt;blue&gt;&quot;)
      echoLink(roomid, 'mmp.gotoRoom('..roomid..')', string.format(&quot;Go to %s (%s)&quot;, roomid, tostring(roomname)))
      cecho(&quot;&lt;DarkSlateGrey&gt;)&quot;)
    end

  else
    for roomname, roomid in pairs(result) do roomid = tonumber(roomid)
      cecho(&quot;&lt;DarkSlateGrey&gt; (&lt;blue&gt;&quot;)
      echoLink(roomid, 'mmp.gotoRoom('..roomid..')', string.format(&quot;Go to %s (%s)&quot;, roomid, tostring(roomname)))
      cecho(&quot;&lt;DarkSlateGrey&gt;)&quot;)
    end
  end
end

function mmp.locateAndEcho(room, person)
    local t = mmp.searchRoomExact(room)

    echo &quot;  (&quot;
    mmp.echonums(room, true)
    echo &quot;)&quot;

	-- lowercase results
	for k,v in pairs(t) do if tonumber(k) then t[k] = v:lower() else t[k:lower()] = v end end

    if not (t[room:lower()] or table.contains(t, room:lower())) then return end

    echo&quot;\n&quot;
    if table.size(t) == 1 then
      local k,v = next(t)
      cecho(&quot;&lt;red&gt;From your knowledge, that room is in &lt;orange_red&gt;&quot;..mmp.cleanAreaName(mmp.areatabler[getRoomArea(type(k) == &quot;number&quot; and k or v)] or &quot;?&quot;)..&quot;&lt;red&gt;.&quot;)
    else
      local k,v = next(t)
    local areas = {}
      if type(k) == &quot;number&quot; then
        for k, _ in pairs(t) do
          areas[mmp.areatabler[getRoomArea(k)] or &quot;?&quot;] = true
        end
      else
        for _, k in pairs(t) do
          areas[mmp.areatabler[getRoomArea(k)] or &quot;?&quot;] = true
        end
      end

      local flattened_areas = {}
      for k, _ in pairs(areas) do
        if k ~= &quot;&quot; then flattened_areas[#flattened_areas+1] = mmp.cleanAreaName(k) end
      end

      cecho(&quot;&lt;red&gt;From your knowledge, that room might be in &lt;orange_red&gt;&quot;..table.concat(flattened_areas, &quot;, or &quot;)..&quot;&lt;red&gt;.&quot;)
    end

   if person then
      mmp.pdb[person] = room
      mmp.pdb_lastupdate[person] = true
      raiseEvent(&quot;mmapper updated pdb&quot;)
   end
end

function mmp.locateAndEchoSide(room, person)
    local t = mmp.searchRoomExact(room)

    echo &quot;  (&quot;
    mmp.echonums(room, true)
    echo &quot;)&quot;

	-- lowercase results
	for k,v in pairs(t) do if tonumber(k) then t[k] = v:lower() else t[k:lower()] = v end end

    if not (t[room:lower()] or table.contains(t, room:lower())) then return end

    --echo&quot;\n&quot;
    if table.size(t) == 1 then
      local k,v = next(t)
      cecho(&quot;&lt;red&gt;  (&quot;..mmp.cleanAreaName(mmp.areatabler[getRoomArea(type(k) == &quot;number&quot; and k or v)] or &quot;?&quot;)..&quot;)&quot;)
    else
      local k,v = next(t)
    local areas = {}
      if type(k) == &quot;number&quot; then
        for k, _ in pairs(t) do
          areas[mmp.areatabler[getRoomArea(k)] or &quot;?&quot;] = true
        end
      else
        for _, k in pairs(t) do
          areas[mmp.areatabler[getRoomArea(k)] or &quot;?&quot;] = true
        end
      end

      local flattened_areas = {}
      for k, _ in pairs(areas) do
        if k ~= &quot;&quot; then flattened_areas[#flattened_areas+1] = mmp.cleanAreaName(k) end
      end

      cecho(&quot;&lt;red&gt; (&quot;..table.concat(flattened_areas, &quot;, &quot;)..&quot;)&quot;)
    end

   if person then
      mmp.pdb[person] = room
      mmp.pdb_lastupdate[person] = true
      raiseEvent(&quot;mmapper updated pdb&quot;)
   end
end

function mmp.locateAndEchoInternal(room, person)
    local t = mmp.searchRoomExact(room)



	-- lowercase results
	for k,v in pairs(t) do if tonumber(k) then t[k] = v:lower() else t[k:lower()] = v end end

    if not (t[room:lower()] or table.contains(t, room:lower())) then return end

    --echo&quot;\n&quot;
    if table.size(t) == 1 then
      local k,v = next(t)
      cecho(&quot;&lt;red&gt; in &quot;..mmp.cleanAreaName(mmp.areatabler[getRoomArea(type(k) == &quot;number&quot; and k or v)] or &quot;?&quot;)..&quot;.&quot;)
    else
      local k,v = next(t)
    local areas = {}
      if type(k) == &quot;number&quot; then
        for k, _ in pairs(t) do
          areas[mmp.areatabler[getRoomArea(k)] or &quot;?&quot;] = true
        end
      else
        for _, k in pairs(t) do
          areas[mmp.areatabler[getRoomArea(k)] or &quot;?&quot;] = true
        end
      end

      local flattened_areas = {}
      for k, _ in pairs(areas) do
        if k ~= &quot;&quot; then flattened_areas[#flattened_areas+1] = mmp.cleanAreaName(k) end
      end

      cecho(&quot;&lt;red&gt; in &quot;..table.concat(flattened_areas, &quot;, &quot;)..&quot;.&quot;)
    end

	echo &quot;  (&quot;
    mmp.echonums(room, true)
    echo &quot;)&quot;

   if person then
      mmp.pdb[person] = room
      mmp.pdb_lastupdate[person] = true
      raiseEvent(&quot;mmapper updated pdb&quot;)
   end
end</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Aliases</name>
                    <packageName></packageName>
                    <script>function mmp.roomWhoFind(query)
  if query:ends('.') then query = query:sub(1,-2) end
  local result = mmp.searchRoomExact(query)

  if type(result) == &quot;string&quot; or not next(result) then
    cecho(&quot;&lt;CadetBlue&gt;  You have no recollection of any room with that name.&quot;) return end

  if not tonumber(select(2, next(result))) then -- old style
    for roomid, roomname in pairs(result) do roomid = tonumber(roomid)
      cecho(string.format(&quot;  &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt; (&lt;blue&gt;&quot;,
        tostring(roomname)))
      cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..roomid, 'mmp.gotoRoom('..roomid..')', string.format(&quot;Go to %s (%s)&quot;, roomid, tostring(roomname)), true)
      cecho(string.format(&quot;&lt;DarkSlateGrey&gt;) &lt;white&gt;%s&lt;DarkSlateGrey&gt;.\n&quot;, tostring(mmp.areatabler[getRoomArea(roomid)])))
    end

  else -- new style
    for roomname, roomid in pairs(result) do roomid = tonumber(roomid)
      cecho(string.format(&quot;  &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt; (&lt;blue&gt;&quot;,
        tostring(roomname)))
      cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..roomid, 'mmp.gotoRoom('..roomid..')', string.format(&quot;Go to %s (%s)&quot;, roomid, tostring(roomname)), true)
      cecho(string.format(&quot;&lt;DarkSlateGrey&gt;) &lt;white&gt;%s&lt;DarkSlateGrey&gt;.\n&quot;, tostring(mmp.areatabler[getRoomArea(roomid)])))
    end
  end
end

function mmp.roomFind(query)
  if query:ends('.') then query = query:sub(1,-2) end
  local result = mmp.searchRoom(query)

  if type(result) == &quot;string&quot; or not next(result) then
    cecho(&quot;&lt;grey&gt;You have no recollection of any room with that name.&quot;) return end

  cecho(&quot;&lt;DarkSlateGrey&gt;You know the following relevant rooms:\n&quot;)

  local function showmeropis(roomid)
    if mmp.game ~= &quot;achaea&quot; then return '' end

    return mmp.oncontinent(getRoomArea(roomid), &quot;Main&quot;) and '' or ' (Meropis)'
  end

  if not tonumber(select(2, next(result))) then -- old style
    for roomid, roomname in pairs(result) do roomid = tonumber(roomid)
      cecho(string.format(&quot;  &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt; (&lt;blue&gt;&quot;,
        tostring(roomname)))
      cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..roomid, 'mmp.gotoRoom('..roomid..')', string.format(&quot;Go to %s (%s)&quot;, roomid, tostring(roomname)), true)
      cecho(string.format(&quot;&lt;DarkSlateGrey&gt;) in &lt;LightSlateGray&gt;%s%s&lt;DarkSlateGrey&gt;.&quot;, mmp.cleanAreaName(tostring(mmp.areatabler[getRoomArea(roomid)])), showmeropis(roomid)))
      fg(&quot;DarkSlateGrey&quot;) echoLink(&quot; &gt; Show path\n&quot;, [[mmp.echoPath(mmp.currentroom, ]]..roomid..[[)]], &quot;Display directions from here to &quot;..roomname, true) resetFormat()
    end

  else -- new style
    for roomname, roomid in pairs(result) do roomid = tonumber(roomid)
      cecho(string.format(&quot;  &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt; (&lt;blue&gt;&quot;,
        tostring(roomname)))
      cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..roomid, 'mmp.gotoRoom('..roomid..')', string.format(&quot;Go to %s (%s)&quot;, roomid, tostring(roomname)), true)
      cecho(string.format(&quot;&lt;DarkSlateGrey&gt;) in &lt;LightSlateGray&gt;%s%s&lt;DarkSlateGrey&gt;.&quot;, mmp.cleanAreaName(tostring(mmp.areatabler[getRoomArea(roomid)])), showmeropis(roomid)))
      fg(&quot;DarkSlateGrey&quot;) echoLink(&quot; &gt; Show path\n&quot;, [[mmp.echoPath(mmp.currentroom, ]]..roomid..[[)]], &quot;Display directions from here to &quot;..roomname, true) resetFormat()
    end
  end

  cecho(string.format(&quot;  &lt;DarkSlateGrey&gt;%d rooms found.\n&quot;, table.size(result)))
end

function mmp.echoRoomList(areaname, exact)
  local areaid, msg, multiples = mmp.findAreaID(areaname, exact)
  if areaid then
    local roomlist, endresult = getAreaRooms(areaid) or {}, {}

    -- obtain a room list for each of the room IDs we got
    local getRoomName = getRoomName
    for _, id in pairs(roomlist) do
      endresult[id] = getRoomName(id)
    end

    -- sort room IDs so we can display them in order
    table.sort(roomlist)

    -- now display something half-decent looking
    cecho(string.format(
      &quot;&lt;DarkSlateGrey&gt;List of all rooms in &lt;grey&gt;%s&lt;DarkSlateGrey&gt; (areaid &lt;grey&gt;%s&lt;DarkSlateGrey&gt; - &lt;grey&gt;%d&lt;DarkSlateGrey&gt; rooms):\n&quot;, msg, areaid, table.size(endresult)))
    local echoLink, sformat, fg, echo = echoLink, string.format, fg, cecho
    -- use pairs, as we can have gaps between room IDs
    for _, roomid in pairs(roomlist) do
      local roomname = endresult[roomid]
      fg(&quot;blue&quot;) cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..sformat(&quot;%6s&quot;, roomid), 'mmp.gotoRoom('..roomid..')', string.format(&quot;Go to %s (%s)&quot;, roomid, tostring(roomname)), true)
       cecho(string.format(&quot;&lt;DarkSlateGrey&gt;: &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt;.\n&quot;, roomname))
    end

  elseif not id and #multiples &gt; 0 then
    mmp.echo(&quot;For which area would you want to list rooms for?&quot;)
    fg(&quot;DimGrey&quot;)
    for _, areaname in ipairs(multiples) do
      echo&quot;  &quot;; setUnderline(true) echoLink(areaname, 'mmp.echoRoomList(&quot;'..areaname..'&quot;, true)', &quot;Click to view the room list for &quot;..areaname, true) setUnderline(false) echo&quot;\n&quot;
    end
    resetFormat()

  else
    mmp.echo(string.format(&quot;Don't know of any area named '%s'.&quot;, areaname))
  end
end

function mmp.echoAreaList()
  local list = getAreaTable()
  local ids, rlist = {}, {}
  local totalroomcount = 0
  for area, id in pairs(list) do
    if id ~= 0 then ids[#ids+1] = id; rlist[id] = area end end
  table.sort(ids)


  -- count the amount of rooms in an area, taking care to count the room in the 0th
  -- index as well if there is one
  -- saves the total room count on the side as well
  local function countrooms(areaid)
    local allrooms = getAreaRooms(areaid) or {}
    local areac = (#allrooms or 0) + (allrooms[0] and 1 or 0)
    totalroomcount = totalroomcount + areac
    return areac
  end

  cecho(string.format(
      &quot;&lt;DarkSlateGrey&gt;List of all areas we know of (click to view room list):\n&quot;))
  local getAreaRooms, cecho, fg, echoLink, format, rep = getAreaRooms, cecho, fg, echoLink, string.format, string.rep
  for _, id in pairs(ids) do
    cecho(format(&quot;&lt;blue&gt;%s%d &quot;, rep(&quot; &quot;, (7-#tostring(id))), id))
    -- +1 because getAreaRooms starts counting at 0
    fg(&quot;DarkSlateGrey&quot;) echoLink(rlist[id]..(&quot; &quot;):rep(40-#rlist[id])..&quot;(&quot;..mmp.comma_value(countrooms(id))..&quot; rooms)&quot;, 'mmp.echoRoomList(&quot;'..rlist[id]..'&quot;, true)', &quot;View the room list for &quot;..rlist[id], true) echo(&quot;\n&quot;)
  end
  cecho(string.format(
      &quot;&lt;DarkSlateGrey&gt;Total amount of rooms in this map: %s\n&quot;, mmp.comma_value(totalroomcount)))
end

function mmp.clearLabels(areaid)
  local function clearlabels(areaid)
    local t = getMapLabels(areaid)
    if type(t) ~= &quot;table&quot; then return end

    for labelid, _ in pairs(t) do deleteMapLabel(areaid, labelid) end
  end

  if areaid == &quot;map&quot; then
    for areaid in pairs(mmp.areatabler) do
      clearlabels(areaid)
    end

    mmp.echo(&quot;Cleared labels in all of the map.&quot;)
    return
  end

  clearlabels(areaid)
  mmp.echo(string.format(&quot;Cleared all labels in '%s'.&quot;, mmp.areatabler[areaid]))
end

function mmp.deleteArea(name, exact)
  local id, fname, ma = mmp.findAreaID(name, exact)

  if id then
    mmp.doareadelete(id)
  elseif next(ma) then
    mmp.echo(&quot;Which one of these specifically would you like to delete?&quot;)

    fg(&quot;DimGrey&quot;)
    for _,name in ipairs(ma) do
    echo &quot;  &quot; setUnderline(true) echoLink(name, [[mmp.deleteArea(&quot;]]..name..[[&quot;, true)]], &quot;Delete &quot;..name, true) setUnderline(false) echo&quot;\n&quot;
    end
    resetFormat()
    else
      mmp.echo(&quot;Don't know of that area.&quot;)
  end

  raiseEvent(&quot;mmp areas changed&quot;)
end

-- the function actually doing area deletion
function mmp.doareadelete(areaid)
  mmp.deletingarea = {}

  local t = mmp.deletingarea

  local rooms = getAreaRooms(areaid)
  t.roomcount = table.size(rooms)
  t.roombatches = {}
  t.currentbatch = 1
  t.areaid = areaid
  t.areaname = getAreaTableSwap()[areaid]

  -- delete the area right away if there's nothing in it
  if t.roomcount == 0 then
    deleteArea(t.areaid)
    mmp.echo(&quot;All done! The area was already gone/empty.&quot;)
  end

  local rooms_per_batch = 100

  -- split up rooms into tables of tables, to be deleted in batches so
  -- that our print statements in between get a chance to be processed
  for batch = 1, t.roomcount, 100 do
    t.roombatches[#t.roombatches+1] = {}
    local onebatch = t.roombatches[#t.roombatches]
    for inbatch = 1, 100 do
      onebatch[#onebatch+1] = rooms[batch+inbatch]
    end
  end

  function mmp.deletenextbatch()
    local t = mmp.deletingarea
    if not t then return end

    local currentbatch = t.roombatches[t.currentbatchi]

    if currentbatch == nil then
      deleteArea(t.areaid)
      mmp.echo(&quot;All done! Deleted the '&quot;..t.areaname..&quot;' area.&quot;)
      mmp.deletingarea = nil
      centerview(mmp.currentroom)
      return
    end

    local deleteRoom = deleteRoom
    for i = 1, #currentbatch do
      deleteRoom(currentbatch[i])
    end

    mmp.echo(string.format(&quot;Deleted %d batch%s so far, %d left to go - %.2f%% done out of %d needed&quot;,
          t.currentbatchi, (t.currentbatchi == 1 and '' or 'es'), #t.roombatches - t.currentbatchi,
          (100/#t.roombatches)*t.currentbatchi, #t.roombatches))

    t.currentbatchi = t.currentbatchi + 1
    tempTimer(0.010, mmp.deletenextbatch)
  end

  t.currentbatchi = 1
  mmp.echo(&quot;Prepped room batches, starting deletion...&quot;)
  tempTimer(0.010, mmp.deletenextbatch)
end

function mmp.renameArea(name, exact)
  if not (mmp.currentroom or getRoomArea(mmp.currentroom)) then
    mmp.echo(&quot;Don't know what area are we in at the moment, to rename it.&quot;)
  else
  setAreaName(getRoomArea(mmp.currentroom), name)
  mmp.echo(string.format(&quot;Renamed %s to %s (%d).&quot;, mmp.areatabler[getRoomArea(mmp.currentroom)], name, getRoomArea(mmp.currentroom)))
  centerview(mmp.currentroom)
  end

  raiseEvent(&quot;mmp areas changed&quot;)
end

function mmp.roomArea(otherroom, name, exact)
    local id,fname,ma
    if tonumber(name) then id = tonumber(name); fname = mmp.areatabler[id]
    else id, fname, ma = mmp.findAreaID(name, exact) end

    if otherroom ~= &quot;&quot; and not mmp.roomexists(otherroom) then
      mmp.echo(&quot;Room id &quot;..otherroom..&quot; doesn't seem to exist.&quot;)
      return
    elseif otherroom == &quot;&quot; and not mmp.roomexists(mmp.currentroom) then
      mmp.echo(&quot;Don't know where we are at the moment.&quot;)
      return
    end

   otherroom = otherroom ~= &quot;&quot; and otherroom or mmp.currentroom

  if id then
    setRoomArea(otherroom, id)
    mmp.echo(string.format(&quot;Moved %s to %s (%d).&quot;, (getRoomName(otherroom) ~= &quot;&quot; and getRoomName(otherroom) or &quot;''&quot;), fname, id))
    centerview(otherroom)
  elseif next(ma) then
    mmp.echo(&quot;Into which area exactly would you like to move the room?&quot;)

    fg(&quot;DimGrey&quot;)
    for _,name in ipairs(ma) do
    echo &quot;  &quot; setUnderline(true) echoLink(name, [[mmp.roomArea('', &quot;]]..name..[[&quot;, true)]], &quot;Move the room to &quot;..name, true) setUnderline(false) echo&quot;\n&quot;
    end
    resetFormat()
    else
      mmp.echo(&quot;Don't know of that area.&quot;)
  end
end

function mmp.getAreaBorders(areaid)
	if mmp.debug then
		mmp.getAreaBordersTimer = mmp.getAreaBordersTimer or createStopWatch()
		startStopWatch(mmp.getAreaBordersTimer)
	end

    local roomlist, endresult = getAreaRooms(areaid), {}
    -- sometimes getAreaRooms can give us no result :(
    if not roomlist then mmp.echo(&quot;Sorry, seems we can't go there - getAreaRooms(&quot;..areaid..&quot;) didn't give us any results (Mudlet problem - redownloading the map might help fix it)&quot;) return end

	local getRoomExits, getRoomName, getSpecialExitsSwap, contains, pairs = getRoomExits, getRoomName, getSpecialExitsSwap, table.contains, pairs

    -- make a key-value list of room IDs
    local reverselist = {}
    for i = 0, #roomlist do reverselist[roomlist[i]] = true end

    -- obtain a room list for each of the room IDs we got
    --for _, id in pairs(roomlist) do
    for i = 0, #roomlist do
      local id = roomlist[i]
      local exits = getRoomExits(id)
      for _, to in pairs(exits) do
        if not reverselist[to] then
          endresult[id] = getRoomName(id)
        end
      end
      local specialexits = getSpecialExitsSwap(id)
      for _, to in pairs(specialexits) do
        if not reverselist[to] then
          endresult[id] = getRoomName(id)
        end
      end
    end

	if mmp.debug then
		mmp.echo(&quot;mmp.getAreaBordersTimer() on areaid &quot;..areaid..&quot; took &quot;..stopStopWatch(mmp.getAreaBordersTimer)..&quot;s to run. Returned &quot;..table.size(endresult)..&quot; results.&quot;)
	end

    return endresult
end


function mmp.viewArea (where, exact)
  if not where or not type(where)==&quot;string&quot; then
    mmp.echo(&quot;Which area would you like to view?&quot;) return end


  local areaid, msg, multiples = mmp.findAreaID(where, exact)
  if areaid then
    -- center on the first room ID, which typically is the start of an area
    local rooms = getAreaRooms(areaid) or {}
    if not rooms[1] then mmp.echo(&quot;The area has no rooms in it.&quot;) else
    centerview(rooms[1]) end

  elseif not areaid and #multiples &gt; 0 then
    mmp.echo(&quot;Which area would you like to view exactly?&quot;)
    fg(&quot;DimGrey&quot;)
    for _, areaname in ipairs(multiples) do
      echo&quot;  &quot;; setUnderline(true) echoLink(areaname, 'mmp.viewArea(&quot;'..areaname..'&quot;, true)', &quot;Click to view &quot;..areaname, true) setUnderline(false) echo&quot;\n&quot;
    end
    resetFormat()
    return
  else
    mmp.echo(string.format(&quot;Don't know of any area named '%s'.&quot;, where))
    return
  end
end

-- room label the room I'm in
-- room label 342 this is a label in room 342
-- room label green this is a green label where I'm at
-- room label green black this is a green to black label where I'm at
-- room label 34 green black this is a green to black label at room 34
-- how it works: split input string into tokens by space, then determine
-- what to do by checking first few tokens, and finally call the local
-- function with the proper arguments
function mmp.roomLabel(input)
  if not createMapLabel then
    mmp.echo(&quot;Your Mudlet doesn't support createMapLabel() yet - please update to 2.0-test3 or better.&quot;) return
  end

  local tk = input:split(&quot; &quot;)
  local room, fg, bg, message = mmp.currentroom, &quot;yellow&quot;, &quot;red&quot;, &quot;Some room label&quot;

  -- input always have to be something, so tk[1] at least always exists
  if tonumber(tk[1]) then
    room = tonumber(table.remove(tk, 1)) -- remove the number, so we're left with the colors or msg
  end

  -- next: is this a foreground color?
  if tk[1] and color_table[tk[1]] then
    fg = table.remove(tk, 1)
  end

  -- next: is this a backround color?
  if tk[1] and color_table[tk[1]] then
    bg = table.remove(tk, 1)
  end

  -- the rest would be our message
  if tk[1] then
    message = table.concat(tk, &quot; &quot;)
  end

  -- if we haven't provided a room ID and we don't know where we are yet, we can't make a label
  if not room then
    mmp.echo(&quot;We don't know where we are to make a label here.&quot;) return
  end

  local x,y = getRoomCoordinates(room)
  local f1,f2,f3 = unpack(color_table[fg])
  local b1,b2,b3 = unpack(color_table[bg])

  -- finally: do it :)

  local lid = createMapLabel(getRoomArea(room), message, x, y, f1,f2,f3, b1,b2,b3)
  mmp.echo(string.format(&quot;Created new label #%d '%s' in %s.&quot;, lid, message, getRoomAreaName(getRoomArea(room))))
end

function mmp.areaLabels (where, exact)
  if not getMapLabels then
    mmp.echo(&quot;Your Mudlet doesn't support getMapLabels() yet - please update to 2.0-test3 or better.&quot;) return
  end

  if (not where or not type(where)==&quot;string&quot;) and not mmp.currentroom then
    mmp.echo(&quot;For which area would you like to view labels?&quot;) return end

  if not where then
  exact = true
    where = getRoomAreaName(getRoomArea(mmp.currentroom))
  end

  local areaid, msg, multiples = mmp.findAreaID(where, exact)
  if areaid then
    local t = getMapLabels(areaid)
    if type(t) ~= &quot;table&quot; or not next(t) then
      mmp.echo(string.format(&quot;'%s' doesn't seem to have any labels.&quot;, getRoomAreaName(areaid)))
      return
    end

    mmp.echo(string.format(&quot;Area labels for '%s'&quot;, getRoomAreaName(areaid)))
    for labelid, labeltext in pairs(t) do
      fg(&quot;DimGrey&quot;)
      echo(string.format(&quot;  %d) %s (&quot;, labelid, labeltext))
      fg&quot;orange_red&quot; setUnderline(true) echoLink('delete', string.format('deleteMapLabel(%d, %d); mmp.echo(&quot;Deleted label #'..labelid..'&quot;)', areaid, labelid), &quot;Delete label #&quot;..labelid..&quot; from &quot;..getRoomAreaName(areaid))
      setUnderline(false) echo&quot;)\n&quot;
    end
    resetFormat()

  elseif not areaid and #multiples &gt; 0 then
    mmp.echo(&quot;Which area would you like to view exactly?&quot;)
    fg(&quot;DimGrey&quot;)
    for _, areaname in ipairs(multiples) do
      echo&quot;  &quot;; setUnderline(true) echoLink(areaname, 'mmp.areaLabels(&quot;'..areaname..'&quot;, true)', &quot;Click to view labels in &quot;..areaname, true) setUnderline(false) echo&quot;\n&quot;
    end
    resetFormat()
    return
  else
    mmp.echo(string.format(&quot;Don't know of any area named '%s'.&quot;, where))
    return
  end
end

function mmp.echoPath(from, to)
	assert(tonumber(from) and tonumber(to), &quot;mmp.getPath: both from and to have to be room IDs&quot;)
	if mmp.getPath(from, to) then
		mmp.echo(&quot;&lt;white&gt;Directions from &lt;yellow&gt;&quot; .. string.upper(searchRoom(from)) .. &quot; &lt;white&gt;to &lt;yellow&gt;&quot; .. string.upper(searchRoom(to)) .. &quot;&lt;white&gt;:&quot;)
		mmp.echo(table.concat(speedWalkDir, &quot;, &quot;))
		return mmp.speedWalkDir
	end
end

function mmp.listSpecialExits(filter)
  local c = 0

  mmp.echo(&quot;Listing special exits...&quot;)
  for area, areaname in pairs(mmp.areatabler) do
    local rooms = getAreaRooms(area) or {}
    for i = 0, #rooms do
      local exits = getSpecialExits(rooms[i] or 0)

       if exits and next(exits) then
         for exit, cmd in pairs(exits) do
           if type(cmd) == &quot;table&quot; then cmd = next(cmd) end
           if cmd:match(&quot;^%d&quot;) then cmd = cmd:sub(2) end

           if not filter or cmd:lower():find(filter, 1, true) then
            if getRoomArea(exit) ~= area then
              cecho(string.format(&quot;&lt;dark_slate_grey&gt;%s &lt;LightSlateGray&gt;(%d, in %s)&lt;dark_slate_grey&gt; &lt;MediumSlateBlue&gt;-&gt; &lt;coral&gt;%s -&lt;MediumSlateBlue&gt;&gt;&lt;dark_slate_grey&gt; %s &lt;LightSlateGray&gt;(%d, in %s)\n&quot;, getRoomName(rooms[i]), rooms[i], areaname,
                cmd, getRoomName(exit), exit, mmp.areatabler[getRoomArea(exit)] or '?'))
            else
              cecho(string.format(&quot;&lt;dark_slate_grey&gt;%s &lt;LightSlateGray&gt;(%d)&lt;dark_slate_grey&gt; &lt;MediumSlateBlue&gt;-&gt; &lt;coral&gt;%s &lt;MediumSlateBlue&gt;-&gt;&lt;dark_slate_grey&gt; %s &lt;LightSlateGray&gt;(%d)&lt;dark_slate_grey&gt; in %s\n&quot;, getRoomName(rooms[i]), rooms[i], cmd, getRoomName(exit), exit, areaname))
            end
            c = c + 1
           end
         end
       end
    end
  end

  mmp.echo(string.format(&quot;%d exits listed%s.&quot;, c, (not filter and '' or &quot;, with for the filter '&quot;..filter..&quot;'&quot;)))
end

function mmp.delSpecialExits(filter)
  local c = 0
  for area, areaname in pairs(mmp.areatabler) do
    local rooms = getAreaRooms(area) or {}
    for i = 0, #rooms do
      local exits = getSpecialExits(rooms[i] or 0)

       if exits and next(exits) then
         for exit, cmd in pairs(exits) do
           if type(cmd) == &quot;table&quot; then cmd = next(cmd) end
           if cmd:match(&quot;^%d&quot;) then cmd = cmd:sub(2) end

           if not filter or cmd:lower():find(filter, 1, true) then
            local rid, action
            local originalExits = {}
            local e = getSpecialExits(rooms[i])
            for t,n in pairs(e) do
              rid = tonumber(t)
              for a,l in pairs(n) do
                action = tostring(a)
              end
              if not action:find(filter,1,true) then
                originalExits[rid] = action
              end
            end
            clearSpecialExits(rooms[i])
            for rid, act in pairs(originalExits) do
              addSpecialExit(rooms[i], tonumber(rid), tostring(act))
            end
            c = c + 1
           end
         end
       end
    end
  end

  mmp.echo(string.format(&quot;%d exits deleted%s.&quot;, c, (not filter and '' or &quot;, with for the filter '&quot;..filter..&quot;'&quot;)))
end</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Directions-translating functions</name>
                    <packageName></packageName>
                    <script>-- translates n to north and so forth
local temp = {
    n = &quot;north&quot;,
    e = &quot;east&quot;,
    s = &quot;south&quot;,
    w = &quot;west&quot;,
    ne = &quot;northeast&quot;,
    se = &quot;southeast&quot;,
    sw = &quot;southwest&quot;,
    nw = &quot;northwest&quot;,
    u = &quot;up&quot;,
    d = &quot;down&quot;,
    i = &quot;in&quot;,
    o = &quot;out&quot;,
    [&quot;in&quot;] = &quot;in&quot;
}
local anytolongmap = {}
for s, l in pairs(temp) do anytolongmap[l] = l; anytolongmap[s] = l end
function mmp.anytolong(exit)

  return anytolongmap[exit]
end

function mmp.anytoshort(exit)
  local t = {
    n = &quot;north&quot;,
    e = &quot;east&quot;,
    s = &quot;south&quot;,
    w = &quot;west&quot;,
    ne = &quot;northeast&quot;,
    se = &quot;southeast&quot;,
    sw = &quot;southwest&quot;,
    nw = &quot;northwest&quot;,
    u = &quot;up&quot;,
    d = &quot;down&quot;,
    [&quot;in&quot;] = &quot;in&quot;,
    out = &quot;out&quot;
  }
  local rt = {}
  for s,l in pairs(t) do
    rt[l] = s; rt[s] = s
  end

  return rt[exit]
end


function mmp.ranytolong(exit)
  local t = {
    n = &quot;south&quot;,
    north = &quot;south&quot;,
    e = &quot;west&quot;,
    east = &quot;west&quot;,
    s = &quot;north&quot;,
    south = &quot;north&quot;,
    w = &quot;east&quot;,
    west = &quot;east&quot;,
    ne = &quot;southwest&quot;,
    northeast = &quot;southwest&quot;,
    se = &quot;northwest&quot;,
    southeast = &quot;northwest&quot;,
    sw = &quot;northeast&quot;,
    southwest = &quot;northeast&quot;,
    nw = &quot;southeast&quot;,
    northwest = &quot;southeast&quot;,
    u = &quot;down&quot;,
    up = &quot;down&quot;,
    d = &quot;up&quot;,
    down = &quot;up&quot;,
    i = &quot;out&quot;,
    [&quot;in&quot;] = &quot;out&quot;,
    o = &quot;in&quot;,
    out = &quot;in&quot;
  }

  return t[exit]
end

-- returns nil or the room number relative to this one
function mmp.relativeroom(from, dir)
  if not mmp.roomexists(from) then return end

  local exits = getRoomExits(tonumber(from))
  return exits[mmp.anytolong(dir)]
end
</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>mconfig settings functions</name>
                    <packageName></packageName>
                    <script>function mmp.doLock(what, lock, filter)
  if what then mmp.echo(string.format(&quot;%s all %s...&quot;, (lock and &quot;Locking&quot; or &quot;Unlocking&quot;), what)) end
  local c = 0

  local getAreaRooms, getSpecialExits, lockSpecialExit, next = getAreaRooms, getSpecialExits, lockSpecialExit, next
  for _, area in pairs(getAreaTable()) do
    local rooms = getAreaRooms(area) or {}
    for i = 0, #rooms do
      local exits = getSpecialExits(rooms[i] or 0)

       if exits and next(exits) then
         for exit, cmd in pairs(exits) do
           if type(cmd) == &quot;table&quot; then cmd = next(cmd) end

           if (not filter and not (cmd:lower():find(&quot;pathfind&quot;, 1, true) or cmd:lower():find(&quot;worm warp&quot;, 1, true) or cmd:lower():find(&quot;enter grate&quot;, 1, true))) or (filter and cmd:lower():find(filter, 1, true)) then
             lockSpecialExit(rooms[i], exit, cmd, lock)
             c = c + 1
           end
         end
       end
    end
  end

  if what then mmp.echo(string.format(&quot;%s %s known %s.&quot;, (lock and &quot;Locked&quot; or &quot;Unlocked&quot;), c, what)) end
  return c
end

function mmp.lockPathways()
  local lock = mmp.settings.lockpathways and true or false
  mmp.doLock(&quot;pathways&quot;, lock, &quot;pathfind&quot;)
end

function mmp.lockSewers()
  local lock = mmp.settings.locksewers and true or false
  return mmp.doLock(&quot;sewer grates&quot;, lock, &quot;enter grate&quot;)
end

function mmp.lockWormholes()
  local lock = mmp.settings.lockwormholes and true or false
  return mmp.doLock(&quot;wormholes&quot;, lock, &quot;worm warp&quot;)
end
tempTimer(0, function() if mmp.firstRun then mmp.lockWormholes() end end)

function mmp.lockPebble()
  local disabled = (not mmp.settings.pebble) and true or false
  mmp.doLock(nil, disabled, &quot;touch 116998&quot;)
  mmp.doLock(nil, disabled, &quot;touch 277930&quot;)

  mmp.echo(string.format(&quot;Use of pebble %s.&quot;, disabled and &quot;disabled&quot; or &quot;enabled&quot;))
end

function mmp.lockSpecials()
  local lock = mmp.settings.lockspecials and true or false
  mmp.doLock(&quot;special exits&quot;, lock)
end

function mmp.setDuanathar()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.duanathar then mmp.echo(&quot;Okay, will see about using Eagle wings when you goto somewhere while outside!&quot;)
  else mmp.echo(&quot;Won't use Eagle wings anymore.&quot;) end
end

function mmp.setDuanatharan()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.duanatharan then mmp.echo(&quot;Okay, will see about using Atavian wings (both duanathar and duanatharan) when you goto somewhere while outside!&quot;)
  else mmp.echo(&quot;Won't use Atavian wings anymore.&quot;) end
end

function mmp.setDuantahar()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.duantahar then mmp.echo(&quot;Okay, will see about using Chenubian wings (duanathar, duanatharan, and duantahar) when you goto somewhere while outside!&quot;)
  else mmp.echo(&quot;Won't use Chenubian wings anymore.&quot;) end
end

function mmp.chageMapSource()
  local use = mmp.settings.crowdmap and true or false
  if use and not mmp.game or mmp.game ~= &quot;achaea&quot; then
    mmp.echo(&quot;Sorry - the crowdsourced map is only available for use in Achaea. If you'd like to help start one for your game, please post at http://forums.mudlet.org/viewtopic.php?f=13&amp;t=1696. If you are playing Achaea, then it is likely that you just downloaded the script - and it doens't know what you are playing. Reconnect and it'll know.&quot;)
    mmp.settings.crowdmap = false
  elseif use and not loadMap then
   mmp.echo(&quot;Sorry - your Mudlet is too old and can't load maps. Please update: http://forums.mudlet.org/viewtopic.php?f=5&amp;t=1874&quot;)
   mmp.settings.crowdmap = false
  elseif use then
    mmp.echo(&quot;Will use the crowdsourced map for updates instead!&quot;)
    mmp.checkforupdate()
  else
    mmp.echo(&quot;Will use the default Achaea map for updates.&quot;)
  end
end

function mmp.setWingsLanguage()
  mmp.echo(&quot;Alright, will say Duanathar and Duanathar in &quot;..mmp.settings.winglanguage:title()..&quot;.&quot;)
end

function mmp.setWingsRemoval()
  mmp.echo(&quot;Okay - &quot;..(mmp.settings.removewings and &quot;will&quot; or &quot;won't&quot;)..&quot; remove wings after using them.&quot;)
end

function mmp.setSlowWalk()
  if mmp.settings.slowwalk then
    mmp.echo(&quot;Will walk 'slowly' - that is, only try to move in a direction once per room, and move again once we've arrived. This will make us better walkers when it's very laggy, as we won't spam directions unnecessarily and miss certain turns - but it does mean that if we fail to move for some reason, we won't retry again either at all.&quot;)
  else
    mmp.echo(&quot;Will walk as quick as we can!&quot;)
  end
end

function mmp.disableWaterWalk()
  local c = 0
  local getRoomEnv, setRoomWeight = getRoomEnv, setRoomWeight
  for roomid, roomname in pairs(getRooms()) do
    if mmp.waterenvs[getRoomEnv(roomid)] then
      setRoomWeight(roomid, 3)
      c = c + 1
    end
  end

  return c
end

function mmp.enableWaterWalk()
  local c = 0
  local getRoomEnv, setRoomWeight = getRoomEnv, setRoomWeight
  for roomid, roomname in pairs(getRooms()) do
    if mmp.waterenvs[getRoomEnv(roomid)] then
      setRoomWeight(roomid, 1)
      c = c + 1
    end
  end

  return c
end

function mmp.setWaterWalk()
  if mmp.settings.waterwalk then
    mmp.echo(&quot;Enabled waterwalk for &quot;..mmp.enableWaterWalk()..&quot; rooms - so we'll be treating land and water rooms the same now in terms of traverse speed over them.&quot;)
  else
    mmp.echo(&quot;Disabled waterwalk for &quot;..mmp.disableWaterWalk()..&quot; rooms - so we'll be preferring land rooms over water ones wherever it's quicker.&quot;)
  end
end

function mmp.setMedallion()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.medallion then mmp.echo(&quot;Okay, will see about using Medallion whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Medallion anymore.&quot;) end
end

function mmp.setFingerblade()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.fingerblade then mmp.echo(&quot;Okay, will see about using Fingerblade whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Fingerblade anymore.&quot;) end
end

function mmp.setBlossom()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.blossom then mmp.echo(&quot;Okay, will see about using the Flame whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use the Flame anymore.&quot;) end
end

function mmp.setMandala()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.mandala then mmp.echo(&quot;Okay, will see about using Mandala whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Mandala anymore.&quot;) end
end

function mmp.setBelt()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.belt then mmp.echo(&quot;Okay, will see about using Belt whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Belt anymore.&quot;) end
end

function mmp.setCubix()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.cubix then mmp.echo(&quot;Okay, will see about using Cubix whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Cubix anymore.&quot;) end
end

function mmp.setPrism()
	mmp.clearpathcache()
	if mmp.settings.prism then mmp.echo(&quot;Okay, will see about using Prism whenever it's quicker&quot;)
	else mmp.echo(&quot;Won't use Prism anymore.&quot;) end
end

function mmp.setScrewdriver()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.screwdriver then mmp.echo(&quot;Okay, will see about using Screwdriver whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Screwdriver anymore.&quot;) end
end

function mmp.setWheel()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.wheel then mmp.echo(&quot;Okay, will see about using Wheel whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Wheel anymore.&quot;) end
end

function mmp.setMud()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.mud then mmp.echo(&quot;Okay, will see about using Mud whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Mud anymore.&quot;) end
end
function mmp.setSnowglobe()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.snowglobe then mmp.echo(&quot;Okay, will see about using Snowglobe whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Snowglobe anymore.&quot;) end
end

function mmp.setCookie()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.cookie then mmp.echo(&quot;Okay, will see about using Cookie whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Cookie anymore.&quot;) end
end

function mmp.setHead()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.head then mmp.echo(&quot;Okay, will see about using Doll's Head whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Doll's Head anymore.&quot;) end
end

function mmp.setIcicle()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.icicle then mmp.echo(&quot;Okay, will see about using Icicle whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Icicle anymore.&quot;) end
end

function mmp.setTibia()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.tibia then mmp.echo(&quot;Okay, will see about using Tibia whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Tibia anymore.&quot;) end
end

function mmp.setBonecurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.bonecurio then mmp.echo(&quot;Okay, will see about using Bone Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Bone Curio collection anymore.&quot;) end
end

function mmp.setFlowercurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.flowercurio then mmp.echo(&quot;Okay, will see about using Flower Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Flower Curio collection anymore.&quot;) end
end

function mmp.setTorus()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.torus then mmp.echo(&quot;Okay, will see about using your Torus whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use your Torus anymore.&quot;) end
end

function mmp.setUtensilcurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.utensilcurio then mmp.echo(&quot;Okay, will see about using Utensil Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Utensil Curio collection anymore.&quot;) end
end

function mmp.setFluttercurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.fluttercurio then mmp.echo(&quot;Okay, will see about using Flutter Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Flutter Curio collection anymore.&quot;) end
end

function mmp.setToolcurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.toolcurio then mmp.echo(&quot;Okay, will see about using Tool Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Tool Curio collection anymore.&quot;) end
end

function mmp.setFacecurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.facecurio then mmp.echo(&quot;Okay, will see about using Face Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Face Curio collection anymore.&quot;) end
end

function mmp.setToycurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.toycurio then mmp.echo(&quot;Okay, will see about using Toy Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Toy Curio collection anymore.&quot;) end
end

function mmp.setFeathercurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.feathercurio then mmp.echo(&quot;Okay, will see about using Feather Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Feather Curio collection anymore.&quot;) end
end

function mmp.setFigurecurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.figurecurio then mmp.echo(&quot;Okay, will see about using Figure Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Figure Curio collection anymore.&quot;) end
end

function mmp.setVernalcurio()
  mmp.clearpathcache() -- clear the cache so it'll use wings or will stop using wings

  if mmp.settings.vernalcurio then mmp.echo(&quot;Okay, will see about using Vernal Curio collection whenever it's quicker&quot;)
  else mmp.echo(&quot;Won't use Vernal Curio collection anymore.&quot;) end
end</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>API</name>
                    <packageName></packageName>
                    <script>-------------------------------------------------
-- This script lists some of the API functions available from the IRE mudlet-mapper
-- not all functions that are available are included here, however.

function mmp.echo(what)
  what = what or &quot;&quot;
  moveCursorEnd(&quot;main&quot;) if getCurrentLine() ~= &quot;&quot; then echo&quot;\n&quot; end
  decho(&quot;&lt;112,229,0&gt;(&lt;73,149,0&gt;mapper&lt;112,229,0&gt;): &lt;255,255,255&gt;&quot;)
  cecho(tostring(what))
  echo(&quot;\n&quot;)
end

function mmp.echon(what)
  moveCursorEnd(&quot;main&quot;) if getCurrentLine() ~= &quot;&quot; then echo&quot;\n&quot; end
  decho(&quot;&lt;112,229,0&gt;(&lt;73,149,0&gt;mapper&lt;112,229,0&gt;): &lt;255,255,255&gt;&quot;)
  cecho(tostring(what))
end

function mmp.deleteLineP()
  deleteLine()
  tempLineTrigger(1,1,[[
    if isPrompt() then deleteLine() end
  ]])
end

function mmp.pause(what)
  assert(what == nil or what == &quot;on&quot; or what == &quot;off&quot;, &quot;mmp.pause wants 'on', 'off' or nothing as an argument&quot;)

  if what == &quot;on&quot; or (what == nil and not mmp.paused) then
    mmp.paused = true
  elseif  what == &quot;off&quot; or (what == nil and mmp.paused) then
    mmp.paused = false
  end

  mmp.echo(&quot;Speedwalking &quot; .. (mmp.paused and &quot;paused&quot; or &quot;unpaused&quot;) .. &quot;.&quot;)
  if not mmp.paused then mmp.move() end
end

function mmp.mapLook(roomid, delay)
  centerview(roomid)
  if mmp.maplooktimer then killTimer(mmp.maplooktimer) end
  mmp.maplooktimer = tempTimer(tonumber(delay) or 4, [[centerview(mmp.currentroom); mmp.maplooktimer = nil]])
end

function mmp.getnums(roomname, exact)
  if tonumber(roomname) then return {roomname} end

  local t = (not exact and mmp.searchRoom or mmp.searchRoomExact)(roomname)

  if not t or not next(t) then
    return nil end

  local result = {}

  if not tonumber(select(2, next(t))) then
    for roomid,_ in pairs(t) do
      if roomid ~= 0 then result[#result+1] = tonumber(roomid) end
    end
  else
    for _,roomid in pairs(t) do
      if roomid ~= 0 then result[#result+1] = tonumber(roomid) end
    end
  end

  return result
end

-- searchRoom with a cache!
local cache = {}
setmetatable(cache, {__mode = &quot;kv&quot;}) -- weak keys/values = it'll periodically get cleaned up by gc

function mmp.searchRoom(what)
  local result = cache[what]
  if not result then
    result = searchRoom(what)
    local realResult = {}
    for key, value in pairs(type(result) == &quot;table&quot; and result or {}) do
        -- both ways, because searchRoom can return either id-room name or the reverse
        if type(key) == &quot;string&quot; then
          realResult[key:ends(&quot; (road)&quot;) and key:sub(1, -8) or key] = value
        else
          realResult[key] = value:ends(&quot; (road)&quot;) and value:sub(1, -8) or value
        end
    end
    cache[what] = realResult
    result = realResult
  end
  return result
end

local function endswith(s, suffix)
    return s:sub(#s - #suffix + 1) == suffix
end

function mmp.searchRoomExact(what)
  if type(what) ~= 'string' then return end

  local roomTable = mmp.searchRoom(what)
  local realResult = {}
  what = what:lower()
  for key, value in pairs (roomTable) do
    if type(key) == &quot;string&quot; and (key:lower() == what or (endswith(key, '.') and key:sub(1, -2) == what)) then
        realResult[key:ends(&quot; (road)&quot;) and key:sub(1, -8) or key] = value
    elseif type(value) == &quot;string&quot; and (value:lower() == what or (endswith(value, '.') and value:sub(1, -2) == what)) then
        realResult[key] = value:ends(&quot; (road)&quot;) and value:sub(1, -8) or value
    end
  end
  if (table.is_empty(realResult)) then
    return roomTable
  else
    return realResult
  end
end

function mmp.findAreaID(areaname, exact)
  local areaname = areaname:lower()
  local list = getAreaTable()

  -- iterate over the list of areas, matching them with substring match.
  -- if we get match a single area, then return it's ID, otherwise return
  -- 'false' and a message that there are than one are matches
  local returnid, fullareaname, multipleareas = nil, nil, {}
  for area, id in pairs(list) do
    if (not exact and area:lower():find(areaname, 1, true)) or (exact and areaname == area:lower()) then
      returnid = id; fullareaname = area; multipleareas[#multipleareas+1] = area
    end
  end

  if #multipleareas == 1 then
    return returnid, fullareaname
  else
    return nil, nil, multipleareas
  end
end

function mmp.roomexists(num)
  if not num then return false end
  if roomExists then return roomExists(num) end

  local s,m = pcall(getRoomArea, tonumber(num))
  return (s and true or false)
end

function mmp.getcontinents()
  local tmp = getRoomUserData(1, &quot;areaContinents&quot;)
  if tmp == &quot;&quot; then return {} end

  return yajl.to_value(tmp)
end

-- patches welcome to finish this function.
function mmp.removecontinent(area, continent)
  local continents = mmp.getcontinents()

  if not next(continents) then return nil, &quot;no continents are known&quot; end
  if not continents[continent] then return nil, &quot;no such continent is recorded&quot; end

  local index = mmp.indexof_valueonly(continents[continent], area)
  if not index then return nil, &quot;this area is not on that continent&quot; end
  table.remove(continents[continent], index)
  local tmp = yajl.to_string(continents)
  setRoomUserData(1, &quot;areaContinents&quot;, tmp)
  return true
end

function mmp.addcontinent(areaid, continent)
  local continents = mmp.getcontinents()

  if not next(continents) then return nil, &quot;no continents are known&quot; end
  if not continents[continent] then continents[continent] = {} end

  local index = mmp.indexof_valueonly(continents[continent], areaid)
  if index then return nil, &quot;this area is already on that continent&quot; end
  continents[continent][#continents[continent] + 1] = areaid
  local tmp = yajl.to_string(continents)
  setRoomUserData(1, &quot;areaContinents&quot;, tmp)
  return true
end

function mmp.indexof_valueonly(data, value)
  for i = 1, #data do
    if data[i] == value then return i end
  end

  return false
end

-- checks if given area ID is on the given continent. Returns true only if certainly knows
function mmp.oncontinent(areaid, continent)
  local continents = mmp.getcontinents()
  if not continents[continent] then return nil, &quot;no such continent is recorded&quot; end

  return mmp.indexof_valueonly(continents[continent], areaid)
end

function mmp.getareacontinents(areaid)
  local areaContinents = {}
  for continentName, areas in pairs(mmp.getcontinents()) do
    if mmp.indexof_valueonly(areas, areaid) then
      areaContinents[#areaContinents + 1] = continentName
    end
  end
  return areaContinents
end

-- accepts areaname or ID
function mmp.cleanAreaName(area)
  local areaname = type(area) == &quot;number&quot; and mmp.areatabler[area] or area
  if not areaname then return area end

  -- strip , the
  areaname = areaname:gsub(&quot;, the$&quot;, '')

  -- strip , the Type of
  areaname = areaname:gsub(&quot;, the %w+ of$&quot;, '')

  -- strip , the Type of (important)
  areaname = areaname:gsub(&quot;, the %w+ of %((.+)%)$&quot;, &quot; (%1)&quot;)

  -- strip , the (important)
  areaname = areaname:gsub(&quot;, the %((.+)%)$&quot;, &quot; (%1)&quot;)

  return areaname
end

-- if this room is in a unique area, report it. Otherwise gives nil
function mmp.getexactarea(roomname)
  local rooms = mmp.searchRoomExact(roomname)

  if not rooms or not next(rooms) then return nil end

  local areaid
  for roomid, roomname in pairs(rooms) do

    local caid = getRoomArea(roomid)
    if areaid and areaid ~= caid then return nil end
    areaid = caid
  end

  if areaid then return mmp.areatabler[areaid] end
end

-- returns the area name of a room or ?
function mmp.getAreaName(roomid)
   return mmp.areatabler[getRoomArea(roomid)] or '?'
end

-- removes extra prefixes and suffixes that are not part of the actual room name
function mmp.cleanroomname(roomname)
  local starts, ends = string.starts, string.ends

  if starts(roomname, &quot;Flying above &quot;) then
    roomname = string.sub(roomname, -(#roomname-13))
  end
  if starts(roomname, &quot;In the trees above &quot;) then
    roomname = string.sub(roomname, -(#roomname-19))
  end
  if starts(roomname, &quot;The ruins of &quot;) then
    roomname = string.sub(roomname, -(#roomname-13))
  end
  if ends(roomname, &quot;.&quot;) then
    roomname = string.sub(roomname, 1, (#roomname-1))
  end
  if ends(roomname, &quot; (road)&quot;) then
    roomname = string.sub(roomname, 1, (#roomname-7))
  end
  if ends(roomname, &quot; (indoors)&quot;) then
    roomname = string.sub(roomname, 1, (#roomname-10))
  end
  if ends(roomname, &quot; (indoor road)&quot;) then
    roomname = string.sub(roomname, 1, (#roomname-14))
  end

  return roomname
end</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>mmp.roomLook</name>
                    <packageName></packageName>
                    <script>function mmp.roomLook(input)
  -- we can do a report with a number
  local function handle_number(num)
    -- compile all available data
    if not mmp.roomexists(num) then mmp.echo(num..&quot; doesn't seem to exist.&quot;) return end
    local s, areanum = pcall(getRoomArea,num)
    if not s then mmp.echo(areanum); return; end

    local exits = getRoomExits(num)
    local name = getRoomName(num)
    local islocked = roomLocked(num)
    local weight = (getRoomWeight(num) and getRoomWeight(num) or &quot;?&quot;) -- getRoomWeight is buggy in one of the versions, is actually linked to setRoomWeight and thus returns nil
    local exitweights = (getExitWeights and getExitWeights(num) or {})
    local coords = {getRoomCoordinates(num)}
    local specexits = getSpecialExits(num)
    local env = getRoomEnv(num)
    local envname = (mmp.envidsr and mmp.envidsr[env]) or &quot;?&quot;

    -- generate a report
    mmp.echo(string.format(&quot;Room: %s #: %d area: %s (%d)&quot;,
      name, num, tostring(mmp.areatabler[areanum]), areanum))

    mmp.echo(string.format(&quot;Coordinates: x:%d, y:%d, z:%d, locked: %s, weight: %s&quot;, coords[1], coords[2], coords[3], (islocked and &quot;yep&quot; or &quot;nope&quot;), tostring(weight)))

    mmp.echo(string.format(&quot;Environment: %s (%d)%s&quot;, tostring(envname), env, (getRoomUserData(num, &quot;indoors&quot;) ~= '' and &quot;, indoors&quot; or '')))

    mmp.echo(string.format(&quot;Exits (%d):&quot;, table.size(exits)))
    for exit, leadsto in pairs(exits) do
      echo(string.format(&quot;  %s -&gt; %s (%d)%s%s\n&quot;, exit, getRoomName(leadsto), leadsto,
        ((getRoomArea(leadsto) or &quot;?&quot;) == areanum and &quot;&quot;
        or &quot; (in &quot;..(mmp.areatabler[getRoomArea(leadsto)] or &quot;?&quot;)..&quot;)&quot;),
        ((not exitweights[mmp.anytoshort(exit)] or exitweights[mmp.anytoshort(exit)] == 0) and &quot;&quot; or &quot; (weight: &quot;..exitweights[mmp.anytoshort(exit)]..&quot;)&quot;)
      ))
    end

    -- display special exits if we got any
    if next(specexits) then
      mmp.echo(string.format(&quot;Special exits (%d):&quot;,table.size(specexits)))

      for leadsto, command in pairs(specexits) do
        if type(command) == &quot;string&quot; then
          echo(string.format(&quot;  %s -&gt; %s (%d)\n&quot;, command, getRoomName(leadsto), leadsto))
        else -- new format - exit name, command
          for cmd, locked in pairs(command) do
            if locked == '1' then
              cecho(string.format(&quot;&lt;DarkSlateGrey&gt;  %s -&gt; %s (%d) (locked)\n&quot;, cmd, getRoomName(leadsto), leadsto))
            else
              echo(string.format(&quot;  %s -&gt; %s (%d)\n&quot;, cmd, getRoomName(leadsto), leadsto))
            end
          end
        end
      end
    end

    -- actions we can do. This will be a short menu of sorts for actions
    mmp.echo(&quot;Stuff you can do:&quot;)
    echo&quot;  &quot; echo(&quot;Clear all labels &quot;) setUnderline(true) echoLink(&quot;(in area)&quot;, 'mmp.clearLabels('..areanum..')', '', true) setUnderline(false)
    echo&quot; &quot; setUnderline(true)
    echoLink(&quot;(whole map)&quot;, [[
    if not mmp.clearinglabels then
      mmp.echo(&quot;Are you sure you want to clear all of your labels on this map? If yes, click the link again.&quot;)
      mmp.clearinglabels = true
    else
      mmp.clearLabels(&quot;map&quot;)
      mmp.clearinglabels = nil
    end
    ]], '', true) setUnderline(false) echo&quot;\n&quot;
    echo&quot;  &quot; setUnderline(true) echoLink(&quot;Check for mapper &amp; map updates&quot;, 'mmp.echo(&quot;Checking...&quot;) mmp.checkforupdate()', '', true) setUnderline(false)
    echo&quot; &quot; setUnderline(true) echoLink(&quot;(force map)&quot;, [[
      if io.exists(getMudletHomeDir()..&quot;/map downloads/current&quot;) then
        local s,m = os.remove(getMudletHomeDir()..&quot;/map downloads/current&quot;)
        if not s then mmp.echo(&quot;Couldn't delete '&quot;..getMudletHomeDir()..&quot;/map downloads/current' file: &quot;..tostring(m)..&quot;.&quot;) end
      end
      mmp.echo(&quot;Re-downloading the latest crowdmap...&quot;)
      mmp.checkforupdate()
    ]], &quot;Re-download the map regardless if you have latest&quot;, true)
    setUnderline(false)
    echo&quot;\n&quot;
  end

  -- see if we can do anything with the name
  local function handle_name(name)
    local result = mmp.searchRoom(name)

    if type(result) == &quot;string&quot; then
      cecho(&quot;&lt;grey&gt;You have no recollection of any room with that name.&quot;) return end

    -- if we got one result, then act on it
    if table.size(result) == 1 then
      if type(next(result)) == &quot;number&quot; then
        handle_number(next(result))
      else
        handle_number(select(2, next(result)))
      end
      return
    end

    -- if not, then ask the user to clarify which one would they want
    mmp.echo(&quot;Which room specifically would you like to look up?&quot;)
    if not select(2, next(result)) or not tonumber(select(2, next(result))) then
      for roomid, roomname in pairs(result) do roomid = tonumber(roomid)
        cecho(string.format(&quot;  &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt; (&lt;blue&gt;&quot;,
          tostring(roomname)))
        cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..roomid, 'mmp.roomLook('..roomid..')', string.format(&quot;View room details for %s (%s)&quot;, roomid, tostring(roomname)), true)
        cecho(string.format(&quot;&lt;DarkSlateGrey&gt;) in the &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt;.\n&quot;, tostring(mmp.areatabler[getRoomArea(roomid)])))
      end

    else
      for roomname, roomid in pairs(result) do roomid = tonumber(roomid)
        cecho(string.format(&quot;  &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt; (&lt;blue&gt;&quot;,
          tostring(roomname)))
        cechoLink(&quot;&lt;&quot;..mmp.echo_colour..&quot;&gt;&quot;..roomid, 'mmp.roomLook('..roomid..')', string.format(&quot;View room details for %s (%s)&quot;, roomid, tostring(roomname)), true)
        cecho(string.format(&quot;&lt;DarkSlateGrey&gt;) in the &lt;LightSlateGray&gt;%s&lt;DarkSlateGrey&gt;.\n&quot;, tostring(mmp.areatabler[getRoomArea(roomid)])))
      end
    end
  end

  if not input then
    if not mmp.roomexists(mmp.currentroom) then
      mmp.echo(mmp.currentroom.. &quot; doesn't seem to be mapped yet.&quot;)
      mmp.echo(&quot;Stuff you can do:&quot;)
      echo&quot;  &quot; echoLink(&quot;Check for all updates&quot;, 'mmp.echo(&quot;Checking...&quot;) mmp.checkforupdate()', '')
      echo&quot; &quot; echoLink(&quot;(force map)&quot;, [[
      local s,m = os.remove(getMudletHomeDir()..&quot;/map downloads/current&quot;)
        if io.exists(getMudletHomeDir()..&quot;/map downloads/current&quot;) then
          local s,m = os.remove(getMudletHomeDir()..&quot;/map downloads/current&quot;)
          if not s then mmp.echo(&quot;Couldn't delete '&quot;..getMudletHomeDir()..&quot;/map downloads/current' file: &quot;..tostring(m)..&quot;.&quot;) end
        end
        mmp.echo(&quot;Re-downloading the latest map...&quot;)
        mmp.checkforupdate()
      ]], &quot;Re-download the map regardless if you have latest&quot;)
      echo&quot;\n&quot;
    else input = mmp.currentroom end
  end

  if tonumber(input) then
    handle_number(tonumber(input))
  else
    handle_name(input)
  end

  mmp.echo(string.format(&quot;version %s.&quot;, tostring(mmp.version)))
end</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>mmp.wormholesfix</name>
                    <packageName></packageName>
                    <script>function mmp.wormholesfix()
  local c = 0
  local weight = 10
  for _, area in pairs(getAreaTable()) do
    local rooms = getAreaRooms(area) or {}
    for i = 0, #rooms do
      local exits = getSpecialExits(rooms[i] or 0)

       if exits and next(exits) then
         for exit, cmd in pairs(exits) do
           if type(cmd) == &quot;table&quot; then cmd = next(cmd) end

           if (cmd:lower():find(&quot;worm warp&quot;, 1, true)) then
				setExitWeight(rooms[i], cmd, weight)
             c = c + 1
           end
         end
       end
    end
  end

  if c &gt; 0 then mmp.echo(string.format(&quot;%s wormholes weighted to %s (so we don't take them over too short distances).&quot;, c, weight)) end
end</script>
                    <eventHandlerList>
                        <string>mmapper updated map</string>
                        <string>sysMapDownloadEvent</string>
                    </eventHandlerList>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>mmp.clearlastupdate</name>
                    <packageName></packageName>
                    <script>function mmp.clearlastupdate()
  -- reset mmp.pdb_lastupdate on the prompt
  enableTrigger&quot;Mudlet Mapper prompt trigger&quot;
end</script>
                    <eventHandlerList>
                        <string>mmapper updated pdb</string>
                    </eventHandlerList>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Third-party functions</name>
                    <packageName></packageName>
                    <script>-- from: http://lua-users.org/wiki/CopyTable
local function deepcopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[deepcopy(orig_key)] = deepcopy(orig_value)
        end
        setmetatable(copy, deepcopy(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

mmp.deepcopy = deepcopy</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>mmp_regenerate_areas</name>
                    <packageName></packageName>
                    <script>function mmp_regenerate_areas()
  -- cached data
  mmp.areatable = getAreaTable() -- this translates an area name to an ID
  mmp.areatabler = {} -- this translates an ID to an area name

  local t = getAreaTable()
  for k,v in pairs(t) do
    mmp.areatabler[tonumber(v)] = k
  end

  mmp.clearpathcache()
end</script>
                    <eventHandlerList>
                        <string>mmp areas changed</string>
                        <string>mmapper map reloaded</string>
                    </eventHandlerList>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>mmp_relock_areas</name>
                    <packageName></packageName>
                    <script>function mmp_relock_areas()
	local getAreaRooms, lockRoom, lockedareas = getAreaRooms, lockRoom, mmp.locked

	for areaid, areaname in pairs(getAreaTableSwap()) do
		if lockedareas[areaid] then
			local rooms = getAreaRooms(areaid) or {}
			for _, roomid in pairs(rooms) do
				lockRoom(roomid, true)
			end
		else
			local rooms = getAreaRooms(areaid) or {}
			for _, roomid in pairs(rooms) do
				lockRoom(roomid, false)
			end
		end
	end

	-- make sure area with ID 0 is locked - this was causing crashing issues
	local rooms = getAreaRooms(0) or {}
	for _, roomid in pairs(rooms) do
		lockRoom(roomid, true)
	end
end</script>
                    <eventHandlerList>
                        <string>mmapper map reloaded</string>
                    </eventHandlerList>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Fix setExit</name>
                    <packageName></packageName>
                    <script>do
local oldsetExit = setExit

local exitmap = {
  n = 1,
  north = 1,
  ne = 2,
  northeast = 2,
  nw = 3,
  northwest = 3,
  e = 4,
  east = 4,
  w = 5,
  west = 5,
  s = 6,
  south = 6,
  se = 7,
  southeast = 7,
  sw = 8,
  southwest = 8,
  u = 9,
  up = 9,
  d = 10,
  down = 10,
  [&quot;in&quot;] = 11,
  out = 12
}

function setExit(from, to, direction)
  if type(direction) == &quot;string&quot; and not exitmap[direction] then return false end

  return oldsetExit(from, to, type(direction) == &quot;string&quot; and exitmap[direction] or direction)
end
end</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Fix exit locking funcs</name>
                    <packageName></packageName>
                    <script>do
local oldlockExit = lockExit
local oldhasExitLock = hasExitLock

local exitmap = {
  n = 1,
  north = 1,
  ne = 2,
  northeast = 2,
  nw = 3,
  northwest = 3,
  e = 4,
  east = 4,
  w = 5,
  west = 5,
  s = 6,
  south = 6,
  se = 7,
  southeast = 7,
  sw = 8,
  southwest = 8,
  u = 9,
  up = 9,
  d = 10,
  down = 10,
  [&quot;in&quot;] = 11,
  out = 12
}

function lockExit(from, direction, status)
  if type(direction) == &quot;string&quot; and not exitmap[direction] then return false end

  return oldlockExit(from, type(direction) == &quot;string&quot; and exitmap[direction] or direction, status)
end

function hasExitLock(from, direction)
  if type(direction) == &quot;string&quot; and not exitmap[direction] then return false end

  return oldhasExitLock(from, type(direction) == &quot;string&quot; and exitmap[direction] or direction)
end
end</script>
                    <eventHandlerList/>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Assorted small utilities</name>
                    <packageName></packageName>
                    <script>function mmp.comma_value(n) -- credit http://richard.warburton.it
	local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
	return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end</script>
                    <eventHandlerList/>
                </Script>
            </Script>
            <Script isActive="yes" isFolder="no">
                <name>Person tracking</name>
                <packageName></packageName>
                <script>--[[
mmp will have 2 person tracking databases:
- mmp.pdb  =  used to store the last known location of a person
- mmp.pdb_lastupdate  =  used to store the output of the last locating command

Both databases work with the person's name as key and the location name as value.

]]
mmp.pdb = mmp.pdb or {}
mmp.pdb_lastupdate = mmp.pdb_lastupdate or {}

function mmp.is_here(who)
  return (mmp.pdb[who] and mmp.pdb[who] == mmp.currentroomname) and true or false
end</script>
                <eventHandlerList/>
            </Script>
            <Script isActive="yes" isFolder="no">
                <name>Lock Area</name>
                <packageName></packageName>
                <script>-- Lock Area

mmp.locked = mmp.locked or {}
mmp.lastLockSearch = mmp.lastLockSearch or nil

function mmp.doLockArea(search)
	local areaList
	if search ~= nil then
		local r = rex.new(string.lower(search))
		mmp.lastLockSearch = search
		for name, id in pairs(getAreaTable()) do
			if r:match(string.lower(name)) then
				areaList = areaList or {}
				areaList[name] = id
			end
		end
		if areaList == nil then
			mmp.echo(&quot;'&quot; .. search .. &quot;' did not match any known areas!&quot;)
			return
		end
	else
		mmp.lastLockSearch = nil
		areaList = getAreaTable()
	end

	for name, id in pairs(areaList) do
		mmp.echon(name .. string.rep(&quot; &quot;, 40 - string.len(name)))
		if not mmp.locked[id] then
			setFgColor(0, 200, 0)
			setUnderline(true)
			echoLink(&quot;Lock!&quot;, [[mmp.lockArea( ']] .. name:gsub(&quot;'&quot;, [[\']]) .. [[', true )]], &quot;Click to lock area '&quot; .. name .. &quot;'&quot;, true)
		else
			setFgColor(200, 0, 0)
			setUnderline(true)
			echoLink(&quot;Unlock!&quot;, [[mmp.lockArea( ']] .. name:gsub(&quot;'&quot;, [[\']]) .. [[', false )]], &quot;Click to unlock area '&quot; .. name .. &quot;'&quot;, true)
		end
	end

	if not search then
		echo&quot;\n\n&quot; mmp.echo(&quot;Use &lt;green&gt;arealock &lt;area&gt;&lt;white&gt; to filter areas.&quot;)
	end
end

function mmp.lockArea(name, lock, dontreshow)
	local areas = getAreaTable()
	local rooms = getAreaRooms(areas[name]) or {}
    local lockRoom = lockRoom
    local count = 0
	for _, room in pairs(rooms) do
		lockRoom(room, lock)
        count = count + 1
	end

	mmp.locked[areas[name]] = lock and true or nil
	mmp.echo(string.format(&quot;Area '%s' %slocked! All %s room%s within it.&quot;, name, (lock and '' or 'un'), count, (count == 1 and '' or 's')))

	if not dontreshow then mmp.doLockArea(mmp.lastLockSearch) end
end


</script>
                <eventHandlerList/>
            </Script>
            <Script isActive="yes" isFolder="no">
                <name>Center view via GMCP</name>
                <packageName></packageName>
                <script></script>
                <eventHandlerList/>
                <Script isActive="yes" isFolder="no">
                    <name>mmp_center_roominfo</name>
                    <packageName></packageName>
                    <script>function mmp_center_roominfo()
  -- lusternia has gmcp.Room.Players before gmcp.Room.Info is created
  if gmcp.Room.Info then centerview(gmcp.Room.Info.num) end
end</script>
                    <eventHandlerList>
                        <string>gmcp.Room</string>
                    </eventHandlerList>
                </Script>
            </Script>
            <ScriptGroup isActive="yes" isFolder="yes">
                <name>mm Mapping</name>
                <packageName></packageName>
                <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                <eventHandlerList/>
                <Script isActive="yes" isFolder="no">
                    <name>mmp_mapping_newroom</name>
                    <packageName></packageName>
                    <script>--mmp_mapping_newroom
local function makeroom(oldid, newid, x,y,z)
  assert(x and y and z, &quot;makeroom: need all 3 coordinates&quot;)
  addRoom(newid)
  setRoomCoordinates(newid, x, y, z)
  setRoomArea(newid, getRoomArea(oldid))

  local fgr,fgg,fgb = unpack(color_table.red)
  local bgr,bgg,bgb = unpack(color_table.blue)
  highlightRoom(newid, fgr,fgg,fgb,bgr,bgg,bgb, 1, 100, 100)

  if mmp.envids[gmcp.Room.Info.environment] then
    setRoomEnv(newid, mmp.envids[gmcp.Room.Info.environment])
  else setRoomEnv(newid, getRoomEnv(oldid)) end

  return string.format(&quot;Created new room %d at %dx,%dy,%dz.&quot;, newid, x,y,z)
end

-- gives the reverse shifted coordinates, ie asking for the sw exit + coords will give the coords at ne
local function getshiftedcoords(original,ox,oy,oz)
  local x,y,z
  local has = table.contains

  -- reverse the exit
  w = mmp.ranytolong(original)

  if has({&quot;west&quot;, &quot;left&quot;, &quot;w&quot;, &quot;l&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy); z = (z or oz)
  elseif has({&quot;east&quot;, &quot;right&quot;, &quot;e&quot;, &quot;r&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy); z = (z or oz)
  elseif has({&quot;north&quot;, &quot;top&quot;, &quot;n&quot;, &quot;t&quot;}, w) then
    x = (x or ox); y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;south&quot;, &quot;bottom&quot;, &quot;s&quot;, &quot;b&quot;}, w) then
    x = (x or ox); y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;northwest&quot;, &quot;topleft&quot;, &quot;nw&quot;, &quot;tl&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;northeast&quot;, &quot;topright&quot;, &quot;ne&quot;, &quot;tr&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy) + 1; z = (z or oz)
  elseif has({&quot;southeast&quot;, &quot;bottomright&quot;, &quot;se&quot;, &quot;br&quot;}, w) then
    x = (x or ox) + 1; y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;southwest&quot;, &quot;bottomleft&quot;, &quot;sw&quot;, &quot;bl&quot;}, w) then
    x = (x or ox) - 1; y = (y or oy) - 1; z = (z or oz)
  elseif has({&quot;up&quot;, &quot;u&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) + 1
  elseif has({&quot;down&quot;, &quot;d&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) - 1
  elseif has({&quot;in&quot;, &quot;i&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) - 1
  elseif has({&quot;out&quot;, &quot;o&quot;}, w) then
    x = (x or ox); y = (y or oy); z = (z or oz) + 1
  else
    mmp.echo(&quot;Don't know where to shift the coordinates for a &quot;..tostring(w)..&quot; (&quot;..tostring(original)..&quot;) exit.&quot;)
  end

  return x,y,z
end

function mmp_mapping_newroom(_, num)
local s,m = xpcall(function ()
  if not mmp.editing then return end
  if not gmcp.Room then
    mmp.echo(&quot;You need to have GMCP turned on (see preferences on a recent Mudlet) for mapping stuff.&quot;)
    return
  end

  -- wilderness mapping right now is UNFINISHED! It does not handle the grid breakup. So, please don't try it, and please won't whine about it.
  local function inwilderness()
    return (gmcp.Room.Info.coords == &quot;&quot; and gmcp.Room.Info.area == &quot;&quot;)
  end

  local getRoomName, getRoomCoordinates, getRoomsByPosition = getRoomName, getRoomCoordinates, getRoomsByPosition

  local num = tonumber(num) or tonumber(gmcp.Room.Info.num)
  local currentexits = gmcp.Room.Info.exits
  local s = &quot;&quot;

  if not mmp.roomexists(num) then
    -- see if we can create and link this room with an existing one
    -- wilderness and non-wilderness rooms require different methods of calculating relative coordinates
    if not inwilderness() then
      for exit, id in pairs(currentexits) do
        if mmp.roomexists(id) then
          s = makeroom(id, num, getshiftedcoords(exit, getRoomCoordinates(id)))
        end
      end
    else
      local x,y = tostring(num):match(&quot;.-(%d%d%d)(%d%d%d)$&quot;)
      -- Achaea's coordinates seem to be in the 4th quadrant, while Mudlets 0,0 is in the middle of the map. Invert y so going north-south looks alright
      s = makeroom(mmp.previousroom, num, x,y*-1,0)
    end
  end

  -- if we created it, and some data could be filled in
  if mmp.roomexists(num) then
    -- cleanup the room name
    local rootroomname = mmp.cleanroomname(gmcp.Room.Info.name)

    -- match exact case, so mappers alertness' works properly
    if getRoomName(num) ~= rootroomname then
      setRoomName(num, rootroomname)
      unHighlightRoom(num)
      s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Updated room name to '&quot;..rootroomname..&quot;'.&quot;
    end

    -- autolink exits
    if not inwilderness() then
      local x = getRoomExits(num) or {}
      -- check for missing exits
      for exit, id in pairs(currentexits) do
        if id == 0 then
          s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Can't link to the &quot;..exit..&quot;, it leads to a room with ID 0 (and that's not supported yet).&quot;
        else
          if not x[mmp.anytolong(exit)] then
            if not mmp.roomexists(id) then
              s = makeroom(num, id, getshiftedcoords(mmp.ranytolong(exit), getRoomCoordinates(num)))
            end
            if setExit(num, id, exit) then
              s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Added missing exit &quot;..exit..&quot; to &quot;..(getRoomName(id) ~= &quot;&quot; and getRoomName(id) or &quot;''&quot;)..&quot; (&quot;..id..&quot;).&quot;
            else
              s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. string.format(&quot;Failed to link %d withh %d via %s exit for some reason :/&quot;, num, id, exit)
            end
          end
        end
      end
    else
      local function getshiftedcoords(direction, ox, oy, oz)
        if direction == 'n' then return ox, oy+1, oz
        elseif direction == 'e' then return ox+1, oy, oz
        elseif direction == 's' then return ox, oy-1, oz
        elseif direction == 'w' then return ox-1, oy, oz
        elseif direction == 'ne' then return ox+1, oy+1, oz
        elseif direction == 'se' then return ox+1, oy-1, oz
        elseif direction == 'sw' then return ox-1, oy-1, oz
        elseif direction == 'nw' then return ox-1, oy+1, oz
        else error(&quot;getshiftedcoords: direction &quot;..direction..&quot; isn't supported yet.&quot;)
        end
      end

      local x,y,z = getRoomCoordinates(num)
      local currentexits = getRoomExits(num) or {}
      for _, exit in ipairs{'n', 'e', 's', 'w', 'ne', 'se', 'sw', 'nw'} do
        local roomatdir = getRoomsByPosition(getRoomArea(num), getshiftedcoords(exit, x,y,z))

        if roomatdir[0] then
          local id = roomatdir[0]

          if not currentexits[mmp.anytolong(exit)] then
            if setExit(num, id, exit) then
              s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Added missing exit &quot;..exit..&quot; to &quot;..(getRoomName(id) ~= &quot;&quot; and getRoomName(id) or &quot;''&quot;)..&quot; (&quot;..id..&quot;).&quot;
            else
              s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. string.format(&quot;Failed to link %d withh %d via %s exit for some reason :/&quot;, num, id, exit)
            end

            local exit = mmp.anytoshort(mmp.ranytolong(exit))
            if setExit(id, num, exit) then
              s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Added missing exit &quot;..exit..&quot; to &quot;..(getRoomName(id) ~= &quot;&quot; and getRoomName(id) or &quot;''&quot;)..&quot; (&quot;..id..&quot;).&quot;
            else
              s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. string.format(&quot;Failed to link %d withh %d via %s exit for some reason :/&quot;, num, id, exit)
            end
          end
        end
      end
    end

    -- check for unexisting exits
    if mmp.settings[&quot;autoclear&quot;] then
      for exit, id in pairs(getRoomExits(num)) do
        if not currentexits[mmp.anytoshort(exit)] then
          setExit(num, -1, exit)
          s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. exit .. &quot; exit to &quot;..id..&quot; doesn't actually exist, removed it.&quot;
        end
      end
    end

    -- check for environment update, if we have environments mapped out
    if mmp.envids[gmcp.Room.Info.environment] and mmp.envids[gmcp.Room.Info.environment] ~= getRoomEnv(num) then
      setRoomEnv(num, mmp.envids[gmcp.Room.Info.environment])
      s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Updated environment name to &quot;..gmcp.Room.Info.environment..&quot;.&quot;
    end

    -- check indoors status
    local indoors = table.contains(gmcp.Room.Info.details, &quot;indoors&quot;)
    if indoors and getRoomUserData(num, &quot;indoors&quot;) == '' then
      setRoomUserData(num, &quot;indoors&quot;, &quot;y&quot;)
      s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Updated room to be indoors.&quot;
    elseif not indoors and getRoomUserData(num, &quot;indoors&quot;) ~= '' then
      setRoomUserData(num, &quot;indoors&quot;, &quot;&quot;)
      s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Updated room to be outdoors.&quot;
    end

    -- check for wilderness exits
    if getRoomChar(num) ~= &quot;W&quot; and table.contains(gmcp.Room.Info.details, &quot;wilderness&quot;) then
      setRoomChar(num, &quot;W&quot;)
      s = s .. (#s &gt; 0 and &quot; &quot; or &quot;&quot;) .. &quot;Added the wilderness mark.&quot;
    end
  end

  if #s &gt; 0 then mmp.echo(s); centerview(mmp.currentroom) end
end, function (error)
  mmp.echo(&quot;Oops! Has a small problem (&quot;..error..&quot;).&quot;)
  echo&quot;  &quot; echoLink(&quot;view steps&quot;, 'echo[['..debug.traceback()..']]', &quot;View steps of code that led up to it&quot;)
end)
if not s then mmp.echo(m) end
end
</script>
                    <eventHandlerList>
                        <string>gmcp.Room.Info</string>
                        <string>RoomNum</string>
                    </eventHandlerList>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>mmp_save_options</name>
                    <packageName></packageName>
                    <script>function mmp_save_options()
	local saveTable = {
		locked_areas = mmp.locked,
		options = mmp.settings:getAllOptions()
	}

	if string.char(getMudletHomeDir():byte()) == &quot;/&quot; then _sep = &quot;/&quot; else  _sep = &quot;\\&quot; end
	local saveFile = getMudletHomeDir() ..  _sep .. &quot;mapper.options.lua&quot;

	table.save(saveFile, saveTable)
end</script>
                    <eventHandlerList>
                        <string>sysExitEvent</string>
                    </eventHandlerList>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>mmp_load_options</name>
                    <packageName></packageName>
                    <script>function mmp_load_options()
	local loadTable = mmp_load_locks()

	if loadTable.options then
		for k, v in pairs(loadTable.options) do
			mmp.settings:setOption(k, v, true)
		end
	end
end

function mmp_load_locks()
	local loadTable = {}

	if string.char(getMudletHomeDir():byte()) == &quot;/&quot; then _sep = &quot;/&quot; else  _sep = &quot;\\&quot; end
	local loadFile = getMudletHomeDir() ..  _sep .. &quot;mapper.options.lua&quot;

    if io.exists(loadFile) then table.load(loadFile, loadTable) end

	if loadTable.locked_areas then
		mmp.locked = loadTable.locked_areas
	end

    local lockRoom, getAreaRooms = lockRoom, getAreaRooms
	for area in pairs(mmp.locked) do
		local rooms = getAreaRooms(area)
		for _, roomid in pairs(rooms or {}) do
			lockRoom(roomid, true)
		end
	end

	return loadTable
end</script>
                    <eventHandlerList>
                        <string>sysLoadEvent</string>
                    </eventHandlerList>
                </Script>
            </ScriptGroup>
            <ScriptGroup isActive="yes" isFolder="yes">
                <name>Game-specific</name>
                <packageName></packageName>
                <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                <eventHandlerList/>
                <Script isActive="yes" isFolder="no">
                    <name>Achaea</name>
                    <packageName></packageName>
                    <script></script>
                    <eventHandlerList/>
                    <Script isActive="yes" isFolder="no">
                        <name>register_achaeas_envdata</name>
                        <packageName></packageName>
                        <script>function register_achaeas_envdata(_, game)
  if game ~= &quot;Achaea&quot; then return end

  mmp.envids =
  {
    Abstract                    = 37,
    Catacombs                   = 14,
    [&quot;Constructed underground&quot;] = 2,
    [&quot;Deep Ocean&quot;]              = 24,
    [&quot;Deep Ocean floor&quot;]        = 30,
    [&quot;Dwarven city&quot;]            = 18,
    [&quot;Magma Caves&quot;]             = 31,
    [&quot;Natural underground&quot;]     = 3,
    [&quot;Ocean floor&quot;]             = 34,
    [&quot;Tsol'aa city&quot;]            = 19,
    Beach                       = 5,
    Blighted                    = 29,
    Chaos                       = 38,
    Desert                      = 6,
    Forest                      = 4,
    Freshwater                  = 22,
    Garden                      = 21,
    Grasslands                  = 7,
    Hills                       = 9,
    Jungle                      = 17,
    [&quot;Lava Fields&quot;]   = 39,
    Mountains                   = 14,
    Nothing                     = 0,
    Ocean                       = 20,
    Path                        = 11,
    Polar                       = 27,
    Reef                        = 25,
    River                       = 10,
    Road                        = 12,
    Ruins                       = 32,
    Sewer                       = 23,
    Skies                       = 10,
    Swamp                       = 15,
    Trees                       = 28,
    Tundra                      = 16,
    Urban                       = 8,
    Valley                      = 13,
    [&quot;Vast Ocean&quot;]    = 40,
    Vessel                      = 36,
    Water                       = 30,
  }

  mmp.waterenvs = {}
  local waterids = { &quot;Freshwater&quot;, &quot;Ocean&quot;, &quot;River&quot;, &quot;Deep Ocean&quot;, &quot;Water&quot;, &quot;Reef&quot;, &quot;Ocean floor&quot;, &quot;Vast Ocean&quot; }
  for i = 1, #waterids do mmp.waterenvs[mmp.envids[waterids[i]]] = true end

  mmp.envidsr = {};
  for name, id in pairs(mmp.envids) do mmp.envidsr[id] = name end
end</script>
                        <eventHandlerList>
                            <string>mmp logged in</string>
                        </eventHandlerList>
                    </Script>
                    <Script isActive="yes" isFolder="no">
                        <name>mmapper_achaea_went_outside</name>
                        <packageName></packageName>
                        <script>-- track whenever we need to use wings when we get outside!
function mmapper_achaea_went_outside()
  if not mmp.autowalking or not (mmp.settings.duanathar or mmp.settings.duanatharan or mmp.settings.duantahar) or mmp.game ~= &quot;achaea&quot; or
    (mmp.currentroom == mmp.speedWalkPath[#mmp.speedWalkPath]) or
    table.contains(gmcp.Room.Info.details, &quot;indoors&quot;) or
    not mmp.oncontinent(getRoomArea(mmp.currentroom), &quot;Main&quot;) then return end

  -- repath, maybe that'll allow us to use wings now.
  local madeduanatharan, madeduanathar, madeduantahar

  local function getcmd(word)
    return mmp.settings.removewings and
      [[script:sendAll(&quot;wear wings&quot;, &quot;say *]]..(mmp.settings.winglanguage)..[[ ]]..word..[[&quot;, &quot;remove wings&quot;, false)]]
      or
      [[script:send(&quot;say *]]..(mmp.settings.winglanguage)..[[ ]]..word..[[&quot;, false)]]
  end

    if mmp.settings.duanatharan then
      addSpecialExit(mmp.currentroom, 4882, getcmd(&quot;duanatharan&quot;))
      addSpecialExit(mmp.currentroom, 3885, getcmd(&quot;duanathar&quot;))
      --mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeduanatharan = true
    elseif mmp.settings.duantahar then
      addSpecialExit(mmp.currentroom, 42319, getcmd(&quot;duanathar&quot;))
      addSpecialExit(mmp.currentroom, 4882, getcmd(&quot;duanatharan&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeduantahar = true
    else
      addSpecialExit(mmp.currentroom, 3885, getcmd(&quot;duanathar&quot;))
      --mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeduanathar = true
    end

  mmp.getPath(mmp.currentroom, mmp.speedWalkPath[#mmp.speedWalkPath]) -- don't need to check return value since that fact shouldnt've changed

  -- if our path didn't change, re-instate it as it was (since the new path starts from this room that we checked at)
  if speedWalkDir[1]:find(&quot;duanathar&quot;, 1, true) then
    speedWalkCounter = 0
    mmp.echo(&quot;We got outside - going to shortcut with wings.&quot;)
    mmp.gotoRoom(mmp.speedWalkPath[#mmp.speedWalkPath])
    mmp.ignore_speedwalking = true
  end

  if madeduanatharan then mmp.clearspecials{4882, 3885}
  elseif madeduanathar then mmp.clearspecials{3885}
  elseif madeduantahar then mmp.clearspecials{42319, 4882}
  end
end</script>
                        <eventHandlerList>
                            <string>mmapper went outside</string>
                            <string>mmapper changed continent</string>
                        </eventHandlerList>
                    </Script>
                    <Script isActive="yes" isFolder="no">
                        <name>achaea_gaia_whirlpool_reset</name>
                        <packageName></packageName>
                        <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
function achaea_gaia_whirlpool_reset(event, game)
	if game == &quot;Achaea&quot; then
		mmp.whirlString = 'script: send(&quot;enter whirlpool&quot;) if tempWhirlTrigger then killTrigger(tempWhirlTrigger) tempWhirlTrigger = nil end if tempWhirlTimer then killTimer(killWhirlTimer) tempWhirlTimer = nil end tempWhirlTrigger = tempTrigger(&quot;What do you wish to enter?&quot;, [[if tempWhirlTimer then killTimer(tempWhirlTimer) tempWhirlTimer = nil end mmp.echo(&quot;Whirlpool not found here. Trying another room.&quot;) local x = {45817, 45780, 45903, 45868, 46254, 45866} if tempWhirlTrigger then killTrigger(tempWhirlTrigger) tempWhirlTrigger = nil end clearSpecialExits(]]..mmp.currentroom..[[) local y = table.index_of(x, ]]..mmp.currentroom..[[) + 1 if y &gt; #x then y = 1 end addSpecialExit(x[y], 793, mmp.whirlString) mmp.clearpathcache() mmp.gotoRoom(mmp.speedWalkPath[#mmp.speedWalkPath]) mmp.echo(&quot;Moved whirlpool to &quot;..x[y]..&quot;.&quot;)]]) tempWhirlTimer = tempTimer(1, [[if tempWhirlTrigger then killTrigger(tempWhirlTrigger) tempWhirlTrigger = nil end if tempWhirlTimer then killTimer(tempWhirlTimer) tempWhirlTimer = nil end]])'
		local x = {45817, 45780, 45903, 45868, 46254, 45866}
		for i, v in ipairs(x) do clearSpecialExits(v) end
		addSpecialExit(45868, 793, mmp.whirlString)
	end
end</script>
                        <eventHandlerList>
                            <string>mmp logged in</string>
                        </eventHandlerList>
                    </Script>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Aetolia</name>
                    <packageName></packageName>
                    <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                    <eventHandlerList/>
                    <Script isActive="yes" isFolder="no">
                        <name>register_aetolias_envdata</name>
                        <packageName></packageName>
                        <script>function register_aetolias_envdata(_, game)
  if game ~= &quot;Aetolia&quot; then return end

  mmp.envids =
  {
    [&quot;a bridge&quot;]                = 55,
    [&quot;Airship wreckage&quot;]        = 62,
    [&quot;camp site&quot;]               = 57,
    [&quot;Constructed underground&quot;] = 2,
    [&quot;Deep ocean&quot;]              = 24,
    [&quot;lifeless sands&quot;]          = 54,
    [&quot;logged forest&quot;]           = 56,
    [&quot;Natural underground&quot;]     = 3,
    [&quot;Tsol'aa city&quot;]            = 19,
    [&quot;Underwater city&quot;]         = 28,
    [&quot;within a tree&quot;]           = 36,
    Beach                       = 5,
    Canyon                      = 34,
    Castle                      = 61,
    Cavern                      = 69,
    Chaos                       = 1,
    Crater                      = 37,
    Desert                      = 6,
    Ethereal                    = 67,
    Forest                      = 4,
    Freshwater                  = 22,
    Garden                      = 21,
    Grasslands                  = 7,
    Graveyard                   = 31,
    grotto                      = 70,
    Hills                       = 9,
    Ice                         = 30,
    Jungle                      = 17,
    lava                        = 39,
    Mines                       = 32,
    Mountains                   = 14,
    Ocean                       = 20,
    Onboard                     = 33,
    Path                        = 11,
    Reef                        = 25,
    River                       = 10,
    Road                        = 12,
    Ruins                       = 26,
    Sewer                       = 23,
    Shadows                     = 58,
    Swamp                       = 15,
    Temple                      = 29,
    Tundra                      = 16,
    Urban                       = 8,
    Valley                      = 13,
    Village                     = 27,
  }

  mmp.waterenvs = {}
  local waterids = { &quot;River&quot;, &quot;Freshwater&quot;, &quot;Deep ocean&quot;, &quot;Reef&quot;, &quot;Underwater city&quot; }
  for i = 1, #waterids do mmp.waterenvs[mmp.envids[waterids[i]]] = true end

  mmp.envidsr = {};
  for name, id in pairs(mmp.envids) do mmp.envidsr[id] = name end
end</script>
                        <eventHandlerList>
                            <string>mmp logged in</string>
                        </eventHandlerList>
                    </Script>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Lusternia</name>
                    <packageName></packageName>
                    <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                    <eventHandlerList/>
                    <Script isActive="yes" isFolder="no">
                        <name>register_lusternias_envdata</name>
                        <packageName></packageName>
                        <script>function register_lusternias_envdata(_, game)
  if game ~= &quot;Lusternia&quot; then return end

  mmp.envids =
  {
    [&quot;constructed underground&quot;] = 2,
    [&quot;deep ocean&quot;]              = 24,
    [&quot;natural underground&quot;]     = 3,
    aether                      = 36,
    astral                      = 35,
    beach                       = 5,
    chaos                       = 39,
    clouds                      = 37,
    concordance                 = 38,
    darkness                    = 1,
    desert                      = 6,
    divine                      = 33,
    farmlands                   = 30,
    flesh                       = 18,
    forest                      = 4,
    freshwater                  = 22,
    garden                      = 21,
    grasslands                  = 7,
    hills                       = 9,
    jungle                      = 17,
    mountains                   = 14,
    netherworld                 = 34,
    ocean                       = 20,
    path                        = 11,
    polar                       = 27,
    reef                        = 25,
    river                       = 10,
    road                        = 12,
    ruins                       = 19,
    sewer                       = 23,
    swamp                       = 15,
    trees                       = 28,
    tundra                      = 16,
    urban                       = 8,
    valley                      = 13,
    volcanic                    = 32,
    wasteland                   = 29,
  }

  mmp.waterenvs = {}
  local waterids = { &quot;river&quot;, &quot;ocean&quot;, &quot;freshwater&quot;, &quot;deep ocean&quot; }
  for i = 1, #waterids do mmp.waterenvs[mmp.envids[waterids[i]]] = true end

  mmp.envidsr = {};
  for name, id in pairs(mmp.envids) do mmp.envidsr[id] = name end
end</script>
                        <eventHandlerList>
                            <string>mmp logged in</string>
                        </eventHandlerList>
                    </Script>
                    <Script isActive="yes" isFolder="no">
                        <name>mmapper_lusternia_went_outside</name>
                        <packageName></packageName>
                        <script>function mmapper_lusternia_went_outside()
  -- track whenever we need to use items when we get outside!
  if not mmp.autowalking or not (mmp.settings.medallion or mmp.settings.fingerblade or mmp.settings.blossom or mmp.settings.belt or mmp.settings.cubix or mmp.settings.screwdriver or mmp.settings.wheel or mmp.settings.mud or mmp.settings.snowglobe or mmp.settings.cookie or mmp.settings.head or mmp.settings.icicle or mmp.settings.tibia or mmp.settings.bonecurio or mmp.settings.flowercurio or mmp.settings.torus or mmp.settings.utensilcurio or mmp.settings.fluttercurio or mmp.settings.toolcurio or mmp.settings.facecurio or mmp.settings.toycurio or mmp.settings.mandala or mmp.settings.feathercurio or mmp.settings.figurecurio or mmp.settings.vernalcurio) or mmp.game ~= &quot;lusternia&quot; or
    (mmp.currentroom == mmp.speedWalkPath[#mmp.speedWalkPath]) then return end

  -- repath, maybe that'll allow us to use wings now.
  local mademedallion, madefingerblade, madeblossom, madebelt, madeprism, madecubix, madescrewdriver, madewheel, mademud, madesnowglobe, madehead, madecookie, madeicicle, madetibia, madebonecurio, madeflowercurio, madetorus, madeutensilcurio, madefluttercurio, madetoolcurio, madefacecurio, madetoycurio, madefeathercurio, madefigurecurio, mademandala, madevernalcurio

  local function getcmd(item)
		if item == &quot;snowglobe&quot; then
			return [[script:send(&quot;shake snowglobe&quot;,false)]]
		elseif word == &quot;bonecurio&quot; then
			return [[script:send(&quot;curio collection activate bone&quot;,false)]]
		elseif word == &quot;flowercurio&quot; then
			return [[script:send(&quot;curio collection activate flower&quot;,false)]]
		elseif word == &quot;utensilcurio&quot; then
			return [[script:send(&quot;curio collection activate utensil&quot;,false)]]
		elseif word == &quot;fluttercurio&quot; then
			return [[script:send(&quot;curio collection activate flutter&quot;,false)]]
		elseif word == &quot;toolcurio&quot; then
			return [[script:send(&quot;curio collection activate tool&quot;,false)]]
		elseif word == &quot;facecurio&quot; then
			return [[script:send(&quot;curio collection activate face&quot;,false)]]
		elseif word == &quot;toycurio&quot; then
			return [[script:send(&quot;curio collection activate toy&quot;,false)]]
		elseif word == &quot;feathercurio&quot; then
			return [[script:send(&quot;curio collection activate feather&quot;,false)]]
		elseif word == &quot;figurecurio&quot; then
			return [[script:send(&quot;curio collection activate figure&quot;,false)]]
		elseif word == &quot;vernalcurio&quot; then
			return [[script:send(&quot;curio collection activate vernal&quot;,false)]]
		else
			return [[script:send(&quot;touch ]]..(item)..[[&quot;, false)]]
		end
  end

    if mmp.settings.medallion and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 13367, getcmd(&quot;medallion&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      mademedallion = true
	end
	if mmp.settings.fingerblade and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 18777, getcmd(&quot;fingerblade&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefingerblade = true
	end
	if mmp.settings.blossom and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 18730, getcmd(&quot;blossom&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeblossom = true
	end
	if mmp.settings.mandala and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 19563, getcmd(&quot;mandala&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      mademandala = true
	end
	if mmp.settings.belt and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 19627, getcmd(&quot;belt&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madebelt = true
	end
	if mmp.settings.cubix and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 6184, getcmd(&quot;cubix&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madecubix = true
	end
	if mmp.settings.screwdriver and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Facility&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;screwdriver&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 10185, getcmd(&quot;screwdriver&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madescrewdriver = true
	end
	if mmp.settings.wheel and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Dramube Triangle&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;wheel&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 10509, getcmd(&quot;wheel&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madewheel = true
	end
	if mmp.settings.mud and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;Mucklemarsh&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;mud&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 9985, getcmd(&quot;mud&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      mademud = true
	end
	if mmp.settings.snowglobe and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Great Spirit Tree&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;snowglobe&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 10992, getcmd(&quot;snowglobe&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madesnowglobe = true
	end
	if mmp.settings.cookie and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;Crumkindivia&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;cookie&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 9888, getcmd(&quot;cookie&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madecookie = true
	end
	if mmp.settings.head and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Bubble of Bottledowns&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;doll&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 11811, getcmd(&quot;doll&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madedoll = true
	end
	if mmp.settings.icicle and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;Frosticia&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;icicle&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 10457, getcmd(&quot;icicle&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeicicle = true
	end
	if mmp.settings.tibia and mmp.usebubblix() then
		if gmcp.Room.Info.area == &quot;the Cankermore Battlegrounds&quot; then
      		addSpecialExit(mmp.currentroom, 6831, getcmd(&quot;tibia&quot;))
		elseif not table.contains(gmcp.Room.Info.details, &quot;an Aetherbubble&quot;) then
      		addSpecialExit(mmp.currentroom, 11600, getcmd(&quot;tibia&quot;))
		end
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madetibia = true
	end
   if mmp.settings.bonecurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28613, getcmd(&quot;bonecurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madebonecurio = true
	end
	if mmp.settings.flowercurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28624, getcmd(&quot;flowercurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeflowercurio = true
	end
	if mmp.settings.torus and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 25848, getcmd(&quot;torus&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madetorus = true
	end
	if mmp.settings.utensilcurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28617, getcmd(&quot;utensilcurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madeutensilcurio = true
	end
	if mmp.settings.fluttercurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28622, getcmd(&quot;fluttercurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefluttercurio = true
	end
	if mmp.settings.toolcurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28586, getcmd(&quot;toolcurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madetoolcurio = true
	end
	if mmp.settings.facecurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28433, getcmd(&quot;facecurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefacecurio = true
	end
	if mmp.settings.toycurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 21548, getcmd(&quot;toycurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madetoycurio = true
	end
	if mmp.settings.feathercurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28591, getcmd(&quot;feathercurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefeathercurio = true
	end
	if mmp.settings.figurecurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 28312, getcmd(&quot;figurecurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madefigurecurio = true
	end
   if mmp.settings.prism and mmp.useprism() then
		addSpecialExit(mmp.currentroom, 6182, getcmd(&quot;prism&quot;))
		mmp.clearpathcache()
		madeprism = true
	end
	if mmp.settings.vernalcurio and mmp.usebix() then
      addSpecialExit(mmp.currentroom, 29908, getcmd(&quot;vernalcurio&quot;))
      mmp.clearpathcache() -- clear cache so mmp.getPath accounts for the new way
      madevernalcurio = true
	end

  mmp.getPath(mmp.currentroom, mmp.speedWalkPath[#mmp.speedWalkPath]) -- don't need to check return value since that fact shouldnt've changed

  -- if our path didn't change, re-instate it as it was (since the new path starts from this room that we checked at)
  if speedWalkDir[1]:find(&quot;medallion&quot;,1,true) or speedWalkDir[1]:find(&quot;fingerblade&quot;,1,true) or speedWalkDir[1]:find(&quot;blossom&quot;,1,true) or speedWalkDir[1]:find(&quot;belt&quot;) or speedWalkDir[1]:find(&quot;cubix&quot;) or speedWalkDir[1]:find(&quot;bonecurio&quot;,1,true) or speedWalkDir[1]:find(&quot;flowercurio&quot;,1,true) or speedWalkDir[1]:find(&quot;torus&quot;,1,true) or speedWalkDir[1]:find(&quot;utensilcurio&quot;,1,true) or speedWalkDir[1]:find(&quot;fluttercurio&quot;,1,true) or speedWalkDir[1]:find(&quot;toolcurio&quot;,1,true) or speedWalkDir[1]:find(&quot;facecurio&quot;,1,true) or speedWalkDir[1]:find(&quot;toycurio&quot;,1,true) or speedWalkDir[1]:find(&quot;feathercurio&quot;,1,true) or speedWalkDir[1]:find(&quot;mandala&quot;,1,true) or speedWalkDir[1]:find(&quot;figurecurio&quot;,1,true) or speedWalkDir[1]:find(&quot;prism&quot;,1,true) or speedWalkDir[1]:find(&quot;vernalcurio&quot;,1,true) then
    speedWalkCounter = 0
    mmp.echo(&quot;We got outside - going to shortcut with 'bix device.&quot;)
    mmp.gotoRoom(mmp.speedWalkPath[#mmp.speedWalkPath])
    mmp.ignore_speedwalking = true
  end

  if mademedallion then mmp.clearspecials{13367} end
  if madefingerblade then mmp.clearspecials{18777} end
  if madeblossom then mmp.clearspecials{18730} end
  if madebelt then mmp.clearspecials{19627} end
  if madecubix then mmp.clearspecials{6184} end
  if madescrewdriver then mmp.clearspecials{6831, 10185} end
  if madewheel then mmp.clearspecials{6831, 10509} end
  if mademud then mmp.clearspecials{6831, 9985} end
  if madesnowglobe then mmp.clearspecials{6831, 10992} end
  if madecookie then mmp.clearspecials{6831, 9888} end
  if madehead then mmp.clearspecials{6831, 11811} end
  if madeicicle then mmp.clearspecials{6831, 10457} end
  if madetibia then mmp.clearspecials{6831, 11600} end
  if madebonecurio then mmp.clearspecials{28613} end
  if madeflowercurio then mmp.clearspecials{28624} end
  if madetorus then mmp.clearspecials{25848} end
  if madeutensilcurio then mmp.clearspecials{28617} end
  if madefluttercurio then mmp.clearspecials{28622} end
  if madetoolcurio then mmp.clearspecials{28586} end
  if madefacecurio then mmp.clearspecials{28433} end
  if madetoycurio then mmp.clearspecials{21548} end
  if madefeathercurio then mmp.clearspecials{28591} end
  if madefigurecurio then mmp.clearspecials{28312} end
  if madeprism then mmp.clearspecials{6182} end
  if madevernalcurio then mmp.clearspecials{29908} end
  if mademandala then mmp.clearspecials{19563} end
end
</script>
                        <eventHandlerList>
                            <string>mmapper went outside</string>
                        </eventHandlerList>
                    </Script>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Imperian</name>
                    <packageName></packageName>
                    <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                    <eventHandlerList/>
                    <Script isActive="yes" isFolder="no">
                        <name>register_imperians_envdata</name>
                        <packageName></packageName>
                        <script>function register_imperians_envdata(_, game)
  if game ~= &quot;Imperian&quot; then return end
  mmp.envids =
  {
    [&quot;a sheltered dell&quot;]        = 68,
    [&quot;Arcane Temple&quot;]           = 66,
    [&quot;Blackened Lands&quot;]         = 58,
    [&quot;Blackstone Dungeon&quot;]      = 65,
    [&quot;Blackstone Keep&quot;]         = 62,
    [&quot;Constructed underground&quot;] = 2,
    [&quot;Dark Forest&quot;]             = 1,
    [&quot;Deep Ocean&quot;]              = 24,
    [&quot;Desert Ruins&quot;]            = 38,
    [&quot;Dwarven city&quot;]            = 18,
    [&quot;Forestal Council&quot;]        = 44,
    [&quot;Frozen Bog&quot;]              = 76,
    [&quot;Lake of Fire&quot;]            = 56,
    [&quot;Natural underground&quot;]     = 3,
    [&quot;Noble Bar&quot;]               = 53,
    [&quot;Noble Chambers&quot;]          = 51,
    [&quot;Rocky Shore&quot;]             = 77,
    [&quot;Sylayan city&quot;]            = 19,
    [&quot;Tainted Underground&quot;]     = 35,
    [&quot;Tainted Water&quot;]           = 39,
    [&quot;Underground Lake&quot;]        = 36,
    [&quot;Vast Ocean&quot;]              = 26,
    [&quot;Wetlands Village&quot;]        = 64,
    [&quot;within a tent&quot;]           = 69,
    Academia                    = 42,
    Acropolis                   = 33,
    Beach                       = 5,
    Blighted                    = 74,
    bog                         = 73,
    Catacombs                   = 63,
    Church                      = 54,
    Cliffs                      = 67,
    Crags                       = 32,
    Desert                      = 6,
    Docks                       = 30,
    Farmland                    = 41,
    Forest                      = 4,
    Freshwater                  = 22,
    Garden                      = 21,
    garrison                    = 71,
    Grasslands                  = 7,
    Graveyard                   = 46,
    Hills                       = 9,
    Jungle                      = 17,
    Mountains                   = 14,
    Nobility                    = 50,
    Ocean                       = 20,
    Path                        = 11,
    Polar                       = 27,
    Pond                        = 49,
    pyramid                     = 72,
    quarry                      = 70,
    River                       = 10,
    Road                        = 12,
    Ruins                       = 37,
    Scrublands                  = 78,
    Sewer                       = 23,
    Swamp                       = 15,
    Temple                      = 57,
    Tower                       = 79,
    transportation              = 48,
    Tundra                      = 16,
    Underworld                  = 28,
    Urban                       = 8,
    Valley                      = 13,
    Villa                       = 75,
    Village                     = 47,
    Village                     = 55,
    Volcano                     = 59,
    Warrens                     = 31,
  }

  mmp.waterenvs = {}
  local waterids = { &quot;River&quot;, &quot;Ocean&quot;, &quot;Deep Ocean&quot;, &quot;Vast Ocean&quot;, &quot;Underground Lake&quot;, &quot;Tainted Water&quot;, &quot;Lake of Fire&quot; }
  for i = 1, #waterids do mmp.waterenvs[mmp.envids[waterids[i]]] = true end

  mmp.envidsr = {};
  for name, id in pairs(mmp.envids) do mmp.envidsr[id] = name end
end</script>
                        <eventHandlerList>
                            <string>mmp logged in</string>
                        </eventHandlerList>
                    </Script>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Midmekia Online</name>
                    <packageName></packageName>
                    <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                    <eventHandlerList/>
                    <Script isActive="yes" isFolder="no">
                        <name>register_midkemias_envdata</name>
                        <packageName></packageName>
                        <script>function register_midkemias_envdata(_, game)
  if game ~= &quot;Midkemia Online&quot; then return end
  mmp.envids =
  {
    [&quot;constructed underground&quot;] = 2,
    [&quot;fresh water&quot;]             = 20,
    [&quot;natural underground&quot;]     = 3,
    [&quot;shores of Lake Moraelin&quot;] = 33,
    beach                       = 5,
    canyon                      = 29,
    farmlands                   = 31,
    forest                      = 4,
    garden                      = 19,
    grasslands                  = 7,
    hills                       = 9,
    ice                         = 27,
    mines                       = 28,
    mountains                   = 14,
    ocean                       = 18,
    path                        = 11,
    plains                      = 30,
    reef                        = 23,
    river                       = 10,
    road                        = 12,
    ruins                       = 24,
    sewers                      = 21,
    swamp                       = 15,
    temple                      = 26,
    tundra                      = 16,
    urban                       = 8,
    valley                      = 13,
    village                     = 25,
    volcanic                    = 32,
  }

  mmp.waterenvs = {}
  local waterids = { &quot;river&quot;, &quot;ocean&quot;, &quot;fresh water&quot;, &quot;reef&quot; }
  for i = 1, #waterids do mmp.waterenvs[mmp.envids[waterids[i]]] = true end

  mmp.envidsr = {};
  for name, id in pairs(mmp.envids) do mmp.envidsr[id] = name end
end</script>
                        <eventHandlerList>
                            <string>mmp logged in</string>
                        </eventHandlerList>
                    </Script>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Lithmeria</name>
                    <packageName></packageName>
                    <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                    <eventHandlerList/>
                    <Script isActive="yes" isFolder="no">
                        <name>register_lithmerias_envdata</name>
                        <packageName></packageName>
                        <script>function register_lithmerias_envdata(_, game)
  if game ~= &quot;Lithmeria&quot; then return end

  mmp.envids =
  {
    [&quot;deep water&quot;] = 4,
    beach          = 11,
    bridge         = 6,
    building       = 13,
    cliffs         = 1,
    desert         = 11,
    forest         = 2,
    highway        = 6,
    jungle         = 10,
    mountain       = 1,
    ocean          = 4,
    path           = 6,
    plains         = 3,
    river          = 4,
    road           = 6,
    shallowwater   = 4,
    swamp          = 2,
    tundra         = 7,
    underground    = 8,
    urban          = 8,
    water          = 4,
  }

  for name, number in pairs(mmp.envids) do
    mmp.envids[name] = number+256 -- adjust for in-built colors
  end

  mmp.waterenvs = {}
  local waterids = { &quot;shallowwater&quot;, &quot;river&quot;, &quot;water&quot;, &quot;deep water&quot;, &quot;ocean&quot; }
  for i = 1, #waterids do mmp.waterenvs[mmp.envids[waterids[i]]] = true end

  mmp.envidsr = {};
  for name, id in pairs(mmp.envids) do mmp.envidsr[id] = name end
end</script>
                        <eventHandlerList>
                            <string>mmp logged in</string>
                        </eventHandlerList>
                    </Script>
                </Script>
            </ScriptGroup>
            <ScriptGroup isActive="yes" isFolder="yes">
                <name>Test / one-time things</name>
                <packageName></packageName>
                <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                <eventHandlerList/>
                <Script isActive="no" isFolder="no">
                    <name>mmp_grabenvid</name>
                    <packageName></packageName>
                    <script>function mmp_grabenvid()
  if not mmp.envids[gmcp.Room.Info.environment] then
    mmp.envids[gmcp.Room.Info.environment] = getRoomEnv(mmp.currentroom)
    mmp.echo(string.format(&quot;Remembered environment %s as %d&quot;, gmcp.Room.Info.environment, mmp.envids[gmcp.Room.Info.environment]))
  end
end

function mmp.getMaxID()
  local roomIDs = {}
  for area, _ in pairs(mmp.areatabler) do
    local ok, t = pcall(getAreaRooms, area)
    if ok then
      for _, id in pairs(t or {}) do
        roomIDs[id] = true
      end
    end
  end

  return table.maxn(roomIDs)
end

function mmp.getUnknownEnvs()
  local maxid, missing = mmp.getMaxID(), {}

  for i = 1, maxid do
    if mmp.roomexists(i) then
      if not table.contains(mmp.envids, getRoomEnv(i)) and not table.contains(missing, getRoomEnv(i)) then
        mmp.echo(string.format(&quot;Missing env %d from room %d ('%s' in '%s')&quot;,
          tostring(getRoomEnv(i)), i, tostring(getRoomName(i)), tostring(mmp.areatabler[getRoomArea(i)])))
        missing[i] = getRoomEnv(i)
      end
    end
  end
end</script>
                    <eventHandlerList>
                        <string>gmcp.Room.Info</string>
                    </eventHandlerList>
                </Script>
            </ScriptGroup>
            <ScriptGroup isActive="yes" isFolder="yes">
                <name>Check for map updates</name>
                <packageName></packageName>
                <script>-------------------------------------------------
--         Put your Lua functions here.        --
--                                             --
-- Note that you can also use external Scripts --
-------------------------------------------------
</script>
                <eventHandlerList/>
                <Script isActive="yes" isFolder="no">
                    <name>mmp_downloaded_file</name>
                    <packageName></packageName>
                    <script>function mmp_downloaded_file(_, filename)
  if not io.exists(filename) then return end

  -- workaround for https://bugs.launchpad.net/mudlet/+bug/1092769
--  if mmp[&quot;downloaded_file_block_&quot;..filename] then return end
--  mmp[&quot;downloaded_file_block_&quot;..filename] = tempTimer(5, [[mmp[&quot;downloaded_file_block_]]..filename..[[&quot;] = nil]])

  if filename == tostring(mmp.mapperfile) then   -- mapper script version
	mmp.checkingupdates = false

    local f, s = io.open(filename)
    if f then s = f:read(&quot;*l&quot;):trim(); io.close(f) end

    if s ~= tostring(mmp.version) then
      mmp.newmapperversion = s
      mmp.retrievechangelog()
    end

  elseif filename == tostring(mmp.changelogfile) then   -- changelog for the mapper script
	mmp.checkingupdates = false

    local f, s, changelog = io.open(filename)
    if f then changelog = f:read(&quot;*a&quot;); io.close(f) end

    mmp.echon(&quot;&quot;)
    echoLink(&quot;The mapper script was updated! Would you like to download the update? Click here if so.&quot;, &quot;mmp.downloadmapperscript()&quot;, &quot;Changelog for the latest (&quot;..tostring(mmp.version)..&quot; -&gt; &quot;..tostring(mmp.newmapperversion)..&quot;) update:\n&quot;..changelog, true)

  elseif filename == mmp.crowdchangelogfile then   -- changelog for the crowdmap
    local f, s = io.open(filename)
    if f then s = f:read(&quot;*a&quot;); io.close(f) end

    -- make environment
    local env = {} -- add functions you know are safe here

    -- run code under environment [Lua 5.1]
    local function run(untrusted_code)
      if untrusted_code:byte(1) == 27 then return nil, &quot;binary bytecode prohibited&quot; end
      local untrusted_function, message = loadstring(untrusted_code)
      if not untrusted_function then return nil, message end
      setfenv(untrusted_function, env)
      return pcall(untrusted_function)
    end

    run(s)

	mmp.crowdchangelog = env.changelog

    mmp.echon(&quot;The crowdmap map was &quot;)
    setUnderline(true)
    echoLink(&quot;updated&quot;, '', &quot;New version: &quot;..tostring(mmp.newversion)..&quot;, previous version: &quot;..(mmp.oldversion or &quot;(none)&quot;), true)
    setUnderline(false)
    echo(&quot; (&quot;)
    setUnderline(true)
    echoLink(&quot;see full changelog&quot;, &quot;mmp.showcrowdchangelog()&quot;, 'View the full changelog for mappers', true)
    setUnderline(false)
    echo(&quot;). Latest improvement is: &quot;..tostring(mmp.crowdchangelog and mmp.crowdchangelog[#mmp.crowdchangelog] or '?')..&quot;.\n&quot;)

    mmp.downloadcrowdmap(mmp.newversion)

  elseif filename == mmp.crowdmapfile then    -- crowdmap map
    mmp.echo(&quot;Map downloaded, loading it in...&quot;)

    local tmp = getRoomUserData(1, &quot;gotoMapping&quot;)
    local oldmaptable = {}

    if tmp ~= &quot;&quot; then
      oldmaptable = yajl.to_value(tmp)
    end

    local ok = loadMap(filename)

    if ok then
      local wc = mmp.lockWormholes()
	  local ws = mmp.lockSewers()
      mmp.lockPebble()
      if mmp.game == &quot;achaea&quot; and wc == 0 and ws == 0 then -- in achaea, using crowdmap, if we didn't get any special exits - it means Mudlet needs to be updated
        mmp.echo(&quot;Sorry, it seems your Mudlet isn't compatible with the new crowdmap format - and the map cannot be loaded fully. Please update your Mudlet:\n  http://www.mudlet.org/download/&quot;)
        return
      end

      if mmp.settings.waterwalk then mmp.enableWaterWalk() else mmp.disableWaterWalk() end

      mmp.echo(&quot;Map loaded fine - enjoy!&quot;)

      tmp = getRoomUserData(1, &quot;gotoMapping&quot;)
      local newmaptable = {}

      if tmp ~= &quot;&quot; then
        newmaptable = yajl.to_value(tmp)
      end

      for k,v in pairs(oldmaptable) do newmaptable[k] = v end
      setRoomUserData(1, &quot;gotoMapping&quot;, yajl.to_string(newmaptable))
      mmp.echo(&quot;Marks from the old map migrated successfully.&quot;)

      raiseEvent(&quot;mmapper updated map&quot;)
    else
      mmp.echon(&quot;Map failed to load - you need to have the mapper open. Please open it, and then &quot;)
      echoLink(&quot;click here&quot;, [[
        local tmp = getRoomUserData(1, &quot;gotoMapping&quot;)
        local oldmaptable = {}
        if tmp ~= &quot;&quot; then
          oldmaptable = yajl.to_value(tmp)
        end

        local ok = loadMap(']]..filename..[[')
        if ok then
        local wc = mmp.lockWormholes()
	    local ws = mmp.lockSewers()
        mmp.lockPebble()
        if mmp.game == &quot;achaea&quot; and wc == 0 and ws == 0 then -- in achaea, using crowdmap, if we didn't get any special exits - it means Mudlet needs to be updated
          mmp.echo(&quot;Sorry, it seems your Mudlet isn't compatible with the new crowdmap format - and the map cannot be loaded fully. Please update your Mudlet:\n  http://www.mudlet.org/download/&quot;)
          return
        end

        if mmp.settings.waterwalk then mmp.enableWaterWalk() else mmp.disableWaterWalk() end

        mmp.echo(&quot;Map loaded successfully!&quot;)

          tmp = getRoomUserData(1, &quot;gotoMapping&quot;)
          local newmaptable = {}
          if tmp ~= &quot;&quot; then
            newmaptable = yajl.to_value(tmp)
          end
          for k,v in pairs(oldmaptable) do newmaptable[k] = v end
          setRoomUserData(1, &quot;gotoMapping&quot;, yajl.to_string(newmaptable))
          mmp.echo(&quot;Marks from the old map migrated successfully.&quot;)
          raiseEvent(&quot;mmapper updated map&quot;)
        else mmp.echo(&quot;Nope, didn't work. Open the map and try again?&quot;) end
      ]],
      &quot;Click here to try loading the map again&quot;)
      echo(&quot; to try loading it in again.\n&quot;)
    end

  elseif filename == tostring(mmp.downloadedscript) then   -- new mapper script xml downloaded
	mmp.checkingupdates = false

    mmp.echo(&quot;Your mapper script was downloaded to '&quot;..filename..&quot;' - uninstall the current copy and install the new one now!&quot;)

  elseif filename == tostring(mmp.mapfile) then   -- map version #, either IRE's or crowd
	mmp.checkingupdates = false

    local function needupdate(currentmd5, oldmd5)
      if not mmp.settings.crowdmap then
        mmp.echon(&quot;The games map was &quot;)
        echoLink(&quot;updated&quot;, '', &quot;New MD5: &quot;..tostring(currentmd5)..&quot;, previous MD5: &quot;..(oldmd5 or &quot;(none)&quot;), true)
        echo(&quot; - you should update yours! Go to Settings -&gt; Mapper tab and click on the button there. Once you've updated, &quot;)
        echoLink(&quot;click here&quot;, &quot;mmp.updatedmap('&quot;..currentmd5..&quot;')&quot;, &quot;Click here to quiet the update reminder&quot;)
        echo(&quot; to remove the reminder.&quot;)
      else
        mmp.newversion, mmp.oldversion = currentmd5, oldmd5
        mmp.retrievecrowdchangelog()
      end
    end

    local f, s = io.open(filename)
    if f then s = f:read(&quot;*a&quot;); io.close(f) end
    local currentmd5 = string.match(s, &quot;([a-z0-9]+)  map%.xml&quot;)

    -- using crowdsourced map
    if not currentmd5 then
      currentmd5 = s:trim()
    end

	os.remove(filename)

    -- never checked yet?
    if not io.exists(getMudletHomeDir()..&quot;/map downloads/current&quot;) then needupdate(currentmd5) return end

    -- otherwise read old file and check
    local f, s = io.open(getMudletHomeDir()..&quot;/map downloads/current&quot;)
    if f then s = f:read(&quot;*a&quot;); io.close(f) end

    if s ~= currentmd5 then needupdate(currentmd5, s) end
  end
end</script>
                    <eventHandlerList>
                        <string>sysDownloadDone</string>
                    </eventHandlerList>
                </Script>
                <Script isActive="yes" isFolder="no">
                    <name>Check for updates</name>
                    <packageName></packageName>
                    <script>local downloadfolder = getMudletHomeDir()..&quot;/map downloads/&quot;
local whereisit

-- this should get called at start and every hour after that
function mmp.checkforupdate()
  if not mmp.game or mmp.checkingupdates then return end

  local game = (mmp.game == &quot;mko&quot;) and &quot;midkemiaonline&quot; or mmp.game
  mmp.mapfile = downloadfolder..&quot;MD5&quot;
  mmp.mapperfile = downloadfolder..&quot;mapper&quot;

  if not downloadFile then
    mmp.echo(&quot;Your version of Mudlet doesn't support downloading files - please upgrade to 2.0+&quot;)
  else
    if not lfs.attributes(downloadfolder) then
      if lfs and lfs.mkdir then
         local t,s = lfs.mkdir(downloadfolder)
         if not t and s ~= &quot;File exists&quot; then mmp.echo(&quot;Couldn't make the '&quot;..downloadfolder..&quot;' folder; &quot;..s) return end
      else
        mmp.echo(&quot;Sorry, but you need LuaFileSystem (lfs) installed, or have the '&quot;..downloadfolder..&quot;' folder exist.&quot;)
        return
      end
    end

    if mmp.settings.crowdmap and mmp.game and mmp.game == &quot;achaea&quot; then
      downloadFile(mmp.mapfile, &quot;http://ire-mudlet-mapping.github.io/AchaeaCrowdmap/Map/version.txt&quot;)
    elseif mmp.settings.updatemap then
      downloadFile(mmp.mapfile, &quot;http://www.&quot;..game..&quot;.com/maps/MD5SUM&quot;)
    end

    downloadFile(mmp.mapperfile, &quot;http://ire-mudlet-mapping.github.io/ire-mapping-script/downloads/version&quot;)
	mmp.checkingupdates = true
  end
end

-- called by the user when the map is updated to register the fact that it was
function mmp.updatedmap(currentmd5)
  assert(currentmd5, &quot;need md5 sum to write to file&quot;)

  local f,err = io.open(downloadfolder..&quot;current&quot;, &quot;w&quot;)
  if not f then return mmp.echo(&quot;Couldn't write to the update file, because: &quot;..err) end
  f:write(currentmd5)
  f:close()

  local t = {&quot;Go you for updating!&quot;, &quot;Thanks for updating the map!&quot;, &quot;Alright, map updated!&quot;}
  mmp.echo(t[math.random(1, #t)])
end

-- downloads the latest changelog for the mapper if it was updated
function mmp.retrievechangelog()
  mmp.changelogfile = downloadfolder..&quot;changelog&quot;

  downloadFile(mmp.changelogfile, &quot;http://ire-mudlet-mapping.github.io/ire-mapping-script/downloads/changelog&quot;)
end

function mmp.retrievecrowdchangelog()
  mmp.crowdchangelogfile = downloadfolder..&quot;crowdchangelogfile&quot;

  downloadFile(mmp.crowdchangelogfile, &quot;http://ire-mudlet-mapping.github.io/AchaeaCrowdmap/Map/changelog.txt&quot;)
end

-- downloads the public crowdsources map!
function mmp.downloadmapperscript()
  local downloadlocationfile = downloadfolder..&quot;savepath&quot;
  local downloadlocation
  local exists = lfs.attributes

  -- somewhat complicated thing to nicely deal with all scenarios.
  if not exists(downloadlocationfile) then
    downloadlocation = whereisit()
    if not downloadlocation then return end
  end

  if not downloadlocation then
    local f, s = io.open(downloadlocationfile)
    if f then downloadlocation = f:read(&quot;*a&quot;); io.close(f) end


    if not exists(downloadlocation) then
      downloadlocation = whereisit()
      if not downloadlocation or not exists(downloadlocation) then return end
    end
  end


  mmp.downloadedscript = downloadlocation..&quot;/mudlet-mapper.xml&quot;
  downloadFile(mmp.downloadedscript, &quot;http://ire-mudlet-mapping.github.io/ire-mapping-script/downloads/mudlet-mapper.xml&quot;)

  local f,err = io.open(downloadlocationfile, &quot;w&quot;)
  if not f then return mmp.echo(&quot;Couldn't write to the location file, because: &quot;..err) end
  f:write(downloadlocation)
  f:close()
  mmp.echo(&quot;Okay, downloading the mapper script...&quot;)
end

function mmp.downloadcrowdmap(newversion)
  mmp.crowdmapfile = downloadfolder..&quot;crowdmap&quot;

  local f,err = io.open(downloadfolder..&quot;current&quot;, &quot;w&quot;)
  if not f then return mmp.echo(&quot;Couldn't write to the update file, because: &quot;..err) end
  f:write(newversion)
  f:close()


  downloadFile(mmp.crowdmapfile, &quot;http://ire-mudlet-mapping.github.io/AchaeaCrowdmap/Map/map&quot;)

  mmp.echo(&quot;Downloading the latest crowdmap...&quot;)
end

function mmp.showcrowdchangelog()
  mmp.echo(&quot;Public map changelog:&quot;)

  if not mmp.crowdchangelog then mmp.echo(&quot;(none yet)&quot;) return end

  for k,v in ipairs(mmp.crowdchangelog) do
    cecho(string.format(&quot;  %s) %s\n&quot;, k,v:gsub(&quot;\t&quot;, &quot;     &quot;)))
  end
end

whereisit = function()
  local path = invokeFileDialog(false, &quot;Where should we save the file? Select a folder and click Open&quot;)

  if path == &quot;&quot; then return nil else return path end
end</script>
                    <eventHandlerList/>
                    <Script isActive="yes" isFolder="no">
                        <name>mmp_checkupdatestart</name>
                        <packageName></packageName>
                        <script>function mmp_checkupdatestart(...)
  if mmp.checkforupdatetimer then killTimer(mmp.checkforupdatetimer) end
  mmp.checkforupdatetimer = tempTimer(math.random(3, 10), mmp.checkforupdate)
end

function mmp.changeUpdateMap()
  if mmp.settings.updatemap then
    mmp.echo(&quot;Will check for new map updates from your MUD.&quot;)
    enableTimer&quot;Check for updates periodically&quot;
    mmp_checkupdatestart()
  else
    mmp.echo(&quot;Won't check for new map updates from your MUD.&quot;)
    disableTimer&quot;Check for updates periodically&quot;
	if mmp.checkforupdatetimer then killTimer(&quot;mmp.checkforupdatetimer&quot;) end
  end
end</script>
                        <eventHandlerList>
                            <string>mmp logged in</string>
                        </eventHandlerList>
                    </Script>
                </Script>
                <Script isActive="no" isFolder="no">
                    <name>mmp_see_dl_errors</name>
                    <packageName></packageName>
                    <script>-- this should be off by default
function mmp_see_dl_errors(...)
  display{...}
end</script>
                    <eventHandlerList>
                        <string>sysDownloadError</string>
                    </eventHandlerList>
                </Script>
            </ScriptGroup>
            <Script isActive="yes" isFolder="no">
                <name>Initialize</name>
                <packageName></packageName>
                <script>mmp.startup()</script>
                <eventHandlerList/>
                <Script isActive="yes" isFolder="no">
                    <name>mmp.mapdata_changed</name>
                    <packageName></packageName>
                    <script>-- aggregates map load and such events into one
function mmp.mapdata_changed()
  raiseEvent(&quot;mmapper map reloaded&quot;)
end</script>
                    <eventHandlerList>
                        <string>sysMapLoad</string>
                        <string>sys2DMapLoad</string>
                        <string>sys3DMapLoad</string>
                        <string>sysMapDownloadEvent</string>
                        <string>mapOpenEvent</string>
                    </eventHandlerList>
                </Script>
            </Script>
        </ScriptGroup>
    </ScriptPackage>
    <KeyPackage/>
    <HelpPackage>
        <helpURL></helpURL>
    </HelpPackage>
</MudletPackage>
