Miniwindow plugin - map window for Aardwolf

Posted by Nick Gammon on Sun 27 Jul 2008 12:37 AM — 22 posts, 127,280 views.

Australia Forum Administrator #0
The plugin below illustrates using the new miniwindows concept in a plugin.

Miniwindows were released in version 4.34, see here for a copy:

http://www.gammon.com.au/forum/?id=8811

It draws the current map in the top RH corner of the output window.

To use, copy between the lines, and save as Aardwolf_Map.xml in your Plugins/Aardwolf directory, and then use File -> Plugins to install it.

It uses telnet negotation, so you also need this file:

http://www.gammon.com.au/mushclient/plugins/Aardwolf/telnet_options.lua


In a standard MUSHclient installation the plugin and telnet_options.lua should to into this directory:



C:\Program Files\MUSHclient\worlds\plugins\Aardwolf\




<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Saturday, June 30, 2007, 10:48  -->
<!-- MuClient version 4.13 -->

<muclient>
<plugin
   name="Aardwolf_Map_v2"
   author="Nick Gammon"
   id="86810b755a33169f0f1d9585"
   language="Lua"
   purpose="Redirects Aardwolf map messages to another pane"
   date_written="2008-07-18"
   requires="4.34"
   version="1.0"
   save_state="y"
   >
<description trim="y">
Redirects the map to a mini window.
</description>

</plugin>

<!--  Triggers  -->

<triggers>

  <trigger
   enabled="y"
   match="<MAPSTART>"
   script="map_redirect"
   omit_from_output="y"
   name="map_start"
   sequence="100"
  >
  </trigger>
  
  <trigger
   enabled="n"
   match="*"
   script="map_redirect"
   name="multi_line_map"
   omit_from_output="y"
   sequence="10"
  >
  </trigger>

  <trigger
   enabled="y"
   match="<MAPEND>"
   script="map_redirect"
   omit_from_output="y"
   name="map_end"
   sequence="5"
  >
  </trigger>
    
  <trigger
   enabled="y"
   match="You can now sense anger in your immediate area."
   sequence="100"
   send_to="12"
  >
  <send>SendNoEcho ("map")</send>
  </trigger>
  
  
</triggers>

<!--  Script  -->


