MessageSettings = { none = {}, consoleYellow = { color = TextColors.yellow, consoleTab = 'Local Chat' }, consoleRed = { color = TextColors.red, consoleTab = 'Local Chat' }, consoleOrange = { color = TextColors.orange, consoleTab = 'Local Chat' }, consoleBlue = { color = TextColors.blue, consoleTab = 'Local Chat' }, centerRed = { color = TextColors.red, consoleTab = 'Server Log', screenTarget = 'lowCenterLabel' }, centerGreen = { color = TextColors.green, consoleTab = 'Server Log', screenTarget = 'highCenterLabel', consoleOption = 'showInfoMessagesInConsole' }, centerHKGreen = { color = TextColors.green, consoleTab = 'Server Log', screenTarget = 'highCenterLabel', consoleOption = 'showHotkeyMessagesInConsole' }, centerWhite = { color = TextColors.white, consoleTab = 'Server Log', screenTarget = 'middleCenterLabel', consoleOption = 'showEventMessagesInConsole' }, bottomWhite = { color = TextColors.white, consoleTab = 'Server Log', screenTarget = 'statusLabel', consoleOption = 'showEventMessagesInConsole' }, status = { color = TextColors.white, consoleTab = 'Server Log', screenTarget = 'statusLabel', consoleOption = 'showStatusMessagesInConsole' }, statusOwn = { color = TextColors.white, consoleTab = 'Server Log', consoleOption = 'showStatusMessagesInConsole' }, statusBoosted = { color = TextColors.white, consoleTab = 'Server Log', screenTarget = 'statusLabel', consoleOption = 'showBoostedMessagesInConsole' }, othersStatus = { color = TextColors.white, consoleTab = 'Server Log', consoleOption = 'showOthersStatusMessagesInConsole' }, statusSmall = { color = TextColors.white, screenTarget = 'statusLabel' }, private = { color = TextColors.lightblue, consoleTab = 'Local Chat', screenTarget = 'privateLabel' }, privateRed = { color = TextColors.red, consoleTab = 'Local Chat', private = true }, privatePlayerToPlayer = { color = TextColors.blue, consoleTab = 'Local Chat', private = true }, privatePlayerToNpc = { color = TextColors.blue, consoleTab = 'Local Chat', private = true, npcChat = true }, privateNpcToPlayer = { color = TextColors.lightblue, consoleTab = 'Local Chat', private = true, npcChat = true }, channelYellow = { color = TextColors.yellow }, channelWhite = { color = TextColors.white }, channelRed = { color = TextColors.red }, channelOrange = { color = TextColors.orange }, monsterSay = { color = TextColors.orange, hideInConsole = true }, monsterYell = { color = TextColors.orange, hideInConsole = true }, potion = { color = TextColors.orange, hideInConsole = true }, loot = { color = TextColors.white, consoleTab = 'Loot', screenTarget = 'highCenterLabel', consoleOption = 'showInfoMessagesInConsole', colored = true }, valuableLoot = { color = TextColors.white, consoleTab = 'Loot', screenTarget = 'statusLabel', consoleOption = 'showInfoMessagesInConsole', colored = true } } MessageTypes = { [MessageModes.Say] = MessageSettings.consoleYellow, [MessageModes.Whisper] = MessageSettings.consoleYellow, [MessageModes.Yell] = MessageSettings.consoleYellow, [MessageModes.MonsterSay] = MessageSettings.monsterSay, [MessageModes.MonsterYell] = MessageSettings.monsterYell, [MessageModes.BarkLow] = MessageSettings.consoleOrange, [MessageModes.BarkLoud] = MessageSettings.consoleOrange, [MessageModes.Failure] = MessageSettings.statusSmall, [MessageModes.Login] = MessageSettings.bottomWhite, [MessageModes.Game] = MessageSettings.centerWhite, [MessageModes.Status] = MessageSettings.status, [MessageModes.Warning] = MessageSettings.centerRed, [MessageModes.Look] = MessageSettings.centerGreen, [MessageModes.Loot] = MessageSettings.loot, [MessageModes.Red] = MessageSettings.consoleRed, [MessageModes.Blue] = MessageSettings.consoleBlue, [MessageModes.PrivateFrom] = MessageSettings.private, [MessageModes.PrivateTo] = MessageSettings.privatePlayerToPlayer, [MessageModes.GamemasterPrivateFrom] = MessageSettings.privateRed, [MessageModes.NpcTo] = MessageSettings.privatePlayerToNpc, [MessageModes.NpcFrom] = MessageSettings.privateNpcToPlayer, [MessageModes.NpcFromStartBlock] = MessageSettings.privateNpcToPlayer, [MessageModes.Channel] = MessageSettings.channelYellow, [MessageModes.ChannelManagement] = MessageSettings.channelWhite, [MessageModes.GamemasterChannel] = MessageSettings.channelRed, [MessageModes.ChannelHighlight] = MessageSettings.channelOrange, [MessageModes.Spell] = MessageSettings.consoleYellow, [MessageModes.RVRChannel] = MessageSettings.channelWhite, [MessageModes.RVRContinue] = MessageSettings.consoleYellow, [MessageModes.GamemasterBroadcast] = MessageSettings.consoleRed, [MessageModes.DamageDealed] = MessageSettings.statusOwn, [MessageModes.DamageReceived] = MessageSettings.statusOwn, [MessageModes.Heal] = MessageSettings.statusOwn, [MessageModes.Exp] = MessageSettings.statusOwn, [MessageModes.DamageOthers] = MessageSettings.othersStatus, [MessageModes.HealOthers] = MessageSettings.othersStatus, [MessageModes.ExpOthers] = MessageSettings.othersStatus, [MessageModes.Potion] = MessageSettings.potion, [MessageModes.TradeNpc] = MessageSettings.centerGreen, [MessageModes.Guild] = MessageSettings.statusOwn, [MessageModes.Party] = MessageSettings.statusOwn, [MessageModes.PartyManagement] = MessageSettings.centerGreen, [MessageModes.TutorialHint] = MessageSettings.statusSmall, [MessageModes.BeyondLast] = MessageSettings.centerWhite, [MessageModes.Report] = MessageSettings.centerWhite, [MessageModes.GameHighlight] = MessageSettings.centerRed, [MessageModes.HotkeyUse] = MessageSettings.centerGreen, [MessageModes.Attention] = MessageSettings.bottomWhite, [MessageModes.BoostedCreature] = MessageSettings.centerWhite, [MessageModes.OfflineTrainning] = MessageSettings.centerWhite, [MessageModes.Transaction] = MessageSettings.centerWhite, [MessageModes.ValuableLoot] = MessageSettings.valuableLoot, [254] = MessageSettings.private } messagesPanel = nil function init() for messageMode, _ in pairs(MessageTypes) do registerMessageMode(messageMode, displayMessage) end connect(g_game, 'onGameEnd', clearMessages) messagesPanel = g_ui.loadUI('textmessage', modules.game_interface.getRootPanel()) end function terminate() for messageMode, _ in pairs(MessageTypes) do unregisterMessageMode(messageMode, displayMessage) end disconnect(g_game, 'onGameEnd', clearMessages) clearMessages() messagesPanel:destroy() messagesPanel = nil end function calculateVisibleTime(text) return math.max(#text * 50, 4000) end -- OT-MMO: Canary escribe sus mensajes en inglés. Se traducen aquí al recibirlos (patrón Lua -> texto), -- así no hay que tocar ni recompilar el servidor. El primero que coincide gana. -- ponytail: lista a mano de los mensajes que de verdad salen en el juego; se amplía cuando aparezca otro. local TRADUCCIONES = { { "^You have joined (.-)'s? party%. Open the party channel to communicate with your companions%.$", "Te uniste al grupo de %1. Abre el canal del grupo para hablar con tus compañeros." }, { "^(.-) has invited you to %a+ party %(Share range: (.-)%)%.$", "%1 te invitó a su grupo (experiencia compartida: %2)." }, { "^(.-) has invited you to %a+ party%.$", "%1 te invitó a su grupo." }, { "^(.-) has been invited to join the party.*$", "%1 fue invitado al grupo." }, { "^(.-) has been invited%..*$", "%1 fue invitado al grupo." }, { "^(.-) has joined the party%.$", "%1 se unió al grupo." }, { "^(.-) has left the party%.$", "%1 dejó el grupo." }, { "^You have left the party%.$", "Dejaste el grupo." }, { "^You are now the leader of the party%.$", "Ahora lideras el grupo." }, { "^(.-) is now the leader of the party%.$", "%1 ahora lidera el grupo." }, { "^Your party has been disbanded%.$", "El grupo se disolvió." }, { "^(.-) has revoked %a+ invitation%.$", "%1 retiró la invitación." }, { "^Target lost%.$", "Objetivo perdido." }, { "^You are exhausted%.$", "Estás agotado." }, { "^Sorry, not possible%.$", "No es posible." }, { "^Paid (%d+) gold from inventory%.$", "Pagas %1 de oro." }, { "^Paid (.-) from inventory and (.-) gold from bank account%..*$", "Pagas %1 de oro de la mochila y %2 del banco." }, { "^You do not have enough mana%.$", "No tienes suficiente maná." }, { "^There is not enough room%.$", "No hay espacio suficiente." }, { "^You are dead%.$", "Has muerto." }, { "^You may not logout during or immediately after a fight!$", "No puedes salir durante un combate o justo después." }, { "^You may not logout during a fight%.$", "No puedes salir durante un combate." }, { "^You advanced from Level (%d+) to Level (%d+)%.$", "Subiste del nivel %1 al nivel %2." }, { "^You were downgraded from Level (%d+) to Level (%d+)%.$", "Bajaste del nivel %1 al nivel %2." }, { "^You advanced to magic level (%d+)%.$", "Tu nivel mágico sube a %1." }, { "^You advanced to (.-) level (%d+)%.$", "Tu habilidad (%1) sube al nivel %2." }, { "^You lose (%d+) hitpoints? due to an attack by (.-)%.$", "Pierdes %1 de vida por un ataque de %2." }, { "^You lose (%d+) hitpoints?%.$", "Pierdes %1 de vida." }, { "^You lose (%d+) mana due to an attack by (.-)%.$", "Pierdes %1 de maná por un ataque de %2." }, { "^You lose (%d+) mana%.$", "Pierdes %1 de maná." }, { "^(.-) loses (%d+) hitpoints? due to your attack%.$", "%1 pierde %2 de vida por tu ataque." }, { "^(.-) loses (%d+) hitpoints? due to an attack by (.-)%.$", "%1 pierde %2 de vida por un ataque de %3." }, { "^You heal yourself for (%d+) hitpoints?%.$", "Te curas %1 de vida." }, { "^You heal (.-) for (%d+) hitpoints?%.$", "Curas a %1: %2 de vida." }, { "^You were healed by (.-) for (%d+) hitpoints?%.$", "%1 te cura %2 de vida." }, { "^You were healed for (%d+) hitpoints?%.$", "Recuperas %1 de vida." }, { "^You gained (%d+) experience points?%.$", "Ganas %1 de experiencia." }, { "^Loot of el (.-): nothing%.?$", "Botín del %1: nada." }, { "^Loot of el (.-): (.*)$", "Botín del %1: %2" }, { "^Loot of (.-): nothing%.?$", "Botín de %1: nada." }, { "^Loot of (.-): (.*)$", "Botín de %1: %2" }, { "^You see yourself%.(.*)$", "Te ves a ti mismo.%1" }, { "^This object is too heavy for you to carry%.$", "Pesa demasiado para que lo cargues." }, { "^You cannot carry more%..*$", "No puedes cargar más." }, { "^A player with this name is not online%.$", "Ese jugador no está conectado." }, { "^This action is not permitted in a protection zone%.$", "No se puede hacer en una zona protegida." }, { "^You may not attack this person%.$", "No puedes atacar a esa persona." }, { "^You cannot use this object%.$", "No puedes usar esto." }, { "^It is locked%.$", "Está cerrada con llave." }, { "^You can only use it on creatures%.$", "Elige un objetivo primero." }, { "^You need to equip a weapon to use this spell%.$", "Necesitas un arma equipada." }, { "^Please choose your outfit%.$", "Elige el aspecto de tu personaje." }, { "^You cannot use objects that are in a protection zone%.$", "No puedes usar objetos en una zona protegida." }, { "^Too far away%.$", "Está demasiado lejos." }, { "^First go upstairs%.$", "Primero sube." }, { "^First go downstairs%.$", "Primero baja." }, { "^You cannot throw there%.$", "No puedes lanzarlo ahí." }, { "^You can not use this object%.$", "No puedes usar esto." }, { "^This is impossible%.$", "Es imposible." }, { "^You are not the owner%.$", "No eres el dueño." }, { "^You see (.*)$", "Ves %1" }, } -- Trozos que aparecen dentro de otros mensajes (p. ej. el peso al mirar un objeto): se cambian todos. local TROZOS = { { "It weighs (.-) oz%.", "Pesa %1 oz." }, { "They weigh (.-) oz%.", "Pesan %1 oz." }, { "\nClassification: %d+ Tier: %d+[^\n]*", "" }, -- clases y niveles de la Forja de Tibia: no existen en OT-MMO { "\nImbuements: %b()%.", "" }, -- tampoco los imbuements { "^Today's boosted boss: .-$", "" }, { "^Today's boosted creature: .-$", "" }, -- Monedas y materiales (botín, mirar): items.xml conserva los nombres de Tibia porque los monstruos de Canary -- buscan su botín por nombre. Primero el plural con cantidad, luego el singular con artículo. { "(%d+) gold coins", "%1 monedas de oro" }, { "%f[%a]an? gold coin%f[%A]", "una moneda de oro" }, { "(%d+) minotaur leathers", "%1 cueros" }, { "%f[%a]an? minotaur leather%f[%A]", "un cuero" }, { "(%d+) iron ores", "%1 minerales de hierro" }, { "%f[%a]an? iron ore%f[%A]", "un mineral de hierro" }, { "(%d+) pieces of iron", "%1 lingotes de hierro" }, { "%f[%a]an? piece of iron%f[%A]", "un lingote de hierro" }, { "(%d+) star herbs", "%1 hierbas estrella" }, { "%f[%a]an? star herb%f[%A]", "una hierba estrella" }, { "(%d+) wooden stakes", "%1 mangos" }, { "%f[%a]an? wooden stake%f[%A]", "un mango" }, { "(%d+) bones%f[%A]", "%1 huesos" }, { "%f[%a]an? bone%f[%A]", "un hueso" }, { "(%d+) meat%f[%A]", "%1 trozos de carne" }, { "%f[%a]meat%f[%A]", "un trozo de carne" }, { "(%d+) wood%f[%A]", "%1 trozos de madera" }, { "%f[%a]wood%f[%A]", "un trozo de madera" }, { "(%d+) white pieces of cloth", "%1 telas" }, { "%f[%a]an? white piece of cloth%f[%A]", "una tela" }, } function traducirServidor(text) if type(text) ~= 'string' then return text end for _, par in ipairs(TROZOS) do text = text:gsub(par[1], par[2]) end for _, par in ipairs(TRADUCCIONES) do local nuevo, n = text:gsub(par[1], par[2]) if n > 0 then return nuevo end end return text end function displayMessage(mode, text) text = traducirServidor(text) if text == '' then -- OT-MMO: mensaje de un sistema de Tibia que no usamos (TROZOS lo vació) return end if not g_game.isOnline() then return end if g_game.getClientVersion() >= 1300 then MessageTypes[MessageModes.Loot] = MessageSettings.loot MessageTypes[MessageModes.ValuableLoot] = MessageSettings.valuableLoot MessageTypes[MessageModes.Guild] = MessageSettings.statusOwn MessageTypes[MessageModes.Party] = MessageSettings.statusOwn else MessageTypes[MessageModes.PrivateFrom] = MessageSettings.privateNpcToPlayer MessageTypes[MessageModes.Loot] = MessageSettings.centerGreen MessageTypes[MessageModes.ValuableLoot] = MessageSettings.centerGreen MessageTypes[MessageModes.Guild] = MessageSettings.centerGreen MessageTypes[MessageModes.Party] = MessageSettings.centerGreen MessageTypes[MessageModes.MonsterSay] = MessageSettings.consoleOrange MessageTypes[MessageModes.MonsterYell] = MessageSettings.consoleOrange end local msgtype = MessageTypes[mode] if not msgtype then return end if msgtype == MessageSettings.none then return end -- OT-MMO: nombres con calidad («{q3|...}», server/scripts/equipo/equipo.lua) en su color, en cualquier mensaje local conCalidad = text:find("{q%d|") ~= nil if conCalidad and msgtype ~= MessageSettings.loot and msgtype ~= MessageSettings.valuableLoot then local coloreado = ItemsDatabase.colorCalidad(text) if msgtype.consoleTab ~= nil and (msgtype.consoleOption == nil or modules.client_options.getOption(msgtype.consoleOption)) then local tipo = {} for k, v in pairs(msgtype) do tipo[k] = v end tipo.colored = true modules.game_console.addText(coloreado, tipo, tr(msgtype.consoleTab)) end if msgtype.screenTarget then local label = messagesPanel:recursiveGetChildById(msgtype.screenTarget) label:setColor(msgtype.color) label:setColoredText(coloreado) label:setVisible(true) removeEvent(label.hideEvent) label.hideEvent = scheduleEvent(function() label:setVisible(false) end, calculateVisibleTime(text)) end return end if msgtype.consoleTab ~= nil and (msgtype.consoleOption == nil or modules.client_options.getOption(msgtype.consoleOption)) then if msgtype == MessageSettings.loot or msgtype == MessageSettings.valuableLoot then local lootColoredText = ItemsDatabase.setColorLootMessage(text) local lootTabName = tr(msgtype.consoleTab) local targetTab = modules.game_console.getTab(lootTabName) and lootTabName or tr("Server Log") modules.game_console.addText(lootColoredText, msgtype, targetTab) else modules.game_console.addText(text, msgtype, tr(msgtype.consoleTab)) end end if msgtype.screenTarget then local label = messagesPanel:recursiveGetChildById(msgtype.screenTarget) if msgtype == MessageSettings.loot and not modules.client_options.getOption('showLootMessagesOnScreen') then return elseif msgtype == MessageSettings.loot or msgtype == MessageSettings.valuableLoot then local coloredText = ItemsDatabase.setColorLootMessage(text) label:setColoredText(coloredText) else label:setText(text) label:setColor(msgtype.color) end label:setVisible(true) removeEvent(label.hideEvent) label.hideEvent = scheduleEvent(function() label:setVisible(false) end, calculateVisibleTime(text)) end end function displayPrivateMessage(text) if not g_game.isOnline() then return end local msgtype = MessageSettings.private if not msgtype or not msgtype.screenTarget then return end local label = messagesPanel:recursiveGetChildById(msgtype.screenTarget) if not label then return end label:setText(text) label:setColor(msgtype.color) label:setVisible(true) removeEvent(label.hideEvent) label.hideEvent = scheduleEvent(function() label:setVisible(false) end, calculateVisibleTime(text)) end function displayStatusMessage(text) displayMessage(MessageModes.Status, text) end function displayFailureMessage(text) displayMessage(MessageModes.Failure, text) end function displayGameMessage(text) displayMessage(MessageModes.Game, text) end function displayBroadcastMessage(text) displayMessage(MessageModes.Warning, text) end function clearMessages() for _i, child in pairs(messagesPanel:recursiveGetChildren()) do if child:getId():match('Label') then child:hide() removeEvent(child.hideEvent) end end end function LocalPlayer:onAutoWalkFail(player) modules.game_textmessage.displayFailureMessage(tr('There is no way.')) end