-- OT-MMO: mercado de Refugio. Solo muestra y pide: el servidor (server/scripts/mercado/mercado.lua) -- guarda el objeto en custodia, cobra, entrega y liquida. Opcode extendido 104: -- «L|oro|o1~o2~...» oferta: id^itemId^cantidad^precio^vendedor^nombre^mia^horasRestantes -- «M|m1~m2~...» mochila: clave^itemId^cantidad^nombre -- El cliente envía «V|clave|itemId|cantidad|precio», «C|oferta» y «R|oferta». local OPCODE = 104 local COMISION = 5 mercadoController = Controller:new() local ventana = nil local ofertas = {} local mochila = {} local elegido = nil local function enviar(texto) local protocol = g_game.getProtocolGame() if protocol then protocol:sendExtendedOpcode(OPCODE, texto) end end local function mostrarOfertas() if not ventana then return end local filtro = ventana.buscar:getText():lower() local lista = ventana.lista lista:destroyChildren() local n = 0 for _, o in ipairs(ofertas) do if filtro == '' or o.nombre:lower():find(filtro, 1, true) then n = n + 1 local fila = g_ui.createWidget('FilaOferta', lista) fila.icono:setItemId(o.item) fila.icono:setItemCount(o.cantidad) fila.nombre:setText(o.nombre) local unidad = o.cantidad > 1 and string.format(' · %d c/u', math.floor(o.precio / o.cantidad)) or '' fila.info:setText(string.format('x%d · %s · %d h%s', o.cantidad, o.mia and 'tuya' or o.vendedor, o.horas, unidad)) fila.precio:setText(string.format('%d oro', o.precio)) if o.mia then fila.accion:setText('Retirar') fila.accion.onClick = function() enviar('R|' .. o.id) end else fila.accion:setText('Comprar') fila.accion:setEnabled(o.precio <= ventana.oroTotal) fila.accion.onClick = function() enviar('C|' .. o.id) end end end end ventana.vacio:setVisible(n == 0) ventana.vacio:setText(#ofertas == 0 and 'Nadie vende nada todavía.' or 'Nada coincide con la búsqueda.') end function calcular() if not ventana then return end local precio = tonumber(ventana.vender.precio:getText()) local cantidad = tonumber(ventana.vender.cantidad:getText()) local ok = elegido and precio and precio >= 1 and cantidad and cantidad >= 1 and cantidad <= elegido.cantidad ventana.vender.publicar:setEnabled(ok and true or false) if not elegido then ventana.vender.recibes:setText('Elige un objeto de tu mochila.') elseif precio and precio >= 1 then ventana.vender.recibes:setText(string.format('Recibes %d de oro al venderse.', precio - math.floor(precio * COMISION / 100))) else ventana.vender.recibes:setText(elegido.nombre) end end local function mostrarMochila() local lista = ventana.vender.mochila lista:destroyChildren() local previo = elegido elegido = nil local foco = nil for _, m in ipairs(mochila) do local fila = g_ui.createWidget('FilaMochila', lista) fila.icono:setItemId(m.item) fila.icono:setItemCount(m.cantidad) fila.nombre:setText(m.nombre) fila.onFocusChange = function(w, focused) if focused then elegido = m ventana.vender.cantidad:setText(tostring(m.cantidad)) calcular() end end if previo and previo.item == m.item and previo.nombre == m.nombre then foco = fila end end if foco then lista:focusChild(foco, KeyboardFocusReason) end calcular() end local function abrir() if not ventana then ventana = g_ui.displayUI('mercado') OtmmoVentanas.recordar(ventana, 'mercado') -- posición entre sesiones (fase 4) end ventana:show() ventana:raise() end local function onOpcode(protocol, opcode, buffer) local partes = buffer:split('|') if partes[1] == 'L' then abrir() ventana.oroTotal = tonumber(partes[2]) or 0 ventana.oro:setText(string.format('Tu oro: %d', ventana.oroTotal)) ofertas = {} for _, fila in ipairs((partes[3] or ''):split('~')) do local f = fila:split('^') if #f >= 8 then ofertas[#ofertas + 1] = { id = tonumber(f[1]), item = tonumber(f[2]), cantidad = tonumber(f[3]), precio = tonumber(f[4]), vendedor = f[5], nombre = f[6], mia = f[7] == '1', horas = tonumber(f[8]) } end end mostrarOfertas() elseif partes[1] == 'M' and ventana then mochila = {} for _, fila in ipairs((partes[2] or ''):split('~')) do local f = fila:split('^') if #f >= 4 then mochila[#mochila + 1] = { clave = tonumber(f[1]), item = tonumber(f[2]), cantidad = tonumber(f[3]), nombre = f[4] } end end mostrarMochila() end end function filtrar() mostrarOfertas() end function publicar() local precio = tonumber(ventana.vender.precio:getText()) local cantidad = tonumber(ventana.vender.cantidad:getText()) if elegido and precio and cantidad then enviar(string.format('V|%d|%d|%d|%d', elegido.clave, elegido.item, cantidad, precio)) ventana.vender.precio:setText('') end end function cerrar() if ventana then ventana:hide() end end function mercadoController:onInit() ProtocolGame.registerExtendedOpcode(OPCODE, onOpcode) end function mercadoController:onTerminate() ProtocolGame.unregisterExtendedOpcode(OPCODE) if ventana then ventana:destroy() ventana = nil end end function mercadoController:onGameEnd() cerrar() end