<script>
<![CDATA[

background_colour = 0x00220E
title_colour = 0x696969
hyperlink_colour = 0x00FFFF

require "checkplugin"
require "commas"

map_lines = {}

function hyperlink_configure_background ()
  local new_colour = PickColour (background_colour)
  if new_colour ~= -1 then
    background_colour = new_colour
    Display_Map ()
  end -- new colour
   
end -- hyperlink_configure_background

function hyperlink_configure_title ()
  local new_colour = PickColour (title_colour)
  if new_colour ~= -1 then
    title_colour = new_colour
    Display_Map ()
  end -- new colour
   
end -- hyperlink_configure_title

function mousedown (flags, hotspotid)
  local f = hyperlink_functions [hotspotid]
  if f then
    f ()
  end -- function found
end -- mousedown

hyperlink_functions = {}

function make_hyperlink (text, id, left, top, action, hint)
local height = WindowFontInfo (win, font_id, 1)  
  
local right = left + WindowTextWidth (win, font_id, text)
local bottom = top + height

  WindowAddHotspot(win, id,  
                    left, top, right, bottom, 
                   "", -- mouseover
                   "", -- cancelmouseover
                   "mousedown",
                   "", -- cancelmousedown
                   "", -- mouseup
                   hint,                 
                   1, 0)
                   
  WindowText (win, font_id, text, left, top, right, bottom, hyperlink_colour)               
  hyperlink_functions [id] = action
      
  return right
            
end -- make_hyperlink       

function Display_Line (line, styles)
local id = font_id

-- first 2 lines in bold
if line < 3 then
  id = font_id_bold
end

local left = 10
local top =  (line - 1) * font_height + 5

  for _, v in ipairs (styles) do
    left = left + WindowText (win, id, v.text,
                             left, top, 0, 0, v.textcolour)
  end -- for each style run                 

end -- Display_Line

function Display_Map ()

  local width = max_width * font_width + 50
  local height = (#map_lines + 1) * font_height
  
   -- recreate the window the correct size
   check (WindowCreate (win, 
                 0, 0,   -- left, top (auto-positions)
                 width,     -- width
                 height,  -- height
                 6,       -- auto-position: top right
                 0,  -- flags
                 background_colour) )
                 
   -- DrawEdge rectangle
   check (WindowRectOp (win, 5, 0, 0, 0, 0, 10, 15))
   
  WindowDeleteAllHotspots (win)
     
   -- title rectangle
   check (WindowRectOp (win, 2, 2, 2, -2, font_height * 2 + 10, title_colour))
   check (WindowRectOp (win, 5, 2, 2, -2, font_height * 2 + 10, 5, 8))
 
   -- display each line        
   for i, v in ipairs (map_lines) do
      Display_Line (i, v)
   end -- for           
 
   make_hyperlink ("?", "back_colour", width - 15, height - 5 - font_height, 
                    hyperlink_configure_background, "Choose background colour")

   make_hyperlink ("?", "title_colour", width - 15, font_height + 5, 
                    hyperlink_configure_title, "Choose title colour")
                       
   -- show it now (or refresh)
   WindowShow (win, true)
                 
end -- Display_Map

-- map redirector
function map_redirect (name, line, wildcards, styles)
  EnableTrigger ("multi_line_map", true)  -- capture subsequent lines

  if name == "map_start" then
    map_lines = {}
    max_width = 0
  elseif name == "map_end" then
    EnableTrigger ("multi_line_map", false)  -- no more lines to go
    Display_Map ()
  else
--    local len = #(trim (line))
      local len = #line
 --   if len > 0 or #map_lines < 3 then
      table.insert (map_lines, styles)
      max_width = math.max (max_width, len)
 --   end -- if
  end -- if

end -- function map_redirect 

function OnPluginInstall ()

  win = GetPluginID ()

  font_name = "Dina"    -- the actual font
  font_id = "map_font"  -- our internal name
  font_id_bold = "map_font_bold"  -- our internal name

  -- make miniwindow so I can grab the font info
  check (WindowCreate (win, 
                 0, 0, 1, 1,  
                 6,   -- top right
                 0, 
                 background_colour) )

  check (WindowFont (win, font_id, font_name, 8, false, false, false, false, 0, 49))  -- normal
  check (WindowFont (win, font_id_bold, font_name, 8, true, false, false, false, 0, 49))   -- bold
  
  font_height = WindowFontInfo (win, font_id, 1)  -- height
  font_width = WindowFontInfo (win, font_id, 6)  -- avg width
  
  background_colour = tonumber (GetVariable ("background_colour")) or background_colour
  title_colour = tonumber (GetVariable ("title_colour")) or title_colour
  
  if GetVariable ("enabled") == "false" then
    ColourNote ("yellow", "", "Warning: Plugin " .. GetPluginName ().. " is currently disabled.")
    check (EnablePlugin(GetPluginID (), false))
    return
  end -- they didn't enable us last time
  
  OnPluginEnable ()  -- do initialization stuff
  
  
end -- OnPluginInstall

-- pull in telnet option handling
dofile (GetPluginInfo (GetPluginID (), 20) .. "telnet_options.lua")
  
function OnPluginConnect ()
  TelnetOptionOn (TELOPT_AUTOMAP)
  TelnetOptionOff (TELOPT_SHORTMAP)
  TelnetOptionOn (TELOPT_MAP)
  TelnetOptionOn (TELOPT_ROOM_NAMES)
  TelnetOptionOn (TELOPT_EXIT_NAMES)
  just_connected = true
end -- function OnPluginConnect

function OnPluginClose ()
  -- if enabled
  if GetPluginInfo (GetPluginID (), 17) then
    TelnetOptionOff (TELOPT_MAP)
    TelnetOptionOff (TELOPT_ROOM_NAMES)
    TelnetOptionOff (TELOPT_EXIT_NAMES)
  end -- if was enabled
end -- OnPluginClose

function OnPluginEnable ()
 
  -- if we are connected when the plugin loads, it must have been reloaded whilst playing
  if IsConnected () then
    OnPluginConnect ()
  end -- if already connected
  
end -- OnPluginEnable

function OnPluginDisable ()
  TelnetOptionOff (TELOPT_MAP)
  TelnetOptionOff (TELOPT_ROOM_NAMES)
  TelnetOptionOff (TELOPT_EXIT_NAMES)
  
  WindowShow (win, false)
  
end -- OnPluginDisable

function OnPluginSaveState ()
  SetVariable ("enabled", tostring (GetPluginInfo (GetPluginID (), 17)))
  SetVariable ("background_colour", background_colour)
  SetVariable ("title_colour", title_colour)
end -- OnPluginSaveState

]]>
</script>
</muclient>
Amended on Mon 28 Jul 2008 09:25 AM by Nick Gammon
Australia Forum Administrator #1

Example of it in operation:

USA Global Moderator #2
You should add Repaint() to the end of the display map function, imo.
Australia Forum Administrator #3
The last thing the drawing function does is:


WindowShow (win, true)


That causes the window to be redrawn the next time through the Windows event loop - that should cause it to be drawn almost immediately. I suppose the only time that wouldn't work is if you are walking quickly (because MUSHclient processes other TCP/IP events first), in which case adding your suggestion might make the map keep up a bit better.

To do that it should read:


-- show it now (or refresh)
WindowShow (win, true)
Repaint()


This is at the end of function Display_Map.
USA #4
Would it be possible to apply this to Achaea? Only problem is that several rooms in Achaea have the same room name but I think the room brief is different at least slightly for each... And you would have to add an exit for all possible modes of transportation, maybe conditional upon class. Like a serpent being able to WORM WARP and DASH, or someone with an artifact that allows them to do the same thing.
Something that gives the functionality of the zMapper would be a very long undertaking, I'm sure, if it's possible.
Amended on Fri 12 Mar 2010 03:47 AM by Kevnuke
USA #5
Nick just released a gemeral-use mapper module, and he also wrote a mapper for Achaea (which he probably pulled the module out of). I don't know the current status of the plugin, but the module will be in the next version of MUSHclient.

Also, the "room name" is the same thing as the "room brief". But every room has a unique ID, which is sent in the Room.Num ATCP message.
Amended on Fri 12 Mar 2010 04:08 AM by Twisol
Australia Forum Administrator #6
Template:post=10138
Please see the forum thread: http://gammon.com.au/forum/?id=10138.


The mapper I describe there is much more powerful, and I was testing it on Achaea too.

As soon as a few loose ends are tied up I will release the full mapper plugin for the IRE MUDs. The data format arriving from the MUD is a bit fluid right now.

They send room numbers as Twisol said, so there is no problem with identical room brief descriptions.

They are planning to make public their full map database, and indeed the demo in the other thread was generated from just that. It includes things like terrain info, area relationships, and so on. So just installing it and zooming out and you see a huge number of rooms.

I am waiting on their programmers to install the latest update on Achaea (it is already there on Imperian), and then the mapper should work fine on that. Initially you may have to discover your own rooms, but that is no great hardship.
Australia Forum Administrator #7
I should add too, that for Aardwolf users, I am working with Lasher to do a version for Aardwolf - I just need a bit more information from the MUD and it should be up shortly. He also is planning to release a full map database.
USA #8
Nick Gammon said:
It includes things like terrain info, area relationships, and so on.

Yyyyyyyesssssss!
USA #9
SWEETNESS!!
#10
Just by question, because I'm not familiar with how this plugin will work. Do you know if it will work with New Worlds Ateraan?
Australia Forum Administrator #11
The one on this page was designed for the way Aardwolf sends its maps, in particular, on request, it sends <MAPSTART> at the start of the map and <MAPEND> at the end. The plugin uses those to know where to capture the map.

You could adapt it for your MUD if you can identify something that always appears at the start of a map, and something that appears at the end (the thing at the end could be something that is *not* usually in the map, if that makes it simpler).
USA #12
Likely a stupid question, but is there a way to make the text coming from the mud wrap around the miniwindows? I tried setting the text to wrap at 75 lines in mush 4.51, but every couple of minutes it resets to wrap at 107 lines, and i've tried doing it multiple ways, to no avail.

Appreciate any feedback on this :)
Australia Forum Administrator #13
It shouldn't change the wrap size on its own. Something must be changing it back.

