-- =========================================================================== -- Novidades (cliente) - janela com o que mudou na ultima atualizacao (pedido do dono em 21/10/2026) -- -- Abre quando o servidor manda NV_Abrir (uma vez por conta a cada versao, ou pelo /novidades) e pela tecla N. -- Fechar (Entendi, X ou Esc) manda NV_Visto com a versao: o servidor grava que a conta ja viu. -- O texto e a versao estao no Config.lua desta pasta. Estilo dos paineis do banco de joias e da lixeira (UX). -- Rolagem (pedido do dono, 22/10/2026): o texto cresce ate AREA_MAX; passando disso aparece a barra do banco de -- joias e a roda do mouse rola o texto. -- =========================================================================== local CONFIG = require("Scripts\\Novidades\\Config") local IMG_PAINEL = 40043 -- Custom\Interface\UX_Novidades.tga (340 x 300, esticado na altura do texto) local IMG_FECHAR = 40044 -- Interface\mini_map_ui_cancel.tga: o X amarelo do inventario (2 estados) local IMG_BOTAO = 31326 -- botao vazio do jogo (108 x 87, 3 estados de 29) local IMG_TRILHO_C, IMG_TRILHO_M, IMG_TRILHO_B, IMG_CURSOR = 40045, 40046, 40047, 40048 -- barra do banco de joias local K_N = 78 -- Util/KeysValue.lua local LARG, Y0, MARGEM = 340, 50, 18 local ALT_TITULO, ALT_LINHA, ESPACO_ITEM = 13, 12, 6 local AREA_MAX = 250 -- altura maxima do texto antes de precisar rolar local PASSO = 24 -- quanto a roda do mouse rola local NV = { Aberta = false, Areas = {}, Rolagem = 0 } Novidades = NV local function Pot2(n) local p = 1 while p < n do p = p * 2 end return p end local function Esticar(id, x, y, w, h, tw, th, recorte, v0) pcall(RenderImage2, id, x, y, w, h, 0, (v0 or 0) / Pot2(th), tw / Pot2(tw), (recorte or th) / Pot2(th), 1, 1, 1.0) end local function Dentro(a, x, y) return a and x >= a.x and x <= a.x + a.w and y >= a.y and y <= a.y + a.h end local function MouseEm(a) return Dentro(a, MousePosX(), MousePosY()) end local function Largura() return MO_LarguraTela and MO_LarguraTela() or (GetWideX() + 320) end -- Scripts/Comum/Tela.lua local function CentroX() return math.floor(Largura() / 2) end -- o texto em linhas, cada uma com a sua altura e a sua cor. { data = "22/10" } na lista e o cabecalho de um patch -- (pedido do dono em 24/10/2026: Novidades do mes separadas por data) local ALT_DATA, ESPACO_DATA = 15, 6 local function Linhas() local L = {} for _, it in ipairs(CONFIG.Itens) do if it.data then if #L > 0 then L[#L + 1] = { alt = ESPACO_DATA } end L[#L + 1] = { txt = it.data, alt = ALT_DATA, data = true } else L[#L + 1] = { txt = it[1], alt = ALT_TITULO, titulo = true } for i = 2, #it do L[#L + 1] = { txt = it[i], alt = ALT_LINHA } end L[#L + 1] = { alt = ESPACO_ITEM } end end return L end local function Abrir() NV.Aberta = true; NV.Rolagem = 0 end local function Fechar() if not NV.Aberta then return end NV.Aberta = false pcall(function() CreatePacket("NV_Visto", 1) SetDwordPacket("NV_Visto", CONFIG.Versao) SendPacket("NV_Visto") ClearPacket("NV_Visto") end) end ------------------------------------------------------------------------------- -- Pacote do servidor ------------------------------------------------------------------------------- local function Protocolo(head, nome) if nome ~= "NV_Abrir" then return nil end pcall(ClearPacket, nome) Abrir() return true end ProtocolFunctions.ClientProtocol(Protocolo) ------------------------------------------------------------------------------- -- Desenho (a cada quadro) ------------------------------------------------------------------------------- function Novidades_Desenhar() NV.Areas = {} if MO_EsconderNomes then MO_EsconderNomes("novidades", NV.Aberta) end -- nomes do jogo por cima da janela if not NV.Aberta then return end local L = Linhas() local total = 0 for _, l in ipairs(L) do total = total + l.alt end local area = math.min(total, AREA_MAX) NV.Max = math.max(0, total - area) NV.Rolagem = math.max(0, math.min(NV.Rolagem, NV.Max)) local h = 36 + area + 16 + 30 + 8 -- nunca fora da tela: na tela do Guilherme (22/10/2026, sem print) a janela saiu torta. A largura vem do -- Scripts/Comum/Tela.lua, medida no log de producao em 22/10/2026 (1280 na wide, 640 na 4:3). local x = CentroX() - math.floor(LARG / 2) x = math.max(4, math.min(x, Largura() - LARG - 4)) local y = Y0 NV.Areas.janela = { x = x, y = y, w = LARG, h = h } Esticar(IMG_PAINEL, x, y, LARG, h, 340, 300) SetFontType(1); SetTextBg(0, 0, 0, 0) SetTextColor(255, 189, 25, 255) RenderText5(x, y + 12, CONFIG.Titulo, LARG, 3) -- X no canto de cima, a direita (mesmo recorte do banco de joias) local ft = 17 local fx, fy = x + LARG - ft - 6, y + 6 NV.Areas.fechar = { x = fx, y = fy, w = ft, h = ft } pcall(RenderImage2, IMG_FECHAR, fx, fy, ft, ft, 6 / 64, ((MouseEm(NV.Areas.fechar) and 29 or 0) + 2) / 64, 25 / 64, 25 / 64, 1, 1, 1.0) -- texto: so as linhas que cabem inteiras na area, a partir da rolagem local topo = y + 36 local larg_txt = LARG - 2 * MARGEM - (NV.Max > 0 and 12 or 0) local ty = topo - NV.Rolagem for _, l in ipairs(L) do if l.txt and ty >= topo and ty + l.alt <= topo + area then if l.data then -- cabecalho do patch: a data, laranja e centralizada SetTextColor(255, 130, 40, 255) RenderText5(x + MARGEM, ty + 1, l.txt, larg_txt, 3) else if l.titulo then SetTextColor(255, 189, 25, 255) else SetTextColor(225, 225, 225, 255) end RenderText5(x + MARGEM, ty, l.txt, larg_txt, 1) end end ty = ty + l.alt end NV.Areas.texto = { x = x, y = topo, w = LARG, h = area } -- barra de rolagem (a do banco de joias) if NV.Max > 0 then local tx, tyb = x + LARG - MARGEM, topo Esticar(IMG_TRILHO_C, tx, tyb, 7, 3, 7, 3) Esticar(IMG_TRILHO_M, tx, tyb + 3, 7, area - 6, 7, 15) Esticar(IMG_TRILHO_B, tx, tyb + area - 3, 7, 3, 7, 3) local cy = tyb + math.floor((area - 30) * NV.Rolagem / NV.Max) Esticar(IMG_CURSOR, tx - 4, cy, 15, 30, 15, 30) end SetTextColor(160, 160, 160, 255) RenderText5(x, topo + area + 4, CONFIG.Rodape, LARG, 3) local bw, bh = 100, 22 local b = { x = x + math.floor((LARG - bw) / 2), y = y + h - bh - 10, w = bw, h = bh } NV.Areas.entendi = b Esticar(IMG_BOTAO, b.x, b.y, bw, bh, 108, 87, 29, MouseEm(b) and 29 or 0) SetTextColor(255, 255, 255, 255) RenderText5(b.x, b.y + math.floor(bh / 2) - 5, CONFIG.Botao, bw, 3) end ------------------------------------------------------------------------------- -- Mouse e teclado ------------------------------------------------------------------------------- function Novidades_Mouse() if not NV.Aberta or CheckReleasedKey(Keys.LButton) ~= 1 then return end local x, y = MousePosX(), MousePosY() if Dentro(NV.Areas.entendi, x, y) or Dentro(NV.Areas.fechar, x, y) then Fechar() end end function Novidades_Rolar(valor) if not NV.Aberta or not MouseEm(NV.Areas.janela) then return end local v = tonumber(valor) or 0 if v > 0 then NV.Rolagem = NV.Rolagem - PASSO elseif v < 0 then NV.Rolagem = NV.Rolagem + PASSO end end function Novidades_Teclas() if NV.Aberta then if MouseEm(NV.Areas.janela) then DisableClickClient() end if CheckPressedKey(Keys.Escape) == 1 then Fechar() end end end -- Tecla N: abre e fecha (nada com o chat aberto, as teclas sao letras) function Novidades_Tecla(key) if key ~= K_N or CheckWindowOpen(UIChatWindow) == 1 then return end if NV.Aberta then Fechar() else Abrir() end end function Novidades_Carregar() pcall(LoadBitmap, "Custom\\Interface\\UX_Novidades.tga", IMG_PAINEL) pcall(LoadBitmap, "Interface\\mini_map_ui_cancel.tga", IMG_FECHAR) pcall(LoadBitmap, "Interface\\newui_scrollbar_up.tga", IMG_TRILHO_C) pcall(LoadBitmap, "Interface\\newui_scrollbar_m.tga", IMG_TRILHO_M) pcall(LoadBitmap, "Interface\\newui_scrollbar_down.tga", IMG_TRILHO_B) pcall(LoadBitmap, "Interface\\newui_scroll_on.tga", IMG_CURSOR) end BridgeFunctionAttach('MainLoader', 'Novidades_Carregar') BridgeFunctionAttach('MainInterfaceProcThread', 'Novidades_Desenhar') BridgeFunctionAttach('UpdateMouseEvent', 'Novidades_Mouse') BridgeFunctionAttach('UpdateKeyEvent', 'Novidades_Teclas') BridgeFunctionAttach('KeyboardEvent', 'Novidades_Tecla') BridgeFunctionAttach('ScrollMouseEvent', 'Novidades_Rolar')