-- OT-MMO (31-oct): el HUD se adapta al tamaño de la ventana. Dos modos automáticos y una regla de anchura: -- · NORMAL: barras de 46 px, minimapa grande, chat de 400 x 170. -- · COMPACTO (ventana baja o estrecha: menos de 800 de alto o de 1280 de ancho, en píxeles del juego; en Chrome con -- Windows al 150 % un monitor de 1920 x 1200 da unos 1280 x 630): barras de 40 px sin título, la barra 2 plegada -- tras un botón, minimapa y chat más pequeños, consejos abajo a la derecha y como mucho dos avisos. -- · ANCHA (solo en NORMAL, desde 1580 de ancho): las dos barras de atajos van lado a lado en vez de apiladas (el chat -- se estrecha lo justo para no quedar debajo; el micromenú cabe a la derecha). -- Con histéresis (se entra en un umbral y se sale 40 px más allá) para que no parpadee al redimensionar, y con una -- espera corta: arrastrar el borde de la ventana da muchos cambios de tamaño seguidos y solo cuenta el último. -- Cada módulo coloca lo suyo: OtmmoHud.alCambiar('clave', fn) llama fn(estado) ahora y tras cada cambio de tamaño (con la -- misma clave se reemplaza: recargar un módulo no duplica su oyente). -- «Más > Interfaz» fija el modo a mano (g_settings «otmmo-hud-modo»: auto, normal o compacto). OtmmoHud = { modo = 'normal', ancha = false } local COMPACTO_ALTO, COMPACTO_ANCHO = 800, 1280 -- por debajo de cualquiera de los dos: compacto local ANCHA_DESDE = 1580 -- barras lado a lado (2 x 468 + 4) con chat de 300 y micromenú de 298 local HISTERESIS = 40 local ESPERA_MS = 150 local oyentes = {} local evento = nil function OtmmoHud.preferencia() local p = g_settings.getString('otmmo-hud-modo', 'auto') if p ~= 'normal' and p ~= 'compacto' then p = 'auto' end return p end function OtmmoHud.calcular(ancho, alto, previo) previo = previo or OtmmoHud local modo = OtmmoHud.preferencia() if modo == 'auto' then local h = previo.modo == 'compacto' and HISTERESIS or 0 -- para volver a NORMAL hay que pasar el umbral + 40 modo = (alto < COMPACTO_ALTO + h or ancho < COMPACTO_ANCHO + h) and 'compacto' or 'normal' end local ancha = false if modo == 'normal' then ancha = ancho >= ANCHA_DESDE - (previo.ancha and HISTERESIS or 0) end return { modo = modo, ancha = ancha, compacto = modo == 'compacto', ancho = ancho, alto = alto } end function OtmmoHud.estado() return { modo = OtmmoHud.modo, ancha = OtmmoHud.ancha, compacto = OtmmoHud.modo == 'compacto', ancho = rootWidget:getWidth(), alto = rootWidget:getHeight() } end local function avisar() local e = OtmmoHud.estado() for _, o in ipairs(oyentes) do local ok, err = pcall(o.fn, e) if not ok then g_logger.error('OtmmoHud: ' .. tostring(err)) end end end -- Recalcula; avisa solo si cambió el modo o la regla de anchura (salvo forzar). function OtmmoHud.revisar(forzar) local e = OtmmoHud.calcular(rootWidget:getWidth(), rootWidget:getHeight()) if not forzar and e.modo == OtmmoHud.modo and e.ancha == OtmmoHud.ancha then return end OtmmoHud.modo, OtmmoHud.ancha = e.modo, e.ancha avisar() end function OtmmoHud.fijar(pref) g_settings.set('otmmo-hud-modo', pref) OtmmoHud.revisar(true) end function OtmmoHud.alCambiar(clave, fn) local nuevo = true for _, o in ipairs(oyentes) do if o.clave == clave then o.fn, nuevo = fn, false end end if nuevo then table.insert(oyentes, { clave = clave, fn = fn }) end local ok, err = pcall(fn, OtmmoHud.estado()) if not ok then g_logger.error('OtmmoHud: ' .. tostring(err)) end end function OtmmoHud.quitar(clave) for i, o in ipairs(oyentes) do if o.clave == clave then table.remove(oyentes, i) return end end end pcall(function() -- al cargar corelib puede que aún no haya ajustes ni tamaño: el primer cambio de tamaño lo corrige local e = OtmmoHud.calcular(rootWidget:getWidth(), rootWidget:getHeight()) OtmmoHud.modo, OtmmoHud.ancha = e.modo, e.ancha end) connect(rootWidget, { onGeometryChange = function() removeEvent(evento) -- se avisa en cada cambio de tamaño (ya agrupado): algunas medidas dependen del ancho, no solo del modo evento = scheduleEvent(function() evento = nil OtmmoHud.revisar(true) end, ESPERA_MS) end, })