diff --git a/MapWindow.plugin/libraries/ppi.lua b/MapWindow.plugin/libraries/ppi.lua index 6359028..adb88bd 100755 --- a/MapWindow.plugin/libraries/ppi.lua +++ b/MapWindow.plugin/libraries/ppi.lua @@ -1,14 +1,25 @@ -- Semantic versioning: http://semver.org/ -local __V_MAJOR, __V_MINOR, __V_PATCH = 1, 2, 4 +local __V_MAJOR, __V_MINOR, __V_PATCH = 1, 3, 0 local __VERSION = string.format("%d.%d.%d", __V_MAJOR, __V_MINOR, __V_PATCH) -- The module table's variable -local PPI +local PPI = { + -- Version identifiers + __V = __VERSION, + __V_MAJOR = __V_MAJOR, + __V_MINOR = __V_MINOR, + __V_PATCH = __V_PATCH, + + -- More added later in the file +} -- Contains a list of PPI proxies to other plugins. -- Also contains private data for each PPI. local PPI_list = {} +-- Loader callbacks (added in v1.3.0) +local loaders = {} + -- Local data for this plugin's PPI local myID = GetPluginID() local myPPI = {} @@ -274,65 +285,78 @@ local PPI_meta = { end, } --- The returned module table. --- Declared (local) at the top of the file. -PPI = { - -- Version identifiers - __V = __VERSION, - __V_MAJOR = __V_MAJOR, - __V_MINOR = __V_MINOR, - __V_PATCH = __V_PATCH, + +-- Given a value during execution of callbacks +PPI.CallerID = nil + +-- Used to retreive a PPI for a specified plugin. +PPI.Load = function(id) + -- Is the plugin installed? + if not IsPluginInstalled(id) then + return nil, "not_installed" + -- Is the plugin enabled? + elseif not GetPluginInfo(id, 17) then + return nil, "not_enabled" + -- Does the plugin support PPI invocations? + elseif PluginSupports(id, invoke_msg) ~= 0 then + return nil, "no_ppi" + end - -- Given a value during execution of callbacks - CallerID = nil, - - - -- Used to retreive a PPI for a specified plugin. - Load = function(id) - -- Is the plugin installed? - if not IsPluginInstalled(id) then - return nil, "not_installed" - -- Is the plugin enabled? - elseif not GetPluginInfo(id, 17) then - return nil, "not_enabled" - -- Does the plugin support PPI invocations? - elseif PluginSupports(id, invoke_msg) ~= 0 then - return nil, "no_ppi" - end - - -- Get the PPI record - local tbl = PPI_list[id] - local reloaded = true - - -- Create one if there isn't one yet - if not tbl then - tbl = { - ppi = setmetatable({}, PPI_meta), - id = id, - thunks = {}, - nonce = GetPluginInfo(id, 22), - } - - PPI_list[id] = tbl - PPI_list[tbl.ppi] = id - -- If there is one, reload it if the plugin's nonce has changed. - elseif tbl.nonce ~= GetPluginInfo(id, 22) then - tbl.nonce = GetPluginInfo(id, 22) - tbl.thunks = {} - else - reloaded = false - end + -- Get the PPI record + local tbl = PPI_list[id] + local reloaded = true + + -- Create one if there isn't one yet + if not tbl then + tbl = { + ppi = setmetatable({}, PPI_meta), + id = id, + thunks = {}, + nonce = GetPluginInfo(id, 22), + } - return tbl.ppi, reloaded - end, + PPI_list[id] = tbl + PPI_list[tbl.ppi] = id + -- If there is one, reload it if the plugin's nonce has changed. + elseif tbl.nonce ~= GetPluginInfo(id, 22) then + tbl.nonce = GetPluginInfo(id, 22) + tbl.thunks = {} + else + reloaded = false + end - -- Used by a plugin to expose methods to other plugins - -- through its own PPI. - Expose = function(name, data) - -- Add the data to the exposed PPI - myPPI[name] = data or _G[name] - end, -} + return tbl.ppi, reloaded +end + +-- Used by a plugin to expose methods to other plugins +-- through its own PPI. +PPI.Expose = function(name, data) + -- Add the data to the exposed PPI + myPPI[name] = data or _G[name] +end + +PPI.OnLoad = function(id, on_success, on_failure) + loaders[id] = { + success=on_success, + failure=on_failure, + } +end + +PPI.Refresh = function() + for id, callbacks in pairs(loaders) do + local iface, is_reloaded = PPI.Load(id) + if not iface then + if callbacks.failure then + callbacks.failure(is_reloaded) + end + elseif is_reloaded then + if callbacks.success then + callbacks.success(iface) + end + end + end +end + -- PPI invocation resolver _G[invoke_msg] = function(id) @@ -387,4 +411,4 @@ end -- Return the module table -return PPI \ No newline at end of file +return PPI diff --git a/MapWindow.plugin/plugin.xml b/MapWindow.plugin/plugin.xml index 0af731e..bff0d73 100755 --- a/MapWindow.plugin/plugin.xml +++ b/MapWindow.plugin/plugin.xml @@ -1,53 +1,53 @@ - - - - - - --> Sets the MAP radius, which affects the mapwindow size. --> MAP WIDTH and MAP HEIGHT also work as expected. - -MAP MOVE --> Displays the current map-window location - -MAP MOVE --> Positions the map window in a specific location on the screen. --> 0 0 is the top-left corner. - -MAP FONTSIZE --> Sets the size each symbol takes up. --> Default is 10. Is not yet saved between sessions. - -MAP PARSE --> Updates the map with MAP, gagging the output. --> You shouldn't need to use this yourself unless you --> don't have the ATCP plugin installed. - -]]> - - - - - - - + + + + + + +-> Sets the MAP radius, which affects the mapwindow size. +-> MAP WIDTH and MAP HEIGHT also work as expected. + +MAP MOVE +-> Displays the current map-window location + +MAP MOVE +-> Positions the map window in a specific location on the screen. +-> 0 0 is the top-left corner. + +MAP FONTSIZE +-> Sets the size each symbol takes up. +-> Default is 10. Is not yet saved between sessions. + +MAP PARSE +-> Updates the map with MAP, gagging the output. +-> You shouldn't need to use this yourself unless you +-> don't have the ATCP plugin installed. +]]> + + + + + + + \ No newline at end of file diff --git a/MapWindow.plugin/project.kpf b/MapWindow.plugin/project.kpf new file mode 100644 index 0000000..71d3f93 --- /dev/null +++ b/MapWindow.plugin/project.kpf @@ -0,0 +1,7 @@ + + + + + 1 + + diff --git a/MapWindow.plugin/readme.txt b/MapWindow.plugin/readme.txt new file mode 100644 index 0000000..a57e9c3 --- /dev/null +++ b/MapWindow.plugin/readme.txt @@ -0,0 +1,57 @@ +MapWindow.plugin, version 2.0.1 +By Soludra Ar'thela + ++--------------+ +| Requirements | ++--------------+ + +* MUSHclient v4.56 or higher +* GMCP plugin, by Soludra + ++--------------+ +| Installation | ++--------------+ + +1. In MUSHclient, File -> Plugins. +2. Click Add. +3. Browse to the same directory as this readme.txt +4. Select 'plugin.xml' and click Open. + +If using alongside compass.plugin and gauges.plugin in their original positions: +5. Use the alias "MAP MOVE 0 152". This should position the map just below the + gauges. +6. Use MAP WIDTH 4 to make the map fit between the edge of the screen and the text. + ++-------+ +| Usage | ++-------+ + +This plugin takes the MAP output and creates a floating miniwindow with it. It +automatically updates itself as you move. + +Use MAP HELP to view the list of commands that can be used. + ++----------------------------+ +| Frequently Asked Questions | ++----------------------------+ + +1. The map doesn't appear/update! +A. The plugin may not be enabled. Go to File -> Plugins and make sure it's + enabled. + + You may also be in an area where there is no map; you should use MAP yourself + to check. + + In some cases - after death, or after passing through unmapped terrain, for + instance - the map may not update. You should use MAP once or twice manually. + This is a known issue. + + Please also see the Troubleshooting section for the GMCP plugin. + +2. Nothing's appearing on the screen, but I see my health falling! (or other + gagged-output issues) +A. In semi-rare cases, the MapWindow will gag everything in its path. This is a + known issue. You should use MAP once or twice to kick it back into gear. + + In general, if something strange happens regarding the map, using MAP once + or twice manually should, in most cases, get it working again. diff --git a/MapWindow.plugin/reflexes/map.lua b/MapWindow.plugin/reflexes/map.lua index dafebfd..60e94e7 100755 --- a/MapWindow.plugin/reflexes/map.lua +++ b/MapWindow.plugin/reflexes/map.lua @@ -1,153 +1,149 @@ -local alias = require("reflex").alias -local trigger = require("reflex").trigger - - -trigger { - match = [[^(?:You are packed much too tightly into the earth to do that\.|You are asleep and can do nothing\. WAKE will attempt to wake you\.|Please await your next instruction\.)$]], - enabled = false, - regexp = true, - group = "fail", - - omit_from_log = true, - omit_from_output = true, - - send_to = 14, - send = [[ - EnableGroup("mapbegin", false) - EnableTrigger("mapsize", false) - EnableGroup("fail", false) - - EnableTrigger("prompt", true) - ]], -} - -trigger["notmapped"] { - match = [[This room has not been mapped.]], - enabled = false, - group = "mapbegin", - - omit_from_log = true, - omit_from_output = true, - - send_to = 14, - send = [[ - EnableGroup("mapbegin", false) - EnableGroup("fail", false) - EnableTrigger("prompt", true) - - map:ClearGrid() - ]], -} - -trigger["arealine"] { - match = [[^\-+(?: Area (?:\d+): (?:.+?) )?\-+$]], - enabled = false, - regexp = true, - group = "mapbegin", - - omit_from_log = true, - omit_from_output = true, - - send_to = 14, - send = [[ - EnableGroup("mapbegin", false) - EnableGroup("fail", false) - EnableGroup("parsemap", true) - - grid = {} - ]], -} - -trigger["maprows"] { - match = [[^.*$]], - enabled = false, - regexp = true, - group = "parsemap", - - script = "ParseLine", - sequence = 101, - - omit_from_log = true, - omit_from_output = true, -} - -trigger["coordline"] { - match = [[^\-+(?: [A-Za-z'"-_ ]+ )?(?:\-+)?(?: -?\d+:-?\d+:-?\d+ )\-+$]], - enabled = false, - regexp = true, - group = "parsemap", - - omit_from_log = true, - omit_from_output = true, - - send_to = 14, - send = [[ - EnableGroup("parsemap", false) - EnableTrigger("prompt", true) - - map:ClearGrid() - map:DrawGrid(grid) - ]], -} - -trigger["prompt"] { - match = [[^(?:\(p\) )?(?:\d+h, )?(?:\d+m,? )?(?:\d+e,? )?(?:\d+w,? )?(?:\d{1,3}%,? )?c?e?x?k?d?b?@? ?(?:Vote)?-]], - enabled = false, - regexp = true, - - omit_from_log = true, - omit_from_output = true, - - send_to = 14, - send = [[ - EnableTrigger("prompt", false) - EnableGroup("begin", false) - - mapping = false - if not gagging then - gagging = true - GagOption(true) - end - ]], -} - -trigger { - match = [[^(?:Your map view is set to (\d) by (\d)\.|You cannot set the (?:radius|width|height) greater than 5\.|Usage:)$]], - enabled = false, - regexp = true, - group = "mapsize", - - send_to = 12, - send = [[ - EnableTrigger("mapsize", false) - EnableGroup("fail", false) - - if tonumber("%1") and tonumber("%2") then - map:MapSize(tonumber("%1"), tonumber("%2")) - Execute("map parse") - end - ]], -} - - - -alias { - match = [[^\s*MAP(?:\s+(.+?))?\s*$]], - regexp = true, - - ignore_case = true, - - script = "MapAlias", -} - -alias { - match = [[\s*map\s+help\s*$]], - regexp = true, - - ignore_case = true, - - send_to = 12, - send = [[ - Note(GetPluginInfo(GetPluginID(), 3)) - ]], +local alias = require("reflex").alias +local trigger = require("reflex").trigger + + +trigger { + match = [[^(?:You are packed much too tightly into the earth to do that\.|You are asleep and can do nothing\. WAKE will attempt to wake you\.|Please await your next instruction\.)$]], + enabled = false, + regexp = true, + group = "fail", + + omit_from_log = true, + omit_from_output = true, + + send_to = 14, + send = [[ + EnableGroup("mapbegin", false) + EnableTrigger("mapsize", false) + EnableGroup("fail", false) + + --EnableTrigger("prompt", true) + ]], +} + +trigger["notmapped"] { + match = [[This room has not been mapped.]], + enabled = false, + group = "mapbegin", + + omit_from_log = true, + omit_from_output = true, + + send_to = 14, + send = [[ + EnableGroup("mapbegin", false) + EnableGroup("fail", false) + --EnableTrigger("prompt", true) + + map:ClearGrid() + ]], +} + +trigger["arealine"] { + match = [[^\-+ Area (?:\d+): (?:.+?) \-+$]], + enabled = true, + regexp = true, + group = "mapbegin", + + omit_from_log = true, + omit_from_output = true, + + send_to = 14, + send = [[ + EnableGroup("mapbegin", false) + EnableGroup("fail", false) + EnableGroup("parsemap", true) + --print("arealine") + grid = {} + ]], +} +trigger["arealine2"] { + match = [[^\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-$]], + enabled = true, + regexp = true, + group = "mapbegin", + + omit_from_log = true, + omit_from_output = true, + + send_to = 14, + send = [[ + EnableGroup("mapbegin", false) + EnableGroup("fail", false) + EnableGroup("parsemap", true) + --print("arealine") + grid = {} + ]], +} + +trigger["maprows"] { + match = [[^.*$]], + enabled = false, + regexp = true, + group = "parsemap", + + script = "ParseLine", + sequence = 101, + + + omit_from_log = true, + omit_from_output = true, +} + +trigger["coordline"] { + match = [[^\-+(?:[A-Za-z'"\-_&, ]+ )?(?:\-+)? -?\d+:-?\d+:-?\d+ \-+$]], + enabled = true, + regexp = true, + group = "parsemap", + + sequence = 100, + omit_from_log = true, + omit_from_output = true, + + send_to = 14, + send = [[ + --print("coordline") + EnableGroup("parsemap", false) + --EnableGroup("mapbegin", true) + --EnableTrigger("prompt", true) + map:ClearGrid() + map:DrawGrid(grid) + ]], +} + +trigger { + match = [[^(?:Your map view is set to (\d) by (\d)\.|You cannot set the (?:radius|width|height) greater than 5\.|Usage:)$]], + enabled = false, + regexp = true, + group = "mapsize", + + send_to = 12, + send = [[ + EnableTrigger("mapsize", false) + EnableGroup("fail", false) + + if tonumber("%1") and tonumber("%2") then + map:MapSize(tonumber("%1"), tonumber("%2")) + Execute("map parse") + end + ]], +} + + + +alias { + match = [[^\s*map(?:\s+(.+?))?\s*$]], + regexp = true, + + script = "MapAlias", +} + +alias { + match = [[^\s*map\s+help\s*$]], + regexp = true, + + send_to = 12, + send = [[ + Note(GetPluginInfo(GetPluginID(), 3)) + ]], } \ No newline at end of file diff --git a/MapWindow.plugin/scripts/main.lua b/MapWindow.plugin/scripts/main.lua index acdfd6c..b63c10a 100755 --- a/MapWindow.plugin/scripts/main.lua +++ b/MapWindow.plugin/scripts/main.lua @@ -1,11 +1,10 @@ +-- Used to load the ATCP/GMCP interface +local PPI = require("ppi") + -- Simple window class used by the map Window = require("scripts.window") --- Used to load the ATCP interface -PPI = require("libraries.ppi") - --- Will contain the ATCP interface -atcp = nil +--require "gmcphelper" -- translate MAP markers @@ -29,22 +28,25 @@ roomcolor = {["@"] = 0xFFFFFF, -- white -- otherwise, one or more MAPs wouldn't be gagged mapping = false --- current room num -current_room = nil - -- tells the ending trigger whether to re-enable gagging -- This allows MAP to be parsed but still be shown, but -- MAP PARSE to be parsed without being shown gagging = true +-- Executed when you get a GMCP message! OnPluginInstall = function() + print("installing mapwindow plugin") local x = GetVariable("x") or 0 local y = GetVariable("y") or 0 local width = GetVariable("width") or 5 local height = GetVariable("height") or 5 map = Window.new(GetPluginID(), x, y, width, height) + --[[PPI.OnLoad("29a4c0721bef6ae11c3e9a82", function(gmcp) + print("registering listener") + gmcp.Listen("Redirect.Window", OnChangedRoom) + end)]] end OnPluginSaveState = function() @@ -54,26 +56,51 @@ OnPluginSaveState = function() SetVariable("height", map.height) end +-- (ID, on_success, on_failure) +PPI.OnLoad("29a4c0721bef6ae11c3e9a82", function(gmcp) + gmcp.Listen("Redirect.Window", OnChangedRoom) + end, + function(reason) + Note("GMCP interface unavailable: ", reason) +end) --- Executed when you get an ATCP message! -OnRoomNum = function(message, content) - local next_room = tonumber(content) - if current_room ~= next_room then - current_room = next_room - Execute("map parse") +--Listen("Room.Info", OnChangedRoom) +--testGMCP() +OnChangedRoom = function(message, content) + --print("room changed") + if content==nil then + return end + window_redirect = content + if window_redirect=="map" then + if mapping then + return + end + mapping = true + grid={} + + --EnableGroup("parsemap", true) + --print("enabling mapbegin") + EnableGroup("mapbegin", true) + elseif window_redirect=="main" then + mapping=false + EnableGroup("mapbegin",false) + --EnableGroup("parsemap", false) + EnableTrigger("coordline", true) + EnableTrigger("prompt",true) + map:ClearGrid() + map:DrawGrid(grid) + end + --SendNoEcho("map") end --- Loads the ATCP library +-- (ID, on_success, on_failure) +PPI.OnLoad("7c08e2961c5e20e5bdbf7fc5", function(atcp) + atcp.Listen("Room.Num", OnChangedRoom) +end) + OnPluginListChanged = function() - local atcp, reloaded = PPI.Load("7c08e2961c5e20e5bdbf7fc5") - if not atcp then - -- Doesn't really matter - it won't do anything - elseif reloaded then - -- Registers a function to call when Client.Compose is received. - atcp.Listen("Room.Num", OnRoomNum) - _G.atcp = atcp - end + PPI.Refresh() end GagOption = function(bool) @@ -81,7 +108,7 @@ GagOption = function(bool) local names = { "notmapped", "maprows", - "coordline", "prompt", + "coordline", "arealine" , "fail", } @@ -111,7 +138,7 @@ commands = { Note("Current location: (" .. map.x .. ", " .. map.y .. ")") end, ["^move%s+(%d+)%s+(%d+)$"] = function(line, x, y) - map:MoveWindow(tonumber(y), tonumber(y)) + map:MoveWindow(tonumber(x), tonumber(y)) end, ["^fontsize$"] = function(line) Note("Current font size: " .. map.fontsize) @@ -120,14 +147,6 @@ commands = { map:FontSize(tonumber(size)) end, ["^parse$"] = function(line) - if mapping then - return - end - mapping = true - - EnableGroup("mapbegin", true) - EnableGroup("fail", true) - SendNoEcho("map") end, ["^$"] = function(line) @@ -194,5 +213,20 @@ ParseLine = function(name, line, matches, styles) table.insert(grid, row) end +GagLines=function() + DeleteLines(1) +end + +function OnPlugin_IAC_GA() + --EnableTrigger("prompt", false) + EnableGroup("mapbegin", true) + EnableGroup("parsemap",false) + + mapping = false + if not gagging then + gagging = true + GagOption(true) + end +end require("reflexes.map") \ No newline at end of file