Finish getting GMCP working; Update module install/uninstall code to keep things cleaner and support uninstallation

This commit is contained in:
Matt Wagner 2021-06-04 12:48:43 -07:00
parent 874bdb0496
commit a621557b08
11 changed files with 164 additions and 73 deletions

View File

@ -46,9 +46,6 @@ Right above your input box, you'll see a bunch of useful information which updat
After creating a Mudlet profile to connect to LOTJ, do the following to add the package:
1. Open the Mudlet **Settings**.
1. On the **General** tab, check **Enable MSDP**
1. On the **Special Options** tab, check **Force compression off**
1. Download a release of this package (the `.mpackage` file) from the [releases page](https://github.com/rengawm/lotj-mudlet-ui/releases)
1. Open the **Package Manager**
1. If present, uninstall the **generic-mapper** package. It conflicts with the one provided here.

2
mfile
View File

@ -1,4 +1,4 @@
{
"package": "lotj-ui",
"version": "1.1"
"version": "2.0"
}

View File

@ -1,7 +1,7 @@
lotj = lotj or {}
lotj.chat = lotj.chat or {}
registerAnonymousEventHandler("lotjUICreated", function()
function lotj.chat.setup()
for keyword, contentsContainer in pairs(lotj.layout.lowerRightTabData.contents) do
lotj.chat[keyword] = Geyser.MiniConsole:new({
x = "1%", y = "1%",
@ -16,12 +16,12 @@ registerAnonymousEventHandler("lotjUICreated", function()
-- Set the wrap at a few characters short of the full width to avoid the scroll bar showing over text
local charsPerLine = lotj.chat[keyword]:getColumnCount()-3
lotj.chat[keyword]:setWrap(charsPerLine)
registerAnonymousEventHandler("sysWindowResizeEvent", function()
lotj.setup.registerEventHandler("sysWindowResizeEvent", function()
local charsPerLine = lotj.chat[keyword]:getColumnCount()-3
lotj.chat[keyword]:setWrap(charsPerLine)
end)
end
end)
end
function lotj.chat.routeMessage(type)
selectCurrentLine()

View File

@ -11,7 +11,7 @@ lotj.galaxyMap = lotj.galaxyMap or {
}
local dataFileName = getMudletHomeDir().."/galaxyMap"
registerAnonymousEventHandler("lotjUICreated", function()
function lotj.galaxyMap.setup()
lotj.galaxyMap.container = Geyser.Label:new({
name = "galaxy",
x = 0, y = 0,
@ -41,8 +41,8 @@ registerAnonymousEventHandler("lotjUICreated", function()
lotj.galaxyMap.drawSystems()
end
registerAnonymousEventHandler("gmcp.Ship.System.y", lotj.galaxyMap.setShipGalCoords)
end)
lotj.setup.registerEventHandler("gmcp.Ship.System", lotj.galaxyMap.setShipGalCoords)
end
function lotj.galaxyMap.log(text)
@ -50,6 +50,7 @@ function lotj.galaxyMap.log(text)
end
function lotj.galaxyMap.setShipGalCoords()
if not gmcp.Ship then return end
if gmcp.Ship.System.x ~= nil and gmcp.Ship.System.y ~= nil then
lotj.galaxyMap.currentX = gmcp.Ship.System.x
lotj.galaxyMap.currentY = gmcp.Ship.System.y

View File

@ -2,7 +2,7 @@ lotj = lotj or {}
lotj.infoPanel = lotj.infoPanel or {}
registerAnonymousEventHandler("lotjUICreated", function()
function lotj.infoPanel.setup()
local basicStatsContainer = Geyser.Label:new({
h_stretch_factor = 0.9
}, lotj.layout.lowerInfoPanel)
@ -15,12 +15,12 @@ registerAnonymousEventHandler("lotjUICreated", function()
local spaceContainer = Geyser.Label:new({
h_stretch_factor = 2.2
}, lotj.layout.lowerInfoPanel)
lotj.infoPanel.createBasicStats(basicStatsContainer)
lotj.infoPanel.createOpponentStats(combatContainer)
lotj.infoPanel.createChatInfo(chatContainer)
lotj.infoPanel.createSpaceStats(spaceContainer)
end)
end
-- Utility functions
@ -66,7 +66,7 @@ end
-- Wires up GMCP subscriptions for a gauge.
-- statName is the short version of the stat name to show after the value (mv, hp, etc)
local function wireGaugeUpdate(gauge, valueVarName, maxVarName, statName)
local function wireGaugeUpdate(gauge, valueVarName, maxVarName, statName, eventName)
local function doUpdate()
local current = gmcpVarByPath(valueVarName) or 0
local max = gmcpVarByPath(maxVarName) or 0
@ -76,8 +76,7 @@ local function wireGaugeUpdate(gauge, valueVarName, maxVarName, statName)
gauge:setValue(0, 1, "")
end
end
registerAnonymousEventHandler("gmcp."..valueVarName, doUpdate)
registerAnonymousEventHandler("gmcp."..maxVarName, doUpdate)
lotj.setup.registerEventHandler(eventName, doUpdate)
end
@ -90,7 +89,7 @@ function lotj.infoPanel.createBasicStats(container)
healthGauge.front:setStyleSheet(gaugeFrontStyle("#f04141", "#ef2929", "#cc0000", "#a40000", "#cc0000"))
healthGauge.back:setStyleSheet(gaugeBackStyle("#3f1111", "#3f0707", "#330000", "#220000", "#330000"))
styleGaugeText(healthGauge, 12)
wireGaugeUpdate(healthGauge, "Char.Stats.hp", "Char.Stats.maxHp", "hp")
wireGaugeUpdate(healthGauge, "Char.Vitals.hp", "Char.Vitals.maxHp", "hp", "gmcp.Char.Vitals")
local wimpyBar = Geyser.Label:new({
x=0, y=0,
@ -100,10 +99,10 @@ function lotj.infoPanel.createBasicStats(container)
background-color: yellow;
]])
registerAnonymousEventHandler("gmcp.Char.Stats.wimpy", function()
local health = gmcp.Char.Stats.hp
local healthMax = gmcp.Char.Stats.maxHp
local wimpy = gmcp.Char.Stats.wimpy
lotj.setup.registerEventHandler("gmcp.Char.Vitals", function()
local health = gmcp.Char.Vitals.hp
local healthMax = gmcp.Char.Vitals.maxHp
local wimpy = gmcp.Char.Vitals.wimpy
if healthMax > 0 then
if wimpy > 0 and health > 0 and wimpy < health then
wimpyBar:show()
@ -122,7 +121,7 @@ function lotj.infoPanel.createBasicStats(container)
movementGauge.front:setStyleSheet(gaugeFrontStyle("#41f041", "#29ef29", "#00cc00", "#00a400", "#00cc00"))
movementGauge.back:setStyleSheet(gaugeBackStyle("#113f11", "#073f07", "#003300", "#002200", "#003300"))
styleGaugeText(movementGauge, 12)
wireGaugeUpdate(movementGauge, "Char.Stats.move", "Char.Stats.maxMove", "mv")
wireGaugeUpdate(movementGauge, "Char.Vitals.move", "Char.Vitals.maxMove", "mv", "gmcp.Char.Vitals")
-- Mana gauge (will be hidden later if we do not have mana)
local manaGauge = Geyser.Gauge:new({
@ -132,10 +131,10 @@ function lotj.infoPanel.createBasicStats(container)
manaGauge.front:setStyleSheet(gaugeFrontStyle("#4141f0", "#2929ef", "#0000cc", "#0000a4", "#0000cc"))
manaGauge.back:setStyleSheet(gaugeBackStyle("#11113f", "#07073f", "#000033", "#000022", "#000011"))
styleGaugeText(manaGauge, 12)
wireGaugeUpdate(manaGauge, "Char.Stats.mana", "Char.stats.maxMana", "mn")
wireGaugeUpdate(manaGauge, "Char.Vitals.mana", "Char.Vitals.maxMana", "mn", "gmcp.Char.Vitals")
registerAnonymousEventHandler("gmcp.Char.Stats.maxMana", function()
local manaMax = gmcp.Char.Stats.maxMana or 0
lotj.setup.registerEventHandler("gmcp.Char.Vitals", function()
local manaMax = gmcp.Char.Vitals.maxMana or 0
if manaMax > 0 then
healthGauge:move(nil, 4)
healthGauge:resize(nil, 16)
@ -190,7 +189,7 @@ function lotj.infoPanel.createOpponentStats(container)
opponentGauge:setValue(0, 1, "Not fighting")
end
end
registerAnonymousEventHandler("gmcp.Char.Enemy", update)
lotj.setup.registerEventHandler("gmcp.Char.Enemy", update)
end
@ -217,7 +216,7 @@ function lotj.infoPanel.createChatInfo(container)
commnetInfo:echo(commChannel, nil, "l13")
end
end
registerAnonymousEventHandler("gmcp.Char.Chat", updateCommnet)
lotj.setup.registerEventHandler("gmcp.Char.Chat", updateCommnet)
-- OOC meter
local oocLabel = Geyser.Label:new({
@ -232,7 +231,7 @@ function lotj.infoPanel.createChatInfo(container)
oocGauge.front:setStyleSheet(gaugeFrontStyle("#31d0d0", "#22cfcf", "#00b2b2", "#009494", "#00b2b2"))
oocGauge.back:setStyleSheet(gaugeBackStyle("#113f3f", "#073f3f", "#003333", "#002222", "#001111"))
registerAnonymousEventHandler("gmcp.Char.Chat.oocLimit", function()
lotj.setup.registerEventHandler("gmcp.Char.Chat", function()
local oocLeft = gmcp.Char.Chat.oocLimit or 0
local oocMax = 6
oocGauge:setValue(oocLeft, oocMax)
@ -248,7 +247,7 @@ function lotj.infoPanel.createSpaceStats(container)
energyGauge.front:setStyleSheet(gaugeFrontStyle("#7a7a7a", "#777777", "#656565", "#505050", "#656565"))
energyGauge.back:setStyleSheet(gaugeBackStyle("#383838", "#303030", "#222222", "#151515", "#222222"))
styleGaugeText(energyGauge, 12)
wireGaugeUpdate(energyGauge, "Ship.Info.energy", "Ship.Info.maxEnergy", "en")
wireGaugeUpdate(energyGauge, "Ship.Info.energy", "Ship.Info.maxEnergy", "en", "gmcp.Ship.Info")
local hullGauge = Geyser.Gauge:new({
x="3%", y=23,
@ -257,7 +256,7 @@ function lotj.infoPanel.createSpaceStats(container)
hullGauge.front:setStyleSheet(gaugeFrontStyle("#bd7833", "#bd6e20", "#994c00", "#703800", "#994c00"))
hullGauge.back:setStyleSheet(gaugeBackStyle("#442511", "#441d08", "#331100", "#200900", "#331100"))
styleGaugeText(hullGauge, 12)
wireGaugeUpdate(hullGauge, "Ship.Info.hull", "Ship.Info.maxHull", "hl")
wireGaugeUpdate(hullGauge, "Ship.Info.hull", "Ship.Info.maxHull", "hl", "gmcp.Ship.Info")
local shieldGauge = Geyser.Gauge:new({
x="3%", y=42,
@ -266,7 +265,7 @@ function lotj.infoPanel.createSpaceStats(container)
shieldGauge.front:setStyleSheet(gaugeFrontStyle("#31d0d0", "#22cfcf", "#00b2b2", "#009494", "#00b2b2"))
shieldGauge.back:setStyleSheet(gaugeBackStyle("#113f3f", "#073f3f", "#003333", "#002222", "#001111"))
styleGaugeText(shieldGauge, 12)
wireGaugeUpdate(shieldGauge, "Ship.Info.shield", "Ship.Info.maxShield", "sh")
wireGaugeUpdate(shieldGauge, "Ship.Info.shield", "Ship.Info.maxShield", "sh", "gmcp.Ship.Info")
-- Piloting indicator
@ -285,8 +284,8 @@ function lotj.infoPanel.createSpaceStats(container)
width=16, height=16
}, pilotBoxCont)
registerAnonymousEventHandler("gmcp.Ship.Base.piloting", function()
if gmcp.Ship.Base.piloting then
lotj.setup.registerEventHandler("gmcp.Ship.Info", function()
if gmcp.Ship and gmcp.Ship.Info.piloting then
pilotBox:setStyleSheet("background-color: #29efef; border: 2px solid #eeeeee;")
else
pilotBox:setStyleSheet("background-color: #073f3f; border: 2px solid #eeeeee;")
@ -300,25 +299,33 @@ function lotj.infoPanel.createSpaceStats(container)
}, container)
local function updateSpeed()
local speed = gmcp.Ship.Base.speed or 0
local maxSpeed = gmcp.Ship.Base.maxSpeed or 0
speedGauge:echo("<b>Sp:</b> "..speed.."<b>/</b>"..maxSpeed, nil, "l12")
if not gmcp.Ship or not gmcp.Ship.Info or not gmcp.Ship.Info.maxSpeed then
speedGauge:echo("<b>Sp:</b> N/A", nil, "l12")
else
local speed = gmcp.Ship.Info.speed or 0
local maxSpeed = gmcp.Ship.Info.maxSpeed or 0
speedGauge:echo("<b>Sp:</b> "..speed.."<b>/</b>"..maxSpeed, nil, "l12")
end
end
registerAnonymousEventHandler("gmcp.Ship.Base", updateSpeed)
lotj.setup.registerEventHandler("gmcp.Ship.Info", updateSpeed)
local coordsInfo = Geyser.Label:new({
x="35%", y=32,
width="40%", height=24,
}, container)
local function updateCoords()
local shipX = gmcp.Ship.Base.posX or 0
local shipY = gmcp.Ship.Base.posY or 0
local shipZ = gmcp.Ship.Base.posZ or 0
coordsInfo:echo("<b>Coords:</b> "..shipX.." "..shipY.." "..shipZ, nil, "l12")
if not gmcp.Ship or not gmcp.Ship.Info or not gmcp.Ship.Info.posX then
coordsInfo:echo("<b>Coords:</b> N/A", nil, "l12")
else
local shipX = gmcp.Ship.Info.posX or 0
local shipY = gmcp.Ship.Info.posY or 0
local shipZ = gmcp.Ship.Info.posZ or 0
coordsInfo:echo("<b>Coords:</b> "..shipX.." "..shipY.." "..shipZ, nil, "l12")
end
end
registerAnonymousEventHandler("gmcp.Ship.Base", updateCoords)
lotj.setup.registerEventHandler("gmcp.Ship.Info", updateCoords)
lotj.infoPanel.spaceTickCounter = Geyser.Label:new({
x="77%", y=6,

View File

@ -35,7 +35,7 @@ local function createTabbedPanel(tabData, container, tabList)
}, container)
lotj.layout.resizeTabContents(container, tabContainer, contentsContainer)
registerAnonymousEventHandler("sysWindowResizeEvent", function()
lotj.setup.registerEventHandler("sysWindowResizeEvent", function()
lotj.layout.resizeTabContents(container, tabContainer, contentsContainer)
end)
@ -75,15 +75,16 @@ function lotj.layout.resizeTabContents(parentContainer, tabContainer, contentsCo
contentsContainer:resize(nil, newHeight)
end
function lotj.layout.setup()
if lotj.layout.drawn then return end
registerAnonymousEventHandler("sysLoadEvent", function()
local rightPanel = Geyser.Container:new({
lotj.layout.rightPanel = Geyser.Container:new({
width = rightPanelWidthPct.."%",
x = (100-rightPanelWidthPct).."%",
y = 0, height = "100%",
})
registerAnonymousEventHandler("sysWindowResizeEvent", function()
local newBorder = math.floor(rightPanel:get_width())
lotj.setup.registerEventHandler("sysWindowResizeEvent", function()
local newBorder = math.floor(lotj.layout.rightPanel:get_width())
if getBorderRight() ~= newBorder then
setBorderRight(newBorder)
end
@ -91,11 +92,11 @@ registerAnonymousEventHandler("sysLoadEvent", function()
-- Upper-right pane, for maps
local upperContainer = Geyser.Container:new({
lotj.layout.upperContainer = Geyser.Container:new({
x = 0, y = 0,
width = "100%",
height = upperRightHeightPct.."%",
}, rightPanel)
}, lotj.layout.rightPanel)
local upperTabList = {}
table.insert(upperTabList, {keyword = "map", label = "Map"})
@ -103,15 +104,15 @@ registerAnonymousEventHandler("sysLoadEvent", function()
table.insert(upperTabList, {keyword = "galaxy", label = "Galaxy"})
lotj.layout.upperRightTabData = {}
createTabbedPanel(lotj.layout.upperRightTabData, upperContainer, upperTabList)
createTabbedPanel(lotj.layout.upperRightTabData, lotj.layout.upperContainer, upperTabList)
-- Lower-right panel, for chat history
local lowerContainer = Geyser.Container:new({
lotj.layout.lowerContainer = Geyser.Container:new({
x = 0, y = upperRightHeightPct.."%",
width = "100%",
height = (100-upperRightHeightPct).."%",
}, rightPanel)
}, lotj.layout.rightPanel)
local lowerTabList = {}
table.insert(lowerTabList, {keyword = "all", label = "All"})
@ -122,7 +123,7 @@ registerAnonymousEventHandler("sysLoadEvent", function()
table.insert(lowerTabList, {keyword = "imm", label = "Imm"})
lotj.layout.lowerRightTabData = {}
createTabbedPanel(lotj.layout.lowerRightTabData, lowerContainer, lowerTabList)
createTabbedPanel(lotj.layout.lowerRightTabData, lotj.layout.lowerContainer, lowerTabList)
-- Lower info panel, for prompt hp/move gauges and other basic status
@ -132,9 +133,13 @@ registerAnonymousEventHandler("sysLoadEvent", function()
height = 60,
})
setBorderBottom(60)
end
raiseEvent("lotjUICreated")
lotj.layout.selectTab(lotj.layout.upperRightTabData, "map")
lotj.layout.selectTab(lotj.layout.lowerRightTabData, "all")
end)
function lotj.layout.teardown()
lotj.layout.rightPanel:hide()
lotj.layout.upperContainer:hide()
lotj.layout.lowerContainer:hide()
lotj.layout.lowerInfoPanel:hide()
setBorderRight(0)
setBorderBottom(0)
end

View File

@ -257,7 +257,7 @@ end
------------------------------------------------------------------------------
registerAnonymousEventHandler("lotjUICreated", function()
function lotj.mapper.setup()
lotj.mapper.mapperInstance = Geyser.Mapper:new({
x = 0, y = 0,
width = "100%",
@ -281,9 +281,9 @@ registerAnonymousEventHandler("lotjUICreated", function()
lotj.mapper.noAreasPrompt:echo("No map data.<br><br>Use <b>map help</b> to get started.", nil, "c14")
end
registerAnonymousEventHandler("sysDataSendRequest", "lotj.mapper.handleSentCommand")
registerAnonymousEventHandler("gmcp.Room.Info.vnum", "lotj.mapper.onEnterRoom")
end)
lotj.setup.registerEventHandler("sysDataSendRequest", lotj.mapper.handleSentCommand)
lotj.setup.registerEventHandler("gmcp.Room.Info", lotj.mapper.onEnterRoom)
end
-- Track the most recent movement command so we know which direction we moved when automapping

View File

@ -0,0 +1,5 @@
[
{
"name": "setup"
}
]

View File

@ -0,0 +1,67 @@
lotj = lotj or {}
lotj.setup = lotj.setup or {}
lotj.setup.eventHandlerKillIds = lotj.setup.eventHandlerKillIds or {}
lotj.setup.gmcpEventHandlerFuncs = lotj.setup.gmcpEventHandlerFuncs or {}
function lotj.setup.registerEventHandler(eventName, func)
local killId = registerAnonymousEventHandler(eventName, func)
table.insert(lotj.setup.eventHandlerKillIds, killId)
-- A little bit hacky, but we want to run all GMCP event handlers when we finish
-- doing initial setup to populate the UI.
if eventName:find("gmcp\.") then
table.insert(lotj.setup.gmcpEventHandlerFuncs, func)
end
end
local function setup()
-- Layout has to be created first
lotj.layout.setup()
-- Then everything else in no particular order
lotj.chat.setup()
lotj.galaxyMap.setup()
lotj.infoPanel.setup()
lotj.mapper.setup()
lotj.systemMap.setup()
-- Then set our UI default view
lotj.layout.selectTab(lotj.layout.upperRightTabData, "map")
lotj.layout.selectTab(lotj.layout.lowerRightTabData, "all")
-- Manually kick off all GMCP event handlers, since GMCP data would not have changed
-- since loading the UI.
for _, func in ipairs(lotj.setup.gmcpEventHandlerFuncs) do
func()
end
end
local function teardown()
for _, killId in ipairs(lotj.setup.eventHandlerKillIds) do
killAnonymousEventHandler(killId)
end
lotj.layout.teardown()
lotj = nil
end
lotj.setup.registerEventHandler("sysLoadEvent", function()
setup()
end)
lotj.setup.registerEventHandler("sysInstallPackage", function(_, pkgName)
if pkgName ~= "lotj-ui" then return end
sendGMCP("Core.Supports.Set", "[\"Ship 1\"]")
setup()
end)
lotj.setup.registerEventHandler("sysUninstallPackage", function(_, pkgName)
if pkgName ~= "lotj-ui" then return end
teardown()
end)
lotj.setup.registerEventHandler("sysProtocolEnabled", function(_, protocol)
if protocol == "GMCP" then
sendGMCP("Core.Supports.Set", "[\"Ship 1\"]")
end
end)

View File

@ -14,7 +14,7 @@ local controlButtonStyle = [[
border: 2px solid white;
]]
registerAnonymousEventHandler("lotjUICreated", function()
function lotj.systemMap.setup()
disableTrigger("system-map-radar")
local tabContents = lotj.layout.upperRightTabData.contents["system"]
@ -23,7 +23,7 @@ registerAnonymousEventHandler("lotjUICreated", function()
background-color: black;
]])
lotj.systemMap.resizeToSquare()
registerAnonymousEventHandler("sysWindowResizeEvent", lotj.systemMap.resizeToSquare)
lotj.setup.registerEventHandler("sysWindowResizeEvent", lotj.systemMap.resizeToSquare)
local zoomInButton = Geyser.Label:new({
x = "2%", y = 10,
@ -88,10 +88,10 @@ registerAnonymousEventHandler("lotjUICreated", function()
]])
end
positionRangeCircle()
registerAnonymousEventHandler("sysWindowResizeEvent", positionRangeCircle)
lotj.setup.registerEventHandler("sysWindowResizeEvent", positionRangeCircle)
registerAnonymousEventHandler("gmcp.Ship.Base", "lotj.systemMap.drawMap")
end)
lotj.setup.registerEventHandler("gmcp.Ship.Info", lotj.systemMap.drawMap)
end
function lotj.systemMap.resetItems()
lotj.systemMap.radarItems = {}
@ -113,13 +113,13 @@ function lotj.systemMap.drawMap()
end
-- We use ship max speed as a proxy for "do we have ship data at all"
if gmcp.Ship.Base.maxSpeed == nil then
if not gmcp.Ship or not gmcp.Ship.Info or gmcp.Ship.Info.maxSpeed == nil then
return
end
local shipX = gmcp.Ship.Base.posX
local shipY = gmcp.Ship.Base.posY
local shipZ = gmcp.Ship.Base.posZ
local shipX = gmcp.Ship.Info.posX
local shipY = gmcp.Ship.Info.posY
local shipZ = gmcp.Ship.Info.posZ
local selfData = {name="You", x=shipX, y=shipY, z=shipZ}
local itemsToDraw = {}

View File

@ -13,7 +13,16 @@ end
line = line:gsub("%(UFG%)", "")
line = line:gsub(" +", ";")
local _, _, planet, system, gov, support = line:find("([^;]+);([^;]+);([^;]+);([^;]+)")
local startIdx, _, planet, system, gov, support = line:find("([^;]+);([^;]+);([^;]+);([^;]+)")
if not startIdx then
gov = "None"
startIdx, _, planet, system, support = line:find("([^;]+);([^;]+);([^;]+)")
end
if not startIdx then
echo("\n")
lotj.galaxyMap.log("Bad planet line: "..matches[2])
return
end
if planet ~= "Planet" then
lotj.galaxyMap.recordPlanet({