-- group.info is request-only (never pushed), so this polls on a
-- timer. Solo -> group.info returns an empty/absent list -> panel
-- hides. In a group -> panel reappears and fills in member frames.
-- ============================================================
groupHUD = groupHUD or {}
-- ---- Reload-safe cleanup ----
if groupHUD.container then
groupHUD.container:hide()
groupHUD.container = nil
end
if groupHUD.infoHandlerID then killAnonymousEventHandler(groupHUD.infoHandlerID) end
if groupHUD.pollTimerID then killTimer(groupHUD.pollTimerID) end
-- ---- CONFIG ----
groupHUD.config = {
x = "76%", y = "26%", width = "22%", -- right side, beneath the vitals HUD
maxMembers = 6, -- fixed slot count; extra members beyond this won't show
rowHeight = 36, -- px per member row
pollSeconds = 3, -- how often to silently poll group.info
}
-- ---- Build window (starts hidden - shown only when grouped) ----
local totalHeight = 20 + (groupHUD.config.maxMembers * groupHUD.config.rowHeight)
groupHUD.container = Geyser.Container:new({
name = "groupHUD_container",
x = groupHUD.config.x, y = groupHUD.config.y,
width = groupHUD.config.width, height = totalHeight .. "px",
})
groupHUD.container:hide()
groupHUD.title = Geyser.Label:new({
name = "groupHUD_title", x = 0, y = 0, width = "100%", height = "20px",
}, groupHUD.container)
groupHUD.title:setStyleSheet("background-color: rgba(20,20,60,200); color:white; font-weight:bold;")
groupHUD.title:echo("Group")
-- ---- Build fixed member slots ----
groupHUD.slots = {}
for i = 1, groupHUD.config.maxMembers do
local rowY = 20 + (i - 1) * groupHUD.config.rowHeight
local nameLabel = Geyser.Label:new({
name = "groupHUD_name" .. i, x = 0, y = rowY .. "px", width = "100%", height = "18px",
}, groupHUD.container)
nameLabel:setStyleSheet("color:white; background: rgba(20,20,20,150);")
local hpGauge = Geyser.Gauge:new({
name = "groupHUD_hpGauge" .. i, x = 0, y = (rowY + 18) .. "px", width = "100%", height = "18px",
}, groupHUD.container)
hpGauge:setColor(200, 40, 40)
local hpLabel = Geyser.Label:new({
name = "groupHUD_hpLabel" .. i, x = 0, y = (rowY + 18) .. "px", width = "100%", height = "18px",
}, groupHUD.container)
hpLabel:setStyleSheet("color:white; background: transparent;")
groupHUD.slots[i] = { nameLabel = nameLabel, hpGauge = hpGauge, hpLabel = hpLabel }
nameLabel:hide()
hpGauge:hide()
hpLabel:hide()
end
-- ---- Update from group.info ----
function groupHUD.onGroupInfo()
local info = gmcp.group and gmcp.group.info
local members = info and info.groups
-- Filter out the player's own entry - their info is already on the
-- vitals HUD, no need to repeat it here.
local ownName = gmcp.char and gmcp.char.prompt and gmcp.char.prompt.n
local others = {}
if members then
for _, m in ipairs(members) do
if not ownName or (m.name ~= ownName and m.longName ~= ownName) then
table.insert(others, m)
end
end
end
if #others == 0 then
groupHUD.container:hide()
return
end
groupHUD.container:show()
for i = 1, groupHUD.config.maxMembers do
local slot = groupHUD.slots[i]
local m = others[i]
if m then
local rankSymbol = ""
if m.rank == "L" then rankSymbol = "[Leader] "
elseif m.rank == "f" then rankSymbol = "[Following] "
elseif m.rank == "2" then rankSymbol = "[Next] "
end
local nameColor = m.sameRoom and "white" or "grey"
slot.nameLabel:setStyleSheet("color:" .. nameColor .. "; background: rgba(20,20,20,150);")
slot.nameLabel:echo(rankSymbol .. tostring(m.longName or m.name))
if m.hp and m.maxHp then
slot.hpGauge:setValue(m.hp, m.maxHp)
slot.hpLabel:echo(string.format("HP: %s/%s Mana: %s/%s Move: %s/%s",
tostring(m.hp), tostring(m.maxHp),
tostring(m.mana), tostring(m.maxMana),
tostring(m.move), tostring(m.maxMove)))
end
slot.nameLabel:show()
slot.hpGauge:show()
slot.hpLabel:show()
else
slot.nameLabel:hide()
slot.hpGauge:hide()
slot.hpLabel:hide()
end
end
end
groupHUD.infoHandlerID = registerAnonymousEventHandler("gmcp.group.info", "groupHUD.onGroupInfo")
function groupHUD.poll()
sendGMCP("group.info")
end
groupHUD.pollTimerID = tempTimer(groupHUD.config.pollSeconds, groupHUD.poll, true)
-- ---- Initial check ----
groupHUD.poll()
cecho("<cyan>[GroupHUD] <white>Loaded. Hidden when solo, polling every " ..
groupHUD.config.pollSeconds .. "s while checking group status.\n")