Anyway, see this page:

Template:post=10106
Please see the forum thread: http://gammon.com.au/forum/?id=10106.


Notice on the screenshot there the text box is much smaller and the map is on one side? Half-way down the page is the alias I used to do that. You can copy and paste that in, and then tweak the settings a bit to make the text part the size you want. You would just have to type that alias every time you started up, or go into the scripting tab and put "!makerect" (note the ! there) in the "on world open" box near the bottom. That makes that alias automatically execute when you open the world.
#14
Is there a way to make this work when the line at the start of the map is the same at the end? What I am trying to capture looks like this:

------------------------------------------------------------------------
      Compass           Auto-Map            Map Key
     ---------         ----------   -----------------------------
       |   |                        C: City, I: Inside, P: Plain
 |   | |   | |   |                  F: Forest, M: Mountain, H: Hills
 |  W| |{ }| |   |       IIX        S: Sky, W: Water, U: Underwater
 | SW| |   | |   |       III        $: Shop, #: Important, D: Desert
       | S |             III        ~: Shallow Water,  : Lava, X: You
------------------------------------------------------------------------
Australia Forum Administrator #15
I think there are other threads about more generic mappers. But yes, it should be possible to do that. After all, once you have the start line, you can disable the trigger that matches that, and enable one that matches the end line.
#16
So I pulled this down and tweaked the trigger to match the start and end of my map windows and it's working somewhat.

the first two lines of the display show portions of my map rather than the roominfo

Also it's not displaying the start and end lines of the map frame.

Also while Look and and move both display the same map with the same dimensions the map only catches the map when I do a look. when I do a move it only seems to rip my closing line of my map from the main screen. The one difference is on roommoves there is a colournote that is displayed before the map and seems to be breaking the trigger processing the map.

Below are the triggers I use and the map from the mud. Any help is greatly appreciated.


/---------------------\
|  |           | X |  |
|  |          ( )-( ) |
|  |           | X |  |
|  |          ( )-( ) |
|  |         / | X |  |
|  |      (*)-( )-( ) |
|  |       | X | X |  |
| ( )     (F)-( )-( ) |
|  |     /   X | X |  |
|-( )-(i)-( )-( )-( ) |
|  |   | \ | X | /    |
\---------------------/


<!--  Triggers  -->

<triggers>

  <trigger
   enabled="y"
   match="^/-{21}\$"
   script="map_redirect"
   omit_from_output="y"
   regexp="y"
   name="map_start"
   sequence="100"
  >
  </trigger>
  
  <trigger
   enabled="n"
   match="*"
   script="map_redirect"
   name="multi_line_map"
   omit_from_output="y"
   sequence="10"
  >
  </trigger>

  <trigger
   enabled="y"
   match="^\-{21}/$"
   script="map_redirect"
   omit_from_output="y"
   name="map_end"
   regexp="y"
   sequence="5"
  >
  </trigger>
    
   
</triggers>

Amended on Mon 31 Dec 2012 05:02 PM by CincyMush
USA Global Moderator #17
Quote:
the first two lines of the display show portions of my map rather than the roominfo

This is just a stylization in the plugin. You can remove the bit that goes


-- title rectangle
   check (WindowRectOp (win, 2, 2, 2, -2, font_height * 2 + 10, title_colour))
   check (WindowRectOp (win, 5, 2, 2, -2, font_height * 2 + 10, 5, 8))


Quote:
Also it's not displaying the start and end lines of the map frame.

That's because the plugin is set up to catch but not show elements that are merely indicators of the start and end of the map. It only shows the stuff between those indicators. You'd have to edit function map_redirect to look like this if you want to show them...


-- map redirector
function map_redirect (name, line, wildcards, styles)
   if name == "map_start" then
      EnableTrigger ("multi_line_map", true)  -- capture subsequent lines
      map_lines = {}
      max_width = 0
   end

   table.insert (map_lines, styles)
   max_width = math.max (max_width, #line)

   if name == "map_end" then
      EnableTrigger ("multi_line_map", false)  -- no more lines to go
      Display_Map ()
   end -- if

end -- function map_redirect 



Quote:
Also while Look and and move both display the same map with the same dimensions the map only catches the map when I do a look. when I do a move it only seems to rip my closing line of my map from the main screen. The one difference is on roommoves there is a colournote that is displayed before the map and seems to be breaking the trigger processing the map.

Then you'll need reconsider how your triggers work, I think.
Amended on Tue 01 Jan 2013 08:16 PM by Fiendish
#18
SO I fixed the issue with picking up the map as it displays on room switching by replacing the coulornotes with simulate so it does not mess with the parsing of map start lines. One final issue I am having is the * that represents my location on the map is showing up in black. In the mud ithas the * with a blinking white cursor so it's not an issue but in the mini window I have to change the background colour from black to grey, but it makes some of the colours look off from the game. Is there a way for me to grab the * and switch the colour?

Thanks
USA Global Moderator #19
Quote:
Is there a way for me to grab the * and switch the colour?

Of course.
#20
Hehe Well lots of digging through the forum helped me find something similar that Nick and Twisol did so I"ve figured it out. Thanks for all the Help
Amended on Sun 06 Jan 2013 04:09 AM by CincyMush
#21
hey guys.
i am trying to make simplest map on another mud (falloutmud.ca) but installing of plugin doesnot work. can you simplify for new users of mushclient how to make it works on another muds? very bid thanks in advance)