| | | @@ -0,0 +1,2377 @@ |
| 1 | + | SpeakTypesSettings = { |
| 2 | + | none = {}, |
| 3 | + | say = { |
| 4 | + | color = "#FFFF00", |
| 5 | + | speakType = MessageModes.Say |
| 6 | + | }, |
| 7 | + | whisper = { |
| 8 | + | color = "#FFFF00", |
| 9 | + | speakType = MessageModes.Whisper |
| 10 | + | }, |
| 11 | + | yell = { |
| 12 | + | color = "#FFFF00", |
| 13 | + | speakType = MessageModes.Yell |
| 14 | + | }, |
| 15 | + | broadcast = { |
| 16 | + | color = "#F55E5E", |
| 17 | + | speakType = MessageModes.GamemasterPrivateFrom |
| 18 | + | }, |
| 19 | + | private = { |
| 20 | + | color = "#5FF7F7", |
| 21 | + | private = true, |
| 22 | + | speakType = MessageModes.PrivateTo |
| 23 | + | }, |
| 24 | + | privateRed = { |
| 25 | + | color = "#F55E5E", |
| 26 | + | private = true, |
| 27 | + | speakType = MessageModes.GamemasterTo |
| 28 | + | }, |
| 29 | + | privatePlayerToPlayer = { |
| 30 | + | color = "#9F9DFD", |
| 31 | + | private = true, |
| 32 | + | speakType = MessageModes.PrivateTo |
| 33 | + | }, |
| 34 | + | privatePlayerToNpc = { |
| 35 | + | color = "#9F9DFD", |
| 36 | + | npcChat = true, |
| 37 | + | private = true, |
| 38 | + | speakType = MessageModes.NpcTo |
| 39 | + | }, |
| 40 | + | privateNpcToPlayer = { |
| 41 | + | color = "#5FF7F7", |
| 42 | + | npcChat = true, |
| 43 | + | private = true, |
| 44 | + | speakType = MessageModes.NpcFrom |
| 45 | + | }, |
| 46 | + | channelYellow = { |
| 47 | + | color = "#FFFF00", |
| 48 | + | speakType = MessageModes.Channel |
| 49 | + | }, |
| 50 | + | channelWhite = { |
| 51 | + | color = "#FFFFFF", |
| 52 | + | speakType = MessageModes.ChannelManagement |
| 53 | + | }, |
| 54 | + | channelRed = { |
| 55 | + | color = "#F55E5E", |
| 56 | + | speakType = MessageModes.GamemasterChannel |
| 57 | + | }, |
| 58 | + | channelOrange = { |
| 59 | + | color = "#FE6500", |
| 60 | + | speakType = MessageModes.ChannelHighlight |
| 61 | + | }, |
| 62 | + | monsterSay = { |
| 63 | + | color = "#FE6500", |
| 64 | + | hideInConsole = true, |
| 65 | + | speakType = MessageModes.MonsterSay |
| 66 | + | }, |
| 67 | + | monsterYell = { |
| 68 | + | color = "#FE6500", |
| 69 | + | hideInConsole = true, |
| 70 | + | speakType = MessageModes.MonsterYell |
| 71 | + | }, |
| 72 | + | rvrAnswerFrom = { |
| 73 | + | color = "#FE6500", |
| 74 | + | speakType = MessageModes.RVRAnswer |
| 75 | + | }, |
| 76 | + | rvrAnswerTo = { |
| 77 | + | color = "#FE6500", |
| 78 | + | speakType = MessageModes.RVRAnswer |
| 79 | + | }, |
| 80 | + | rvrContinue = { |
| 81 | + | color = "#FFFF00", |
| 82 | + | speakType = MessageModes.RVRContinue |
| 83 | + | } |
| 84 | + | } |
| 85 | + | ChatStatusActivated = false |
| 86 | + | ChatControlStatus = nil |
| 87 | + | SpeakTypes = { |
| 88 | + | [MessageModes.Say] = SpeakTypesSettings.say, |
| 89 | + | [MessageModes.Whisper] = SpeakTypesSettings.whisper, |
| 90 | + | [MessageModes.Yell] = SpeakTypesSettings.yell, |
| 91 | + | [MessageModes.GamemasterBroadcast] = SpeakTypesSettings.broadcast, |
| 92 | + | [MessageModes.PrivateFrom] = SpeakTypesSettings.private, |
| 93 | + | [MessageModes.GamemasterPrivateFrom] = SpeakTypesSettings.privateRed, |
| 94 | + | [MessageModes.NpcTo] = SpeakTypesSettings.privatePlayerToNpc, |
| 95 | + | [MessageModes.NpcFrom] = SpeakTypesSettings.privateNpcToPlayer, |
| 96 | + | [MessageModes.Channel] = SpeakTypesSettings.channelYellow, |
| 97 | + | [MessageModes.ChannelManagement] = SpeakTypesSettings.channelWhite, |
| 98 | + | [MessageModes.GamemasterChannel] = SpeakTypesSettings.channelRed, |
| 99 | + | [MessageModes.ChannelHighlight] = SpeakTypesSettings.channelOrange, |
| 100 | + | [MessageModes.MonsterSay] = SpeakTypesSettings.monsterSay, |
| 101 | + | [MessageModes.MonsterYell] = SpeakTypesSettings.monsterYell, |
| 102 | + | [MessageModes.RVRChannel] = SpeakTypesSettings.channelWhite, |
| 103 | + | [MessageModes.RVRContinue] = SpeakTypesSettings.rvrContinue, |
| 104 | + | [MessageModes.RVRAnswer] = SpeakTypesSettings.rvrAnswerFrom, |
| 105 | + | [MessageModes.NpcFromStartBlock] = SpeakTypesSettings.privateNpcToPlayer, |
| 106 | + | [MessageModes.Spell] = SpeakTypesSettings.none, |
| 107 | + | [MessageModes.BarkLow] = SpeakTypesSettings.none, |
| 108 | + | [MessageModes.BarkLoud] = SpeakTypesSettings.none |
| 109 | + | } |
| 110 | + | SayModes = { |
| 111 | + | { |
| 112 | + | icon = "/images/game/chat/icons/whisper", |
| 113 | + | speakTypeDesc = "whisper" |
| 114 | + | }, |
| 115 | + | { |
| 116 | + | icon = "/images/game/chat/icons/say", |
| 117 | + | speakTypeDesc = "say" |
| 118 | + | }, |
| 119 | + | { |
| 120 | + | icon = "/images/game/chat/icons/yell", |
| 121 | + | speakTypeDesc = "yell" |
| 122 | + | } |
| 123 | + | } |
| 124 | + | -- Global channel color mapping used in final message formatting and addText |
| 125 | + | CHANNEL_COLOR_MAP = { |
| 126 | + | ["Default"] = "#FFFF00", -- amarillo |
| 127 | + | ["Global"] = "#FF0000", -- rojo |
| 128 | + | ["Help"] = "#00FF00", -- verde |
| 129 | + | ["Trade"] = "#00BFFF", -- azul claro |
| 130 | + | ["Private"] = "#800080", -- púrpura (fallback for private channels) |
| 131 | + | ["Canal1"] = "#FF00FF", -- color específico para Canal1 |
| 132 | + | ["Canal2"] = "#00FFFF" -- color específico para Canal2 |
| 133 | + | } |
| 134 | + | MAX_HISTORY = 500 |
| 135 | + | MAX_LINES = 100 |
| 136 | + | HELP_CHANNEL = 9 |
| 137 | + | TIME_CLEAR_TEXT = 15000 |
| 138 | + | FINAL_MESSAGE_COLOR = "#FFAA00" -- color distintivo para los mensajes finales |
| 139 | + | chatWindow = nil |
| 140 | + | contentPanel = nil |
| 141 | + | consoleTabBar = nil |
| 142 | + | textEdit = nil |
| 143 | + | channels = nil |
| 144 | + | channelsWindow = nil |
| 145 | + | communicationWindow = nil |
| 146 | + | ownPrivateName = nil |
| 147 | + | messageHistory = {} |
| 148 | + | currentMessageIndex = 0 |
| 149 | + | ignoreNpcMessages = false |
| 150 | + | defaultTab = nil |
| 151 | + | serverTab = nil |
| 152 | + | violationsChannelId = nil |
| 153 | + | violationWindow = nil |
| 154 | + | violationReportTab = nil |
| 155 | + | chatLocked = false |
| 156 | + | ignoredChannels = {} |
| 157 | + | filters = {} |
| 158 | + | local hk = false |
| 159 | + | local isOnline = false |
| 160 | + | local chatactive = true |
| 161 | + | local communicationSettings = { |
| 162 | + | yelling = false, |
| 163 | + | useIgnoreList = true, |
| 164 | + | allowVIPs = false, |
| 165 | + | useWhiteList = true, |
| 166 | + | privateMessages = false, |
| 167 | + | ignoredPlayers = {}, |
| 168 | + | whitelistedPlayers = {} |
| 169 | + | } |
| 170 | + | local options = { |
| 171 | + | chatAlwaysActive = false, |
| 172 | + | classicChat = false, |
| 173 | + | chatAlwaysActiveEnableWASD = false, |
| 174 | + | backgroundAlwaysVisible = false |
| 175 | + | } |
| 176 | + | |
| 177 | + | -- Función para normalizar nombres de canal |
| 178 | + | local function normalizeChannelName(name) |
| 179 | + | -- recorta espacios y convierte la primera letra a mayúscula |
| 180 | + | name = name:match("^%s*(.-)%s*$") |
| 181 | + | return name:gsub("^(%l)", string.upper) |
| 182 | + | end |
| 183 | + | |
| 184 | + | function init() |
| 185 | + | connect(g_game, { |
| 186 | + | onTalk = onTalk, |
| 187 | + | onChannelList = onChannelList, |
| 188 | + | onOpenChannel = onOpenChannel, |
| 189 | + | onOpenPrivateChannel = onOpenPrivateChannel, |
| 190 | + | onOpenOwnPrivateChannel = onOpenOwnPrivateChannel, |
| 191 | + | onCloseChannel = onCloseChannel, |
| 192 | + | onRuleViolationChannel = onRuleViolationChannel, |
| 193 | + | onRuleViolationRemove = onRuleViolationRemove, |
| 194 | + | onRuleViolationCancel = onRuleViolationCancel, |
| 195 | + | onRuleViolationLock = onRuleViolationLock, |
| 196 | + | onGameEnd = onGameEnd, |
| 197 | + | onGameStart = onGameStart |
| 198 | + | }) |
| 199 | + | |
| 200 | + | chatWindow = g_ui.loadUI("chat", modules.game_interface.getRootPanel()) |
| 201 | + | configWindow = g_ui.loadUI("config", modules.game_interface.getRootPanel()) |
| 202 | + | allchat = g_ui.loadUI("allchat", modules.game_interface.getRootPanel()) |
| 203 | + | configWindow.configsContent.chatAlwaysActive.tooltip = "Essa opção desabilita o WASD." |
| 204 | + | configWindow.configsContent.chatAlwaysActiveEnableWASD.tooltip = "Essa opção ativa o WASD quando o seu chat está com a opção chatAlwaysActive ativa." |
| 205 | + | allchatPanel = allchat.consoleBuffer |
| 206 | + | |
| 207 | + | allchat:fill("chat") |
| 208 | + | |
| 209 | + | textEdit = chatWindow.textEdit |
| 210 | + | -- Agregar enviar mensaje o alternar chat con Enter |
| 211 | + | textEdit.onEnter = function() |
| 212 | + | if textEdit:getText() == "" then |
| 213 | + | toggleChat() |
| 214 | + | return true |
| 215 | + | else |
| 216 | + | doSendCurrentMessageBtn() |
| 217 | + | return true |
| 218 | + | end |
| 219 | + | end |
| 220 | + | |
| 221 | + | textEdit.onKeyPress = function(self, keyCode, keyboardModifiers) |
| 222 | + | if keyCode == KeyEnter then |
| 223 | + | if self:getText() == "" then |
| 224 | + | toggleChat() |
| 225 | + | return true |
| 226 | + | else |
| 227 | + | doSendCurrentMessageBtn() |
| 228 | + | return true |
| 229 | + | end |
| 230 | + | end |
| 231 | + | return false |
| 232 | + | end |
| 233 | + | contentPanel = chatWindow.contentPanel |
| 234 | + | consoleTabBar = chatWindow.consoleTabBar |
| 235 | + | |
| 236 | + | consoleTabBar:setContentWidget(contentPanel) |
| 237 | + | consoleTabBar:setTabSpacing(1) |
| 238 | + | |
| 239 | + | chatTextLineWindow = chatWindow.textLineWindow |
| 240 | + | chatEnterBackground = chatWindow.enterBackground |
| 241 | + | backgroundEmotes = chatWindow.backgroundEmotes |
| 242 | + | emotesPanel = chatWindow.backgroundEmotes.Emotes |
| 243 | + | EmotesButton = chatWindow.EmotesButton |
| 244 | + | |
| 245 | + | function chatWindow:onGeometryChange() |
| 246 | + | chatTextLineWindow:setHeight(self:getHeight() - 75) |
| 247 | + | chatTextLineWindow:setWidth(self:getWidth() - 47) |
| 248 | + | chatEnterBackground:setWidth(self:getWidth() - 36) |
| 249 | + | end |
| 250 | + | |
| 251 | + | chatWindow.rB:setMaximum(1000) |
| 252 | + | chatWindow.rB:setMinimum(245) |
| 253 | + | chatWindow.rB2:setMaximum(600) |
| 254 | + | chatWindow.rB2:setMinimum(140) |
| 255 | + | |
| 256 | + | chatWindow.rB3.inverted = true |
| 257 | + | |
| 258 | + | chatWindow.rB3:setMaximum(600) |
| 259 | + | chatWindow.rB3:setMinimum(140) |
| 260 | + | |
| 261 | + | chatWindow.rB4.inverted = true |
| 262 | + | |
| 263 | + | chatWindow.rB4:setMaximum(1000) |
| 264 | + | chatWindow.rB4:setMinimum(245) |
| 265 | + | |
| 266 | + | chatWindow.closeChannelButton.tooltip = tr("Close this channel") .. " (Ctrl + E)" |
| 267 | + | chatWindow.clearChannelButton.tooltip = tr("Clear current message window") |
| 268 | + | chatWindow.channelsButton.tooltip = tr("Open new channel") .. " (Ctrl+O)" |
| 269 | + | chatWindow.ignoreButton.tooltip = tr("Ignore players") |
| 270 | + | chatWindow.sayModeButton.tooltip = tr("Adjust volume") |
| 271 | + | |
| 272 | + | hide() |
| 273 | + | |
| 274 | + | channels = {} |
| 275 | + | |
| 276 | + | function chatWindow:onKeyPress(keyCode, keyboardModifiers) |
| 277 | + | if keyboardModifiers ~= KeyboardCtrlModifier or keyCode ~= KeyC then |
| 278 | + | return false |
| 279 | + | end |
| 280 | + | |
| 281 | + | local tab = consoleTabBar:getCurrentTab() |
| 282 | + | |
| 283 | + | if not tab then |
| 284 | + | return false |
| 285 | + | end |
| 286 | + | |
| 287 | + | local consoleBuffer = tab.tabPanel.consoleBuffer |
| 288 | + | |
| 289 | + | if not consoleBuffer then |
| 290 | + | return false |
| 291 | + | end |
| 292 | + | |
| 293 | + | local consoleLabel = consoleBuffer:getFocusedChild() |
| 294 | + | |
| 295 | + | if not consoleLabel or not consoleLabel:hasSelection() then |
| 296 | + | return false |
| 297 | + | end |
| 298 | + | |
| 299 | + | g_window.setClipboardText(consoleLabel:getSelection()) |
| 300 | + | |
| 301 | + | return true |
| 302 | + | end |
| 303 | + | |
| 304 | + | g_keyboard.bindKeyPress("Shift+Up", function () |
| 305 | + | navigateMessageHistory(1) |
| 306 | + | end, chatWindow) |
| 307 | + | g_keyboard.bindKeyPress("Shift+Down", function () |
| 308 | + | navigateMessageHistory(-1) |
| 309 | + | end, chatWindow) |
| 310 | + | g_keyboard.bindKeyPress("Tab", function () |
| 311 | + | consoleTabBar:selectNextTab() |
| 312 | + | end, chatWindow) |
| 313 | + | g_keyboard.bindKeyPress("Shift+Tab", function () |
| 314 | + | consoleTabBar:selectPrevTab() |
| 315 | + | end, chatWindow) |
| 316 | + | g_keyboard.bindKeyPress("Ctrl+A", function () |
| 317 | + | textEdit:clearText() |
| 318 | + | end, consolePanel) |
| 319 | + | g_keyboard.bindKeyDown("Ctrl+O", g_game.requestChannels) |
| 320 | + | g_keyboard.bindKeyDown("Ctrl+E", removeCurrentTab) |
| 321 | + | g_keyboard.bindKeyDown("Ctrl+H", openHelp) |
| 322 | + | consoleTabBar:setNavigation(chatWindow.prevChannelButton, chatWindow.nextChannelButton) |
| 323 | + | |
| 324 | + | consoleTabBar.onTabChange = onTabChange |
| 325 | + | |
| 326 | + | load() |
| 327 | + | chatWindow:setVisible(false) |
| 328 | + | end |
| 329 | + | |
| 330 | + | function isActive() |
| 331 | + | return chatWindow:isFocusable() |
| 332 | + | end |
| 333 | + | |
| 334 | + | function doToggleAllChat() |
| 335 | + | if chatWindow:isVisible() then |
| 336 | + | allchat:setVisible(false) |
| 337 | + | else |
| 338 | + | allchat:setVisible(true) |
| 339 | + | end |
| 340 | + | end |
| 341 | + | |
| 342 | + | function doSendCurrentMessageBtn() |
| 343 | + | local message = textEdit:getText() |
| 344 | + | |
| 345 | + | if #message == 0 or not isActive() then |
| 346 | + | return true |
| 347 | + | end |
| 348 | + | |
| 349 | + | -- Si se detecta que el mensaje es exactamente un shortcut de emote, se procesa de inmediato. |
| 350 | + | local emoteShortcuts = { ":)", ":(", ":D", ":O", ":P", ";)", ":@", ":S", ":Z", ":!", ":?", ":|", ":$", ":X", ":E", ":F", ":H", ":I", ":K", ":L", ":M", ":N", ":Q", ":R", ":T", ":U", ":V", ":Y", ":W", ":G", ":B", ":C", ":A", ":D2", ":O2", ":P2", ":S2", ":Z2", ":!2", ":?2", ":|2", ":$2", ":X2", ":E2", ":F2", ":H2", ":I2", ":K2", ":L2", ":M2", ":N2", ":Q2", ":R2", ":T2", ":U2", ":V2", ":Y2", ":W2", ":G2", ":B2", ":C2", ":A2" } |
| 351 | + | for _, shortcut in ipairs(emoteShortcuts) do |
| 352 | + | if message == shortcut then |
| 353 | + | -- Se puede agregar lógica adicional si se desea tratar el emote de forma especial. |
| 354 | + | break |
| 355 | + | end |
| 356 | + | end |
| 357 | + | |
| 358 | + | doCloseWindowEmoticons() -- Se cierra el panel de emotes antes de enviar |
| 359 | + | sendCurrentMessage() |
| 360 | + | end |
| 361 | + | |
| 362 | + | function sendCurrentMessage() |
| 363 | + | local message = textEdit:getText() |
| 364 | + | |
| 365 | + | if #message == 0 or not isActive() then |
| 366 | + | toggleChat() |
| 367 | + | doToggleAllChat() |
| 368 | + | |
| 369 | + | return |
| 370 | + | end |
| 371 | + | |
| 372 | + | textEdit:clearText() |
| 373 | + | sendMessage(message) |
| 374 | + | |
| 375 | + | if options.classicChat == false then |
| 376 | + | toggleChat() |
| 377 | + | doToggleAllChat() |
| 378 | + | end |
| 379 | + | end |
| 380 | + | |
| 381 | + | function sendMessage(message, tab) |
| 382 | + | local tab = tab or getCurrentTab() |
| 383 | + | |
| 384 | + | if not tab then |
| 385 | + | return |
| 386 | + | end |
| 387 | + | |
| 388 | + | for k, func in pairs(filters) do |
| 389 | + | if func(message) then |
| 390 | + | return true |
| 391 | + | end |
| 392 | + | end |
| 393 | + | |
| 394 | + | local name = tab:getText() |
| 395 | + | |
| 396 | + | if tab == serverTab or tab == getRuleViolationsTab() then |
| 397 | + | tab = defaultTab |
| 398 | + | name = defaultTab:getText() |
| 399 | + | end |
| 400 | + | |
| 401 | + | local channel = tab.channelId |
| 402 | + | local originalMessage = message |
| 403 | + | local chatCommandSayMode, chatCommandPrivate, chatCommandPrivateReady, chatCommandMessage = nil |
| 404 | + | chatCommandMessage = message:match("^%#[y|Y] (.*)") |
| 405 | + | |
| 406 | + | if chatCommandMessage ~= nil then |
| 407 | + | chatCommandSayMode = "yell" |
| 408 | + | channel = 0 |
| 409 | + | message = chatCommandMessage |
| 410 | + | end |
| 411 | + | |
| 412 | + | local chatCommandMessage = message:match("^%#[w|W] (.*)") |
| 413 | + | |
| 414 | + | if chatCommandMessage ~= nil then |
| 415 | + | chatCommandSayMode = "whisper" |
| 416 | + | message = chatCommandMessage |
| 417 | + | channel = 0 |
| 418 | + | end |
| 419 | + | |
| 420 | + | local chatCommandMessage = message:match("^%#[s|S] (.*)") |
| 421 | + | |
| 422 | + | if chatCommandMessage ~= nil then |
| 423 | + | chatCommandSayMode = "say" |
| 424 | + | message = chatCommandMessage |
| 425 | + | channel = 0 |
| 426 | + | end |
| 427 | + | |
| 428 | + | local findIni, findEnd, chatCommandInitial, chatCommandPrivate, chatCommandEnd, chatCommandMessage = message:find("([%*%@])(.+)([%*%@])(.*)") |
| 429 | + | |
| 430 | + | if findIni ~= nil and findIni == 1 and chatCommandInitial == chatCommandEnd then |
| 431 | + | chatCommandPrivateRepeat = false |
| 432 | + | |
| 433 | + | if chatCommandInitial == "*" then |
| 434 | + | setTextEditText("*" .. chatCommandPrivate .. "* ") |
| 435 | + | end |
| 436 | + | |
| 437 | + | message = chatCommandMessage:trim() |
| 438 | + | chatCommandPrivateReady = true |
| 439 | + | end |
| 440 | + | |
| 441 | + | message = message:gsub("^(%s*)(.*)", "%2") |
| 442 | + | |
| 443 | + | if #message == 0 then |
| 444 | + | return |
| 445 | + | end |
| 446 | + | |
| 447 | + | currentMessageIndex = 0 |
| 448 | + | |
| 449 | + | if #messageHistory == 0 or messageHistory[#messageHistory] ~= originalMessage then |
| 450 | + | table.insert(messageHistory, originalMessage) |
| 451 | + | |
| 452 | + | if MAX_HISTORY < #messageHistory then |
| 453 | + | table.remove(messageHistory, 1) |
| 454 | + | end |
| 455 | + | end |
| 456 | + | |
| 457 | + | local speaktypedesc = nil |
| 458 | + | |
| 459 | + | if (channel or tab == defaultTab) and not chatCommandPrivateReady then |
| 460 | + | if tab == defaultTab then |
| 461 | + | speaktypedesc = chatCommandSayMode or SayModes[chatWindow.sayModeButton.sayMode].speakTypeDesc |
| 462 | + | |
| 463 | + | if speaktypedesc ~= "say" then |
| 464 | + | sayModeChange(2) |
| 465 | + | end |
| 466 | + | |
| 467 | + | g_game.talkChannel(SpeakTypesSettings[speaktypedesc].speakType, channel, message) |
| 468 | + | |
| 469 | + | -- ✅ NOVO AJUSTE COM FORMATACAO E CORES IGUAIS À IMAGEM |
| 470 | + | local channelColorMap = { |
| 471 | + | ["Padrao"] = "#FFFF00", -- amarelo |
| 472 | + | ["Global"] = "#FF0000", -- vermelho |
| 473 | + | ["Help"] = "#00FF00", -- verde |
| 474 | + | ["Trade"] = "#00BFFF" -- azul claro |
| 475 | + | } |
| 476 | + | |
| 477 | + | local timeStamp = os.date("%H:%M") |
| 478 | + | local channelName = defaultTab:getText() |
| 479 | + | local playerName = g_game.getCharacterName() |
| 480 | + | local playerTag = "[ADM]" -- aqui, ajuste conforme o cargo/tag real do jogador |
| 481 | + | local channelColor = channelColorMap[channelName] or "#FFFFFF" |
| 482 | + | |
| 483 | + | local finalMessage = string.format("%s Chat (%s)%s %s: %s", |
| 484 | + | timeStamp, |
| 485 | + | string.format("{%s}%s", channelColor, channelName), |
| 486 | + | string.format("{#FFFFFF}%s", playerTag), |
| 487 | + | string.format("{#FFFF00}%s", playerName), |
| 488 | + | message |
| 489 | + | ) |
| 490 | + | addText(finalMessage, SpeakTypesSettings[speaktypedesc], defaultTab, playerName) |
| 491 | + | |
| 492 | + | return |
| 493 | + | else |
| 494 | + | speaktypedesc = chatCommandSayMode or "channelYellow" |
| 495 | + | end |
| 496 | + | |
| 497 | + | g_game.talkChannel(SpeakTypesSettings[speaktypedesc].speakType, channel, message) |
| 498 | + | |
| 499 | + | return |
| 500 | + | else |
| 501 | + | local isPrivateCommand = false |
| 502 | + | local priv = true |
| 503 | + | local tabname = name |
| 504 | + | |
| 505 | + | if chatCommandPrivateReady then |
| 506 | + | speaktypedesc = "privatePlayerToPlayer" |
| 507 | + | name = chatCommandPrivate |
| 508 | + | isPrivateCommand = true |
| 509 | + | elseif tab.npcChat then |
| 510 | + | speaktypedesc = "privatePlayerToNpc" |
| 511 | + | elseif tab == violationReportTab then |
| 512 | + | if violationReportTab.locked then |
| 513 | + | modules.game_textmessage.displayFailureMessage("Wait for a gamemaster reply.") |
| 514 | + | return |
| 515 | + | end |
| 516 | + | speaktypedesc = "rvrContinue" |
| 517 | + | tabname = tr("Report Rule") .. "..." |
| 518 | + | elseif tab.violationChatName then |
| 519 | + | speaktypedesc = "rvrAnswerTo" |
| 520 | + | name = tab.violationChatName |
| 521 | + | tabname = tab.violationChatName .. "'..." |
| 522 | + | else |
| 523 | + | speaktypedesc = "privatePlayerToPlayer" |
| 524 | + | end |
| 525 | + | |
| 526 | + | local speaktype = SpeakTypesSettings[speaktypedesc] |
| 527 | + | local player = g_game.getLocalPlayer() |
| 528 | + | |
| 529 | + | g_game.talkPrivate(speaktype.speakType, name, message) |
| 530 | + | |
| 531 | + | message = applyMessagePrefixies(g_game.getCharacterName(), player:getLevel(), message) |
| 532 | + | |
| 533 | + | addPrivateText(message, speaktype, tabname, isPrivateCommand, g_game.getCharacterName()) |
| 534 | + | end |
| 535 | + | end |
| 536 | + | |
| 537 | + | function sayModeChange(sayMode) |
| 538 | + | local buttom = chatWindow.sayModeButton |
| 539 | + | |
| 540 | + | if sayMode == nil then |
| 541 | + | sayMode = buttom.sayMode + 1 |
| 542 | + | end |
| 543 | + | |
| 544 | + | if sayMode > #SayModes then |
| 545 | + | sayMode = 1 |
| 546 | + | end |
| 547 | + | |
| 548 | + | buttom:setIcon(SayModes[sayMode].icon) |
| 549 | + | |
| 550 | + | buttom.sayMode = sayMode |
| 551 | + | end |
| 552 | + | |
| 553 | + | function getOwnPrivateTab() |
| 554 | + | if not ownPrivateName then |
| 555 | + | return |
| 556 | + | end |
| 557 | + | |
| 558 | + | return getTab(ownPrivateName) |
| 559 | + | end |
| 560 | + | |
| 561 | + | function setIgnoreNpcMessages(ignore) |
| 562 | + | ignoreNpcMessages = ignore |
| 563 | + | end |
| 564 | + | |
| 565 | + | function navigateMessageHistory(step) |
| 566 | + | local numCommands = #messageHistory |
| 567 | + | |
| 568 | + | if numCommands > 0 then |
| 569 | + | currentMessageIndex = math.min(math.max(currentMessageIndex + step, 0), numCommands) |
| 570 | + | |
| 571 | + | if currentMessageIndex > 0 then |
| 572 | + | local command = messageHistory[numCommands - currentMessageIndex + 1] |
| 573 | + | |
| 574 | + | setTextEditText(command) |
| 575 | + | else |
| 576 | + | textEdit:clearText() |
| 577 | + | end |
| 578 | + | end |
| 579 | + | end |
| 580 | + | |
| 581 | + | function clearChannel(consoleTabBar) |
| 582 | + | consoleTabBar:getCurrentTab().tabPanel.consoleBuffer:destroyChildren() |
| 583 | + | end |
| 584 | + | |
| 585 | + | function setTextEditText(text) |
| 586 | + | textEdit:setText(text) |
| 587 | + | textEdit:setCursorPos(-1) |
| 588 | + | end |
| 589 | + | |
| 590 | + | function openHelp() |
| 591 | + | local helpChannel = 9 |
| 592 | + | |
| 593 | + | if g_game.getClientVersion() <= 810 then |
| 594 | + | helpChannel = 8 |
| 595 | + | end |
| 596 | + | |
| 597 | + | g_game.joinChannel(helpChannel) |
| 598 | + | end |
| 599 | + | |
| 600 | + | function openPlayerReportRuleViolationWindow() |
| 601 | + | if violationWindow or violationReportTab then |
| 602 | + | return |
| 603 | + | end |
| 604 | + | |
| 605 | + | violationWindow = g_ui.loadUI("violationwindow", rootWidget) |
| 606 | + | |
| 607 | + | function violationWindow.onEscape() |
| 608 | + | violationWindow:destroy() |
| 609 | + | |
| 610 | + | violationWindow = nil |
| 611 | + | end |
| 612 | + | |
| 613 | + | function violationWindow.onEnter() |
| 614 | + | local text = violationWindow.text:getText() |
| 615 | + | |
| 616 | + | g_game.talkChannel(MessageModes.RVRChannel, 0, text) |
| 617 | + | |
| 618 | + | violationReportTab = addTab(tr("Report Rule") .. "...", true) |
| 619 | + | |
| 620 | + | addTabText(tr("Please wait patiently for a gamemaster to reply") .. ".", SpeakTypesSettings.privateRed, violationReportTab) |
| 621 | + | addTabText(applyMessagePrefixies(g_game.getCharacterName(), 0, text), SpeakTypesSettings.say, violationReportTab, g_game.getCharacterName()) |
| 622 | + | |
| 623 | + | violationReportTab.locked = true |
| 624 | + | |
| 625 | + | violationWindow:destroy() |
| 626 | + | |
| 627 | + | violationWindow = nil |
| 628 | + | end |
| 629 | + | end |
| 630 | + | |
| 631 | + | function addTab(name, focus) |
| 632 | + | local tab = getTab(name) |
| 633 | + | |
| 634 | + | if tab then |
| 635 | + | if not focus then |
| 636 | + | focus = true |
| 637 | + | end |
| 638 | + | else |
| 639 | + | tab = consoleTabBar:addTab(name, nil, processChannelTabMenu) |
| 640 | + | |
| 641 | + | tab:setImageSource("/images/game/chat/channelButtons") |
| 642 | + | end |
| 643 | + | |
| 644 | + | if focus then |
| 645 | + | consoleTabBar:selectTab(tab) |
| 646 | + | end |
| 647 | + | |
| 648 | + | return tab |
| 649 | + | end |
| 650 | + | |
| 651 | + | function removeTab(tab) |
| 652 | + | if type(tab) == "string" then |
| 653 | + | tab = consoleTabBar:getTab(tab) |
| 654 | + | end |
| 655 | + | |
| 656 | + | if tab == defaultTab or tab == serverTab then |
| 657 | + | return |
| 658 | + | end |
| 659 | + | |
| 660 | + | if tab == violationReportTab then |
| 661 | + | g_game.cancelRuleViolation() |
| 662 | + | |
| 663 | + | violationReportTab = nil |
| 664 | + | elseif tab.violationChatName then |
| 665 | + | g_game.closeRuleViolation(tab.violationChatName) |
| 666 | + | elseif tab.channelId then |
| 667 | + | for k, v in pairs(channels) do |
| 668 | + | if k == tab.channelId then |
| 669 | + | channels[k] = nil |
| 670 | + | end |
| 671 | + | end |
| 672 | + | |
| 673 | + | g_game.leaveChannel(tab.channelId) |
| 674 | + | elseif tab:getText() == "NPCs" then |
| 675 | + | g_game.closeNpcChannel() |
| 676 | + | end |
| 677 | + | |
| 678 | + | consoleTabBar:removeTab(tab) |
| 679 | + | end |
| 680 | + | |
| 681 | + | function removeCurrentTab() |
| 682 | + | removeTab(consoleTabBar:getCurrentTab()) |
| 683 | + | consoleTabBar:selectTab(defaultTab) |
| 684 | + | end |
| 685 | + | |
| 686 | + | function getTab(name) |
| 687 | + | return consoleTabBar:getTab(name) |
| 688 | + | end |
| 689 | + | |
| 690 | + | function getChannelTab(channelId) |
| 691 | + | local channel = channels[channelId] |
| 692 | + | |
| 693 | + | if channel then |
| 694 | + | return getTab(channel) |
| 695 | + | end |
| 696 | + | |
| 697 | + | return nil |
| 698 | + | end |
| 699 | + | |
| 700 | + | function getRuleViolationsTab() |
| 701 | + | if violationsChannelId then |
| 702 | + | return getChannelTab(violationsChannelId) |
| 703 | + | end |
| 704 | + | |
| 705 | + | return nil |
| 706 | + | end |
| 707 | + | |
| 708 | + | function getCurrentTab() |
| 709 | + | return consoleTabBar:getCurrentTab() |
| 710 | + | end |
| 711 | + | |
| 712 | + | function addChannel(name, id) |
| 713 | + | channels[id] = name |
| 714 | + | local focus = not table.find(ignoredChannels, id) |
| 715 | + | local tab = addTab(name, focus) |
| 716 | + | tab.channelId = id |
| 717 | + | |
| 718 | + | return tab |
| 719 | + | end |
| 720 | + | |
| 721 | + | function addPrivateChannel(receiver) |
| 722 | + | channels[receiver] = receiver |
| 723 | + | |
| 724 | + | return addTab(receiver, false) |
| 725 | + | end |
| 726 | + | |
| 727 | + | function addPrivateText(text, speaktype, name, isPrivateCommand, creatureName) |
| 728 | + | local focus = false |
| 729 | + | |
| 730 | + | if speaktype.npcChat then |
| 731 | + | name = "NPCs" |
| 732 | + | focus = true |
| 733 | + | end |
| 734 | + | |
| 735 | + | local privateTab = getTab(name) |
| 736 | + | |
| 737 | + | if privateTab == nil then |
| 738 | + | if modules.client_options.getOption("showPrivateMessagesInConsole") and not focus or isPrivateCommand and not privateTab then |
| 739 | + | privateTab = defaultTab |
| 740 | + | else |
| 741 | + | privateTab = addTab(name, focus) |
| 742 | + | channels[name] = name |
| 743 | + | end |
| 744 | + | |
| 745 | + | privateTab.npcChat = speaktype.npcChat |
| 746 | + | elseif focus then |
| 747 | + | consoleTabBar:selectTab(privateTab) |
| 748 | + | end |
| 749 | + | |
| 750 | + | addTabText(text, speaktype, privateTab, creatureName) |
| 751 | + | end |
| 752 | + | |
| 753 | + | function addText(text, speaktype, tabName, creatureName) |
| 754 | + | local tab = getTab(tabName) |
| 755 | + | |
| 756 | + | if tab ~= nil then |
| 757 | + | addTabText(text, speaktype, tab, creatureName) |
| 758 | + | end |
| 759 | + | end |
| 760 | + | |
| 761 | + | local letterWidth = { |
| 762 | + | nil, |
| 763 | + | nil, |
| 764 | + | nil, |
| 765 | + | nil, |
| 766 | + | nil, |
| 767 | + | nil, |
| 768 | + | nil, |
| 769 | + | nil, |
| 770 | + | nil, |
| 771 | + | 1, |
| 772 | + | nil, |
| 773 | + | nil, |
| 774 | + | nil, |
| 775 | + | nil, |
| 776 | + | nil, |
| 777 | + | nil, |
| 778 | + | nil, |
| 779 | + | nil, |
| 780 | + | nil, |
| 781 | + | nil, |
| 782 | + | nil, |
| 783 | + | nil, |
| 784 | + | nil, |
| 785 | + | nil, |
| 786 | + | nil, |
| 787 | + | nil, |
| 788 | + | 1, |
| 789 | + | 3, |
| 790 | + | 6, |
| 791 | + | 8, |
| 792 | + | 7, |
| 793 | + | 13, |
| 794 | + | 9, |
| 795 | + | 3, |
| 796 | + | 5, |
| 797 | + | 5, |
| 798 | + | 6, |
| 799 | + | 8, |
| 800 | + | 4, |
| 801 | + | 5, |
| 802 | + | 3, |
| 803 | + | 8, |
| 804 | + | 7, |
| 805 | + | 6, |
| 806 | + | 7, |
| 807 | + | 7, |
| 808 | + | 7, |
| 809 | + | 7, |
| 810 | + | 7, |
| 811 | + | 7, |
| 812 | + | 7, |
| 813 | + | 7, |
| 814 | + | 3, |
| 815 | + | 4, |
| 816 | + | 8, |
| 817 | + | 8, |
| 818 | + | 8, |
| 819 | + | 6, |
| 820 | + | 10, |
| 821 | + | 9, |
| 822 | + | 7, |
| 823 | + | 7, |
| 824 | + | 8, |
| 825 | + | 7, |
| 826 | + | 7, |
| 827 | + | 8, |
| 828 | + | 8, |
| 829 | + | 5, |
| 830 | + | 5, |
| 831 | + | 7, |
| 832 | + | 7, |
| 833 | + | 9, |
| 834 | + | 8, |
| 835 | + | 8, |
| 836 | + | 7, |
| 837 | + | 8, |
| 838 | + | 8, |
| 839 | + | 7, |
| 840 | + | 8, |
| 841 | + | 8, |
| 842 | + | 8, |
| 843 | + | 12, |
| 844 | + | 8, |
| 845 | + | 8, |
| 846 | + | 7, |
| 847 | + | 5, |
| 848 | + | 8, |
| 849 | + | 5, |
| 850 | + | 9, |
| 851 | + | 8, |
| 852 | + | 5, |
| 853 | + | 7, |
| 854 | + | 7, |
| 855 | + | 6, |
| 856 | + | 7, |
| 857 | + | 7, |
| 858 | + | 5, |
| 859 | + | 7, |
| 860 | + | 7, |
| 861 | + | 3, |
| 862 | + | 4, |
| 863 | + | 7, |
| 864 | + | 3, |
| 865 | + | 11, |
| 866 | + | 7, |
| 867 | + | 7, |
| 868 | + | 7, |
| 869 | + | 7, |
| 870 | + | 6, |
| 871 | + | 6, |
| 872 | + | 5, |
| 873 | + | 7, |
| 874 | + | 8, |
| 875 | + | 10, |
| 876 | + | 8, |
| 877 | + | 8, |
| 878 | + | 6, |
| 879 | + | 7, |
| 880 | + | 4, |
| 881 | + | 7, |
| 882 | + | 8, |
| 883 | + | 1, |
| 884 | + | 7, |
| 885 | + | 6, |
| 886 | + | 3, |
| 887 | + | 7, |
| 888 | + | 6, |
| 889 | + | 11, |
| 890 | + | 7, |
| 891 | + | 7, |
| 892 | + | 7, |
| 893 | + | 13, |
| 894 | + | 7, |
| 895 | + | 4, |
| 896 | + | 11, |
| 897 | + | 6, |
| 898 | + | 6, |
| 899 | + | 6, |
| 900 | + | 6, |
| 901 | + | 4, |
| 902 | + | 3, |
| 903 | + | 7, |
| 904 | + | 6, |
| 905 | + | 6, |
| 906 | + | 7, |
| 907 | + | 10, |
| 908 | + | 7, |
| 909 | + | 10, |
| 910 | + | 6, |
| 911 | + | 5, |
| 912 | + | 11, |
| 913 | + | 6, |
| 914 | + | 6, |
| 915 | + | 8, |
| 916 | + | 4, |
| 917 | + | 3, |
| 918 | + | 7, |
| 919 | + | 7, |
| 920 | + | 7, |
| 921 | + | 8, |
| 922 | + | 4, |
| 923 | + | 7, |
| 924 | + | 6, |
| 925 | + | 10, |
| 926 | + | 6, |
| 927 | + | 8, |
| 928 | + | 8, |
| 929 | + | 16, |
| 930 | + | 10, |
| 931 | + | 8, |
| 932 | + | 5, |
| 933 | + | 8, |
| 934 | + | 5, |
| 935 | + | 5, |
| 936 | + | 6, |
| 937 | + | 7, |
| 938 | + | 7, |
| 939 | + | 3, |
| 940 | + | 5, |
| 941 | + | 6, |
| 942 | + | 6, |
| 943 | + | 8, |
| 944 | + | 12, |
| 945 | + | 12, |
| 946 | + | 12, |
| 947 | + | 6, |
| 948 | + | 9, |
| 949 | + | 9, |
| 950 | + | 9, |
| 951 | + | 9, |
| 952 | + | 9, |
| 953 | + | 9, |
| 954 | + | 11, |
| 955 | + | 7, |
| 956 | + | 7, |
| 957 | + | 7, |
| 958 | + | 7, |
| 959 | + | 7, |
| 960 | + | 5, |
| 961 | + | 5, |
| 962 | + | 6, |
| 963 | + | 5, |
| 964 | + | 8, |
| 965 | + | 8, |
| 966 | + | 8, |
| 967 | + | 8, |
| 968 | + | 8, |
| 969 | + | 8, |
| 970 | + | 8, |
| 971 | + | 8, |
| 972 | + | 8, |
| 973 | + | 8, |
| 974 | + | 8, |
| 975 | + | 8, |
| 976 | + | 8, |
| 977 | + | 8, |
| 978 | + | 7, |
| 979 | + | 7, |
| 980 | + | 7, |
| 981 | + | 7, |
| 982 | + | 7, |
| 983 | + | 7, |
| 984 | + | 7, |
| 985 | + | 7, |
| 986 | + | 11, |
| 987 | + | 6, |
| 988 | + | 7, |
| 989 | + | 7, |
| 990 | + | 7, |
| 991 | + | 7, |
| 992 | + | 3, |
| 993 | + | 4, |
| 994 | + | 4, |
| 995 | + | 4, |
| 996 | + | 7, |
| 997 | + | 7, |
| 998 | + | 7, |
| 999 | + | 7, |
| 1000 | + | 7, |
| 1001 | + | 7, |
| 1002 | + | 7, |
| 1003 | + | 9, |
| 1004 | + | 7, |
| 1005 | + | 7, |
| 1006 | + | 7, |
| 1007 | + | 7, |
| 1008 | + | 7, |
| 1009 | + | 8, |
| 1010 | + | 7, |
| 1011 | + | 8 |
| 1012 | + | } |
| 1013 | + | |
| 1014 | + | function applyMessagePrefixies(name, level, message) |
| 1015 | + | if name then |
| 1016 | + | if modules.client_options.getOption("showLevelsInConsole") and level > 0 then |
| 1017 | + | message = name .. " [" .. level .. "]: " .. message |
| 1018 | + | else |
| 1019 | + | message = name .. ": " .. message |
| 1020 | + | end |
| 1021 | + | end |
| 1022 | + | |
| 1023 | + | return message |
| 1024 | + | end |
| 1025 | + | |
| 1026 | + | function getHighlightedText(text) |
| 1027 | + | local tmpData = {} |
| 1028 | + | |
| 1029 | + | repeat |
| 1030 | + | local tmp = { |
| 1031 | + | string.find(text, "{([^}]+)}", tmpData[#tmpData - 1]) |
| 1032 | + | } |
| 1033 | + | |
| 1034 | + | for _, v in pairs(tmp) do |
| 1035 | + | table.insert(tmpData, v) |
| 1036 | + | end |
| 1037 | + | until not string.find(text, "{([^}]+)}", tmpData[#tmpData - 1]) |
| 1038 | + | |
| 1039 | + | return tmpData |
| 1040 | + | end |
| 1041 | + | |
| 1042 | + | -- Nueva función que parsea el texto con códigos de color y devuelve el texto sin etiquetas y los datos de resaltado |
| 1043 | + | function parseColoredText(text) |
| 1044 | + | local plainText = "" |
| 1045 | + | local highlightData = {} |
| 1046 | + | local currentPos = 1 |
| 1047 | + | while true do |
| 1048 | + | local s, e, colorCode = string.find(text, "{(#%x+)}", currentPos) |
| 1049 | + | if not s then |
| 1050 | + | plainText = plainText .. string.sub(text, currentPos) |
| 1051 | + | break |
| 1052 | + | end |
| 1053 | + | plainText = plainText .. string.sub(text, currentPos, s - 1) |
| 1054 | + | local startPlain = #plainText + 1 |
| 1055 | + | currentPos = e + 1 |
| 1056 | + | local s2, e2, resetCode = string.find(text, "{(#%x+)}", currentPos) |
| 1057 | + | if not s2 then |
| 1058 | + | plainText = plainText .. string.sub(text, currentPos) |
| 1059 | + | break |
| 1060 | + | end |
| 1061 | + | local coloredSegment = string.sub(text, currentPos, s2 - 1) |
| 1062 | + | plainText = plainText .. coloredSegment |
| 1063 | + | table.insert(highlightData, startPlain) |
| 1064 | + | table.insert(highlightData, #plainText) |
| 1065 | + | table.insert(highlightData, colorCode) |
| 1066 | + | currentPos = e2 + 1 |
| 1067 | + | end |
| 1068 | + | return plainText, highlightData |
| 1069 | + | end |
| 1070 | + | |
| 1071 | + | -- Modificación de addTabText para usar la nueva función |
| 1072 | + | function addTabText(text, speaktype, tab, creatureName) |
| 1073 | + | if not tab or tab.locked or not text or #text == 0 then |
| 1074 | + | return |
| 1075 | + | end |
| 1076 | + | |
| 1077 | + | local panel = consoleTabBar:getTabPanel(tab) |
| 1078 | + | local consoleBuffer = panel.consoleBuffer |
| 1079 | + | local label = g_ui.createWidget("ConsoleLabel", consoleBuffer) |
| 1080 | + | |
| 1081 | + | if string.find(text, "{#") then |
| 1082 | + | local plain, highlight = parseColoredText(text) |
| 1083 | + | label:setText(plain) |
| 1084 | + | if #highlight > 0 then |
| 1085 | + | label:setColoredText(highlight) |
| 1086 | + | end |
| 1087 | + | -- No sobrescriba el color base para preservar el marcado |
| 1088 | + | else |
| 1089 | + | label:setText(text) |
| 1090 | + | label:setColor(speaktype.color) |
| 1091 | + | end |
| 1092 | + | |
| 1093 | + | if not ChatStatusActivated then |
| 1094 | + | ChatStatusActivated = true |
| 1095 | + | local label2 = g_ui.createWidget("ConsoleLabel", allchatPanel) |
| 1096 | + | label2:setId("consoleLabel" .. consoleBuffer:getChildCount()) |
| 1097 | + | if string.find(text, "{#") then |
| 1098 | + | local plain2, highlight2 = parseColoredText(text) |
| 1099 | + | label2:setText(plain2) |
| 1100 | + | if #highlight2 > 0 then |
| 1101 | + | label2:setColoredText(highlight2) |
| 1102 | + | end |
| 1103 | + | else |
| 1104 | + | label2:setText(text) |
| 1105 | + | label2:setColor(speaktype.color) |
| 1106 | + | end |
| 1107 | + | g_effects.fadeIn(label2, 350) |
| 1108 | + | scheduleEvent(function () |
| 1109 | + | g_effects.fadeOut(label2, 350) |
| 1110 | + | scheduleEvent(function () |
| 1111 | + | label2:destroy() |
| 1112 | + | label2 = nil |
| 1113 | + | end, 500) |
| 1114 | + | end, TIME_CLEAR_TEXT + 550) |
| 1115 | + | end |
| 1116 | + | |
| 1117 | + | consoleTabBar:blinkTab(tab) |
| 1118 | + | end |
| 1119 | + | |
| 1120 | + | function removeTabLabelByName(tab, name) |
| 1121 | + | local panel = consoleTabBar:getTabPanel(tab) |
| 1122 | + | local consoleBuffer = panel.consoleBuffer |
| 1123 | + | |
| 1124 | + | for _, label in pairs(consoleBuffer:getChildren()) do |
| 1125 | + | if label.name == name then |
| 1126 | + | label:destroy() |
| 1127 | + | end |
| 1128 | + | end |
| 1129 | + | end |
| 1130 | + | |
| 1131 | + | function processChannelTabMenu(tab, mousePos, mouseButton) |
| 1132 | + | local menu = g_ui.createWidget("PopupMenu") |
| 1133 | + | channelName = tab:getText() |
| 1134 | + | |
| 1135 | + | if tab ~= defaultTab and tab ~= serverTab then |
| 1136 | + | menu:addOption(tr("Close"), function () |
| 1137 | + | removeTab(channelName) |
| 1138 | + | end) |
| 1139 | + | menu:addSeparator() |
| 1140 | + | end |
| 1141 | + | |
| 1142 | + | if consoleTabBar:getCurrentTab() == tab then |
| 1143 | + | menu:addOption(tr("Clear Messages"), function () |
| 1144 | + | clearChannel(consoleTabBar) |
| 1145 | + | end) |
| 1146 | + | end |
| 1147 | + | |
| 1148 | + | menu:display(mousePos) |
| 1149 | + | end |
| 1150 | + | |
| 1151 | + | function processMessageMenu(mousePos, mouseButton, creatureName, text, label, tab) |
| 1152 | + | if mouseButton == MouseRightButton then |
| 1153 | + | local menu = g_ui.createWidget("PopupMenu") |
| 1154 | + | |
| 1155 | + | if creatureName and #creatureName > 0 then |
| 1156 | + | if creatureName ~= g_game.getCharacterName() then |
| 1157 | + | menu:addOption(tr("Message to " .. creatureName), function () |
| 1158 | + | g_game.openPrivateChannel(creatureName) |
| 1159 | + | end) |
| 1160 | + | |
| 1161 | + | if not g_game.getLocalPlayer():hasVip(creatureName) then |
| 1162 | + | menu:addOption(tr("Add to VIP list"), function () |
| 1163 | + | g_game.addVip(creatureName) |
| 1164 | + | end) |
| 1165 | + | end |
| 1166 | + | |
| 1167 | + | if modules.game_chat.getOwnPrivateTab() then |
| 1168 | + | menu:addSeparator() |
| 1169 | + | menu:addOption(tr("Invite to private chat"), function () |
| 1170 | + | g_game.inviteToOwnChannel(creatureName) |
| 1171 | + | end) |
| 1172 | + | menu:addOption(tr("Exclude from private chat"), function () |
| 1173 | + | g_game.excludeFromOwnChannel(creatureName) |
| 1174 | + | end) |
| 1175 | + | end |
| 1176 | + | |
| 1177 | + | if isIgnored(creatureName) then |
| 1178 | + | menu:addOption(tr("Unignore") .. " " .. creatureName, function () |
| 1179 | + | removeIgnoredPlayer(creatureName) |
| 1180 | + | end) |
| 1181 | + | else |
| 1182 | + | menu:addOption(tr("Ignore") .. " " .. creatureName, function () |
| 1183 | + | addIgnoredPlayer(creatureName) |
| 1184 | + | end) |
| 1185 | + | end |
| 1186 | + | |
| 1187 | + | menu:addSeparator() |
| 1188 | + | end |
| 1189 | + | |
| 1190 | + | if modules.game_ruleviolation.hasWindowAccess() then |
| 1191 | + | menu:addOption(tr("Rule Violation"), function () |
| 1192 | + | modules.game_ruleviolation.show(creatureName, text:match(".+%:%s(.+)")) |
| 1193 | + | end) |
| 1194 | + | menu:addSeparator() |
| 1195 | + | end |
| 1196 | + | |
| 1197 | + | menu:addOption(tr("Copy name"), function () |
| 1198 | + | g_window.setClipboardText(creatureName) |
| 1199 | + | end) |
| 1200 | + | end |
| 1201 | + | |
| 1202 | + | if label:hasSelection() then |
| 1203 | + | menu:addOption(tr("Copy"), function () |
| 1204 | + | g_window.setClipboardText(label:getSelection()) |
| 1205 | + | end, "(Ctrl+C)") |
| 1206 | + | end |
| 1207 | + | |
| 1208 | + | menu:addOption(tr("Copy message"), function () |
| 1209 | + | g_window.setClipboardText(text) |
| 1210 | + | end) |
| 1211 | + | menu:addOption(tr("Select all"), function () |
| 1212 | + | label:selectAll() |
| 1213 | + | end) |
| 1214 | + | |
| 1215 | + | if tab.violations then |
| 1216 | + | menu:addSeparator() |
| 1217 | + | menu:addOption(tr("Process") .. " " .. creatureName, function () |
| 1218 | + | processViolation(creatureName, text) |
| 1219 | + | end) |
| 1220 | + | menu:addOption(tr("Remove") .. " " .. creatureName, function () |
| 1221 | + | g_game.closeRuleViolation(creatureName) |
| 1222 | + | end) |
| 1223 | + | end |
| 1224 | + | |
| 1225 | + | menu:display(mousePos) |
| 1226 | + | end |
| 1227 | + | end |
| 1228 | + | |
| 1229 | + | function terminate() |
| 1230 | + | disconnect(g_game, { |
| 1231 | + | onTalk = onTalk, |
| 1232 | + | onChannelList = onChannelList, |
| 1233 | + | onOpenChannel = onOpenChannel, |
| 1234 | + | onOpenPrivateChannel = onOpenPrivateChannel, |
| 1235 | + | onOpenOwnPrivateChannel = onOpenOwnPrivateChannel, |
| 1236 | + | onCloseChannel = onCloseChannel, |
| 1237 | + | onRuleViolationChannel = onRuleViolationChannel, |
| 1238 | + | onRuleViolationRemove = onRuleViolationRemove, |
| 1239 | + | onRuleViolationCancel = onRuleViolationCancel, |
| 1240 | + | onRuleViolationLock = onRuleViolationLock, |
| 1241 | + | onGameEnd = onGameEnd, |
| 1242 | + | onGameStart = onGameStart |
| 1243 | + | }) |
| 1244 | + | chatWindow:destroy() |
| 1245 | + | end |
| 1246 | + | |
| 1247 | + | function save() |
| 1248 | + | local settings = { |
| 1249 | + | messageHistory = messageHistory |
| 1250 | + | } |
| 1251 | + | |
| 1252 | + | g_settings.setNode("game_chat", settings) |
| 1253 | + | end |
| 1254 | + | |
| 1255 | + | function load() |
| 1256 | + | local settings = g_settings.getNode("game_chat") |
| 1257 | + | |
| 1258 | + | if settings then |
| 1259 | + | messageHistory = settings.messageHistory or {} |
| 1260 | + | end |
| 1261 | + | |
| 1262 | + | loadCommunicationSettings() |
| 1263 | + | end |
| 1264 | + | |
| 1265 | + | function onTabChange(tabBar, tab) |
| 1266 | + | -- Para los tabs donde se envían mensajes se mantiene el TextEdit activo |
| 1267 | + | if tab == defaultTab or tab == serverTab then |
| 1268 | + | chatWindow.closeChannelButton:disable() |
| 1269 | + | textEdit:setEnabled(true) |
| 1270 | + | else |
| 1271 | + | chatWindow.closeChannelButton:enable() |
| 1272 | + | textEdit:setEnabled(true) |
| 1273 | + | end |
| 1274 | + | end |
| 1275 | + | |
| 1276 | + | function clear() |
| 1277 | + | local lastChannelsOpen = g_settings.getNode("lastChannelsOpen") or {} |
| 1278 | + | local char = g_game.getCharacterName() |
| 1279 | + | local savedChannels = {} |
| 1280 | + | local set = false |
| 1281 | + | |
| 1282 | + | for channelId, channelName in pairs(channels) do |
| 1283 | + | if type(channelId) == "number" then |
| 1284 | + | savedChannels[channelName] = channelId |
| 1285 | + | set = true |
| 1286 | + | end |
| 1287 | + | end |
| 1288 | + | |
| 1289 | + | if set then |
| 1290 | + | lastChannelsOpen[char] = savedChannels |
| 1291 | + | else |
| 1292 | + | lastChannelsOpen[char] = nil |
| 1293 | + | end |
| 1294 | + | |
| 1295 | + | g_settings.setNode("lastChannelsOpen", lastChannelsOpen) |
| 1296 | + | |
| 1297 | + | for _, channelName in pairs(channels) do |
| 1298 | + | local tab = consoleTabBar:getTab(channelName) |
| 1299 | + | |
| 1300 | + | consoleTabBar:removeTab(tab) |
| 1301 | + | end |
| 1302 | + | |
| 1303 | + | channels = {} |
| 1304 | + | |
| 1305 | + | consoleTabBar:removeTab(defaultTab) |
| 1306 | + | consoleTabBar:removeTab(serverTab) |
| 1307 | + | |
| 1308 | + | local npcTab = consoleTabBar:getTab("NPCs") |
| 1309 | + | |
| 1310 | + | if npcTab then |
| 1311 | + | consoleTabBar:removeTab(npcTab) |
| 1312 | + | end |
| 1313 | + | |
| 1314 | + | if violationReportTab then |
| 1315 | + | consoleTabBar:removeTab(violationReportTab) |
| 1316 | + | |
| 1317 | + | violationReportTab = nil |
| 1318 | + | end |
| 1319 | + | |
| 1320 | + | textEdit:clearText() |
| 1321 | + | |
| 1322 | + | if violationWindow then |
| 1323 | + | violationWindow:destroy() |
| 1324 | + | |
| 1325 | + | violationWindow = nil |
| 1326 | + | end |
| 1327 | + | |
| 1328 | + | if channelsWindow then |
| 1329 | + | channelsWindow:destroy() |
| 1330 | + | |
| 1331 | + | channelsWindow = nil |
| 1332 | + | end |
| 1333 | + | end |
| 1334 | + | |
| 1335 | + | function onGameStart() |
| 1336 | + | isOnline = true |
| 1337 | + | defaultTab = addTab(tr("Default"), true) |
| 1338 | + | serverTab = addTab(tr("Server Log"), false) |
| 1339 | + | |
| 1340 | + | if g_game.getClientVersion() < 862 then |
| 1341 | + | g_keyboard.bindKeyDown("Ctrl+R", openPlayerReportRuleViolationWindow) |
| 1342 | + | end |
| 1343 | + | |
| 1344 | + | local lastChannelsOpen = g_settings.getNode("lastChannelsOpen") |
| 1345 | + | |
| 1346 | + | if lastChannelsOpen then |
| 1347 | + | local savedChannels = lastChannelsOpen[g_game.getCharacterName()] |
| 1348 | + | |
| 1349 | + | if savedChannels then |
| 1350 | + | for channelName, channelId in pairs(savedChannels) do |
| 1351 | + | channelId = tonumber(channelId) |
| 1352 | + | |
| 1353 | + | if channelId ~= -1 and channelId < 100 and not table.find(channels, channelId) then |
| 1354 | + | g_game.joinChannel(channelId) |
| 1355 | + | table.insert(ignoredChannels, channelId) |
| 1356 | + | end |
| 1357 | + | end |
| 1358 | + | end |
| 1359 | + | end |
| 1360 | + | |
| 1361 | + | scheduleEvent(function () |
| 1362 | + | ignoredChannels = {} |
| 1363 | + | end, 3000) |
| 1364 | + | |
| 1365 | + | local lB = chatWindow.lockButton |
| 1366 | + | |
| 1367 | + | if chatLocked then |
| 1368 | + | chatWindow:setPhantom(true) |
| 1369 | + | enableResize(false) |
| 1370 | + | lB:setImageSource("/images/game/chat/lockSmall") |
| 1371 | + | |
| 1372 | + | function lB.onHoverChange(s, h) |
| 1373 | + | if h then |
| 1374 | + | s:setImageSource("/images/game/chat/unlockSmall") |
| 1375 | + | else |
| 1376 | + | s:setImageSource("/images/game/chat/lockSmall") |
| 1377 | + | end |
| 1378 | + | end |
| 1379 | + | else |
| 1380 | + | chatWindow:setPhantom(false) |
| 1381 | + | |
| 1382 | + | if not options.classicChat then |
| 1383 | + | enableResize(true) |
| 1384 | + | end |
| 1385 | + | |
| 1386 | + | lB:setImageSource("/images/game/chat/unlockSmall") |
| 1387 | + | |
| 1388 | + | function lB.onHoverChange(s, h) |
| 1389 | + | if h then |
| 1390 | + | s:setImageSource("/images/game/chat/lockSmall") |
| 1391 | + | else |
| 1392 | + | s:setImageSource("/images/game/chat/unlockSmall") |
| 1393 | + | end |
| 1394 | + | end |
| 1395 | + | chatLocked = false |
| 1396 | + | end |
| 1397 | + | |
| 1398 | + | local cB = chatWindow.configButton |
| 1399 | + | |
| 1400 | + | cB:setImageSource("/images/game/chat/configSmall") |
| 1401 | + | show() |
| 1402 | + | end |
| 1403 | + | |
| 1404 | + | function enableResize(e) |
| 1405 | + | if e then |
| 1406 | + | chatWindow.rB:setVisible(true) |
| 1407 | + | chatWindow.rB2:setVisible(true) |
| 1408 | + | chatWindow.rB3:setVisible(true) |
| 1409 | + | chatWindow.rB4:setVisible(true) |
| 1410 | + | else |
| 1411 | + | chatWindow.rB:setVisible(false) |
| 1412 | + | chatWindow.rB2:setVisible(false) |
| 1413 | + | chatWindow.rB3:setVisible(false) |
| 1414 | + | chatWindow.rB4:setVisible(false) |
| 1415 | + | end |
| 1416 | + | end |
| 1417 | + | |
| 1418 | + | function onGameEnd() |
| 1419 | + | isOnline = false |
| 1420 | + | |
| 1421 | + | hide() |
| 1422 | + | clear() |
| 1423 | + | end |
| 1424 | + | |
| 1425 | + | function clickLockButton() |
| 1426 | + | local lB = chatWindow.lockButton |
| 1427 | + | |
| 1428 | + | if chatLocked then |
| 1429 | + | if not options.classicChat then |
| 1430 | + | chatWindow:setPhantom(false) |
| 1431 | + | enableResize(true) |
| 1432 | + | end |
| 1433 | + | |
| 1434 | + | lB:setImageSource("/images/game/chat/lockSmall") |
| 1435 | + | |
| 1436 | + | function lB.onHoverChange(s, h) |
| 1437 | + | if h then |
| 1438 | + | s:setImageSource("/images/game/chat/lockSmall") |
| 1439 | + | else |
| 1440 | + | s:setImageSource("/images/game/chat/unlockSmall") |
| 1441 | + | end |
| 1442 | + | end |
| 1443 | + | |
| 1444 | + | chatLocked = false |
| 1445 | + | else |
| 1446 | + | chatWindow:setPhantom(true) |
| 1447 | + | enableResize(false) |
| 1448 | + | lB:setImageSource("/images/game/chat/unlockSmall") |
| 1449 | + | |
| 1450 | + | function lB.onHoverChange(s, h) |
| 1451 | + | if h then |
| 1452 | + | s:setImageSource("/images/game/chat/unlockSmall") |
| 1453 | + | else |
| 1454 | + | s:setImageSource("/images/game/chat/lockSmall") |
| 1455 | + | end |
| 1456 | + | end |
| 1457 | + | |
| 1458 | + | chatLocked = true |
| 1459 | + | end |
| 1460 | + | end |
| 1461 | + | |
| 1462 | + | function onTalk(name, level, mode, message, channelId, creaturePos) |
| 1463 | + | if mode == 44 then |
| 1464 | + | ChatStatusActivated = true |
| 1465 | + | else |
| 1466 | + | ChatStatusActivated = false |
| 1467 | + | end |
| 1468 | + | |
| 1469 | + | if mode == MessageModes.GamemasterBroadcast then |
| 1470 | + | modules.game_textmessage.displayBroadcastMessage(name .. ": " .. message) |
| 1471 | + | |
| 1472 | + | return |
| 1473 | + | end |
| 1474 | + | |
| 1475 | + | if ignoreNpcMessages and mode == MessageModes.NpcFrom then |
| 1476 | + | return |
| 1477 | + | end |
| 1478 | + | |
| 1479 | + | speaktype = SpeakTypes[mode] |
| 1480 | + | |
| 1481 | + | if not speaktype then |
| 1482 | + | perror("unhandled onTalk message mode " .. mode .. ": " .. message) |
| 1483 | + | |
| 1484 | + | return |
| 1485 | + | end |
| 1486 | + | |
| 1487 | + | local localPlayer = g_game.getLocalPlayer() |
| 1488 | + | |
| 1489 | + | if name ~= g_game.getCharacterName() and isUsingIgnoreList() and not isUsingWhiteList() or isUsingWhiteList() and not isWhitelisted(name) and (not isAllowingVIPs() or not localPlayer:hasVip(name)) then |
| 1490 | + | if mode == MessageModes.Yell and isIgnoringYelling() then |
| 1491 | + | return |
| 1492 | + | elseif speaktype.private and isIgnoringPrivate() and mode ~= MessageModes.NpcFrom then |
| 1493 | + | return |
| 1494 | + | elseif isIgnored(name) then |
| 1495 | + | return |
| 1496 | + | end |
| 1497 | + | end |
| 1498 | + | |
| 1499 | + | if mode == MessageModes.RVRChannel then |
| 1500 | + | channelId = violationsChannelId |
| 1501 | + | end |
| 1502 | + | |
| 1503 | + | if (mode == MessageModes.Say or mode == MessageModes.Whisper or mode == MessageModes.Yell or mode == MessageModes.Spell or mode == MessageModes.MonsterSay or mode == MessageModes.MonsterYell or mode == MessageModes.NpcFrom or mode == MessageModes.BarkLow or mode == MessageModes.BarkLoud) and creaturePos then |
| 1504 | + | local staticMessage = message |
| 1505 | + | |
| 1506 | + | if mode == MessageModes.NpcFrom then |
| 1507 | + | local highlightData = getHighlightedText(staticMessage) |
| 1508 | + | |
| 1509 | + | if #highlightData > 0 then |
| 1510 | + | for i = 1, #highlightData / 3 do |
| 1511 | + | local dataBlock = { |
| 1512 | + | _start = highlightData[(i - 1) * 3 + 1], |
| 1513 | + | _end = highlightData[(i - 1) * 3 + 2], |
| 1514 | + | words = highlightData[(i - 1) * 3 + 3] |
| 1515 | + | } |
| 1516 | + | staticMessage = staticMessage:gsub("{" .. dataBlock.words .. "}", dataBlock.words) |
| 1517 | + | end |
| 1518 | + | end |
| 1519 | + | end |
| 1520 | + | |
| 1521 | + | local staticText = StaticText.create() |
| 1522 | + | |
| 1523 | + | staticText:addMessage(name, mode, staticMessage) |
| 1524 | + | g_map.addThing(staticText, creaturePos, -1) |
| 1525 | + | end |
| 1526 | + | |
| 1527 | + | local defaultMessage = mode <= 3 and true or false |
| 1528 | + | |
| 1529 | + | if speaktype == SpeakTypesSettings.none then |
| 1530 | + | return |
| 1531 | + | end |
| 1532 | + | |
| 1533 | + | if speaktype.hideInConsole then |
| 1534 | + | return |
| 1535 | + | end |
| 1536 | + | |
| 1537 | + | local composedMessage = applyMessagePrefixies(name, level, message) |
| 1538 | + | if mode == MessageModes.RVRAnswer then |
| 1539 | + | violationReportTab.locked = false |
| 1540 | + | addTabText(composedMessage, speaktype, violationReportTab, name) |
| 1541 | + | elseif mode == MessageModes.RVRContinue then |
| 1542 | + | addText(composedMessage, speaktype, name .. "'...", name) |
| 1543 | + | elseif speaktype.private then |
| 1544 | + | addPrivateText(composedMessage, speaktype, name, false, name) |
| 1545 | + | if modules.client_options.getOption("showPrivateMessagesOnScreen") and speaktype ~= SpeakTypesSettings.privateNpcToPlayer then |
| 1546 | + | modules.game_textmessage.displayPrivateMessage(name .. ":\n" .. message) |
| 1547 | + | end |
| 1548 | + | else |
| 1549 | + | local channel = channels[channelId] or tr("Default") |
| 1550 | + | if channel then |
| 1551 | + | ChatControlStatus = mode |
| 1552 | + | local player = g_game.getLocalPlayer() |
| 1553 | + | local playerName = g_game.getCharacterName() |
| 1554 | + | local level = player and player:getLevel() or 0 |
| 1555 | + | -- Normalizar el nombre del canal para la búsqueda en CHANNEL_COLOR_MAP |
| 1556 | + | local channelKey = normalizeChannelName(channel) |
| 1557 | + | local channelColor = CHANNEL_COLOR_MAP[channelKey] or speaktype.color |
| 1558 | + | local finalMessage = string.format("Chat->[%s]->[%s] [%d]: %s", channel, playerName, level, message) |
| 1559 | + | local modifiedSpeakType = table.copy(speaktype) |
| 1560 | + | modifiedSpeakType.color = channelColor |
| 1561 | + | addText(finalMessage, modifiedSpeakType, channel, name) |
| 1562 | + | else |
| 1563 | + | pwarning("message in channel id " .. channelId .. " which is unknown, relogin if you want to see messages in this channel") |
| 1564 | + | end |
| 1565 | + | end |
| 1566 | + | end |
| 1567 | + | |
| 1568 | + | function onOpenChannel(channelId, channelName) |
| 1569 | + | addChannel(channelName, channelId) |
| 1570 | + | end |
| 1571 | + | |
| 1572 | + | function onOpenPrivateChannel(receiver) |
| 1573 | + | addPrivateChannel(receiver) |
| 1574 | + | end |
| 1575 | + | |
| 1576 | + | function onOpenOwnPrivateChannel(channelId, channelName) |
| 1577 | + | local privateTab = getTab(channelName) |
| 1578 | + | |
| 1579 | + | if privateTab == nil then |
| 1580 | + | addChannel(channelName, channelId) |
| 1581 | + | end |
| 1582 | + | |
| 1583 | + | ownPrivateName = channelName |
| 1584 | + | end |
| 1585 | + | |
| 1586 | + | function onCloseChannel(channelId) |
| 1587 | + | local channel = channels[channelId] |
| 1588 | + | |
| 1589 | + | if channel then |
| 1590 | + | local tab = getTab(channel) |
| 1591 | + | |
| 1592 | + | if tab then |
| 1593 | + | consoleTabBar:removeTab(tab) |
| 1594 | + | end |
| 1595 | + | |
| 1596 | + | for k, v in pairs(channels) do |
| 1597 | + | if k == tab.channelId then |
| 1598 | + | channels[k] = nil |
| 1599 | + | end |
| 1600 | + | end |
| 1601 | + | end |
| 1602 | + | end |
| 1603 | + | |
| 1604 | + | function processViolation(name, text) |
| 1605 | + | local tabname = name .. "'..." |
| 1606 | + | local tab = addTab(tabname, true) |
| 1607 | + | channels[tabname] = tabname |
| 1608 | + | tab.violationChatName = name |
| 1609 | + | |
| 1610 | + | g_game.openRuleViolation(name) |
| 1611 | + | addTabText(text, SpeakTypesSettings.say, tab, name) |
| 1612 | + | end |
| 1613 | + | |
| 1614 | + | function onRuleViolationChannel(channelId) |
| 1615 | + | violationsChannelId = channelId |
| 1616 | + | local tab = addChannel(tr("Rule Violations"), channelId) |
| 1617 | + | tab.violations = true |
| 1618 | + | end |
| 1619 | + | |
| 1620 | + | function onRuleViolationRemove(name) |
| 1621 | + | local tab = getRuleViolationsTab() |
| 1622 | + | |
| 1623 | + | if not tab then |
| 1624 | + | return |
| 1625 | + | end |
| 1626 | + | |
| 1627 | + | removeTabLabelByName(tab, name) |
| 1628 | + | end |
| 1629 | + | |
| 1630 | + | function onRuleViolationCancel(name) |
| 1631 | + | local tab = getTab(name .. "'...") |
| 1632 | + | |
| 1633 | + | if not tab then |
| 1634 | + | return |
| 1635 | + | end |
| 1636 | + | |
| 1637 | + | addTabText(tr("%s has finished the request", name) .. ".", SpeakTypesSettings.privateRed, tab) |
| 1638 | + | |
| 1639 | + | tab.locked = true |
| 1640 | + | end |
| 1641 | + | |
| 1642 | + | function onRuleViolationLock() |
| 1643 | + | if not violationReportTab then |
| 1644 | + | return |
| 1645 | + | end |
| 1646 | + | |
| 1647 | + | violationReportTab.locked = false |
| 1648 | + | |
| 1649 | + | addTabText(tr("Your request has been closed") .. ".", SpeakTypesSettings.privateRed, violationReportTab) |
| 1650 | + | |
| 1651 | + | violationReportTab.locked = true |
| 1652 | + | end |
| 1653 | + | |
| 1654 | + | function show() |
| 1655 | + | local player = g_game.getLocalPlayer() |
| 1656 | + | |
| 1657 | + | if not chatWindow:isVisible() or chatWindow:getOpacity() < 0.95 then |
| 1658 | + | addEvent(function () |
| 1659 | + | g_effects.fadeIn(chatWindow, 250, 0, 237.5) |
| 1660 | + | end) |
| 1661 | + | end |
| 1662 | + | |
| 1663 | + | chatWindow:show() |
| 1664 | + | |
| 1665 | + | return true |
| 1666 | + | end |
| 1667 | + | |
| 1668 | + | function showConfigs() |
| 1669 | + | configWindow:show() |
| 1670 | + | |
| 1671 | + | local cC = configWindow.configsContent |
| 1672 | + | local oBAV = cC.backgroundAlwaysVisible |
| 1673 | + | local oCC = cC.classicChat |
| 1674 | + | local oCAA = cC.chatAlwaysActive |
| 1675 | + | local WASD = cC.chatAlwaysActiveEnableWASD |
| 1676 | + | |
| 1677 | + | WASD:setEnabled(oBAV:isChecked()) |
| 1678 | + | oCC:setEnabled(oBAV:isChecked()) |
| 1679 | + | oCAA:setEnabled(oBAV:isChecked()) |
| 1680 | + | end |
| 1681 | + | |
| 1682 | + | function hideConfigs() |
| 1683 | + | configWindow:hide() |
| 1684 | + | end |
| 1685 | + | |
| 1686 | + | function clickConfigButton() |
| 1687 | + | if configWindow:isVisible() then |
| 1688 | + | configWindow:hide() |
| 1689 | + | else |
| 1690 | + | showConfigs() |
| 1691 | + | end |
| 1692 | + | end |
| 1693 | + | |
| 1694 | + | function getrB3() |
| 1695 | + | return chatWindow.backgroundkeys |
| 1696 | + | end |
| 1697 | + | |
| 1698 | + | function setOption(key, value, force) |
| 1699 | + | if not force and options[key] == value then |
| 1700 | + | return |
| 1701 | + | end |
| 1702 | + | |
| 1703 | + | local gameMapPanel = modules.game_interface.getMapPanel() |
| 1704 | + | |
| 1705 | + | if key == "backgroundAlwaysVisible" then |
| 1706 | + | configWindow.configsContent.classicChat:setEnabled(value) |
| 1707 | + | configWindow.configsContent.chatAlwaysActive:setEnabled(value) |
| 1708 | + | configWindow.configsContent.chatAlwaysActiveEnableWASD:setEnabled(value) |
| 1709 | + | |
| 1710 | + | if not value then |
| 1711 | + | options.classicChat = value |
| 1712 | + | options.chatAlwaysActive = value |
| 1713 | + | options.chatAlwaysActiveEnableWASD = value |
| 1714 | + | end |
| 1715 | + | elseif key == "classicChat" then |
| 1716 | + | modules.game_interface.getBottomPanel():setOn(value) |
| 1717 | + | |
| 1718 | + | local cSB = chatWindow:recursiveGetChildById("consoleScrollBar") |
| 1719 | + | |
| 1720 | + | if value then |
| 1721 | + | chatWindow:fill("gameBottomPanel") |
| 1722 | + | cSB:setMarginBottom(22) |
| 1723 | + | enableResize(false) |
| 1724 | + | chatWindow:setDraggable(false) |
| 1725 | + | modules.game_interface.bottomSplitter:setVisible(true) |
| 1726 | + | else |
| 1727 | + | chatWindow:setSize("551 255") |
| 1728 | + | chatWindow:removeAnchor(AnchorTop) |
| 1729 | + | chatWindow:removeAnchor(AnchorRight) |
| 1730 | + | chatWindow:addAnchor(AnchorBottom, "parent", AnchorBottom) |
| 1731 | + | chatWindow:addAnchor(AnchorLeft, "parent", AnchorLeft) |
| 1732 | + | cSB:setMarginBottom(0) |
| 1733 | + | enableResize(true) |
| 1734 | + | chatWindow:setDraggable(true) |
| 1735 | + | modules.game_interface.bottomSplitter:setVisible(false) |
| 1736 | + | end |
| 1737 | + | |
| 1738 | + | chatWindow:setPhantom(value) |
| 1739 | + | elseif key == "showFps" then |
| 1740 | + | modules.client_topmenu.setFpsVisible(value) |
| 1741 | + | modules.client_botmenu.setFpsVisible(value) |
| 1742 | + | elseif key == "fullscreen" then |
| 1743 | + | g_window.setFullscreen(value) |
| 1744 | + | end |
| 1745 | + | |
| 1746 | + | g_settings.set(key, value) |
| 1747 | + | |
| 1748 | + | if configWindow.configsContent.chatAlwaysActiveEnableWASD:isChecked() then |
| 1749 | + | modules.game_walking.enableWSAD() |
| 1750 | + | elseif configWindow.configsContent.chatAlwaysActive:isChecked() then |
| 1751 | + | modules.game_walking.disableWSAD() |
| 1752 | + | end |
| 1753 | + | |
| 1754 | + | options[key] = value |
| 1755 | + | end |
| 1756 | + | |
| 1757 | + | function getOption(key) |
| 1758 | + | return options[key] |
| 1759 | + | end |
| 1760 | + | |
| 1761 | + | function toggleChat() |
| 1762 | + | local gameInterface = modules.game_interface |
| 1763 | + | |
| 1764 | + | if isActive() and not configWindow.configsContent.chatAlwaysActive:isChecked() then |
| 1765 | + | modules.game_walking.enableWSAD() |
| 1766 | + | end |
| 1767 | + | |
| 1768 | + | if not isActive() then |
| 1769 | + | modules.game_walking.disableWSAD() |
| 1770 | + | chatWindow:setFocusable(true) |
| 1771 | + | chatWindow:setVisible(true) |
| 1772 | + | chatWindow:focus() |
| 1773 | + | hk = false |
| 1774 | + | emotesPanel:destroyChildren() |
| 1775 | + | |
| 1776 | + | for i = 1, #emotesTable do |
| 1777 | + | emoticon = g_ui.createWidget("EmotesButtonUI", emotesPanel) |
| 1778 | + | |
| 1779 | + | emoticon:setText(emotesTable[i].type) |
| 1780 | + | |
| 1781 | + | function emoticon.onClick() |
| 1782 | + | textEdit:setText(textEdit:getText() .. "" .. emotesTable[i].type) |
| 1783 | + | textEdit:setCursorPos(1) |
| 1784 | + | doCloseWindowEmoticons() -- Se cierra el panel al seleccionar el emote |
| 1785 | + | end |
| 1786 | + | end |
| 1787 | + | |
| 1788 | + | chatWindow.textEdit:setFocusable(true) |
| 1789 | + | else |
| 1790 | + | -- Al cerrar el chat, se reactivan las teclas de movimiento |
| 1791 | + | chatWindow:setFocusable(false) |
| 1792 | + | chatWindow:setVisible(false) |
| 1793 | + | chatWindow.textEdit:setFocusable(false) |
| 1794 | + | hk = true |
| 1795 | + | modules.game_walking.enableWSAD() |
| 1796 | + | end |
| 1797 | + | end |
| 1798 | + | |
| 1799 | + | function doCloseWindowEmoticons() |
| 1800 | + | if backgroundEmotes:isVisible() then |
| 1801 | + | backgroundEmotes:setVisible(false) |
| 1802 | + | EmotesButton:setImageSource("/images/game/chat/icons/emotes") |
| 1803 | + | end |
| 1804 | + | end |
| 1805 | + | |
| 1806 | + | function doShowWindowEmoticons() |
| 1807 | + | if not backgroundEmotes:isVisible() then |
| 1808 | + | backgroundEmotes:setVisible(true) |
| 1809 | + | EmotesButton:setImageSource("/images/game/chat/icons/emote_light") |
| 1810 | + | emotesPanel:destroyChildren() |
| 1811 | + | for i = 1, #emotesTable do |
| 1812 | + | emoticon = g_ui.createWidget("EmotesButtonUI", emotesPanel) |
| 1813 | + | emoticon:setText(emotesTable[i].type) |
| 1814 | + | function emoticon.onClick() |
| 1815 | + | textEdit:setText(textEdit:getText() .. emotesTable[i].type) |
| 1816 | + | textEdit:setCursorPos(-1) |
| 1817 | + | doCloseWindowEmoticons() -- Se cierra el panel al seleccionar el emote |
| 1818 | + | end |
| 1819 | + | end |
| 1820 | + | end |
| 1821 | + | end |
| 1822 | + | |
| 1823 | + | function doToggleWindowEmoticons() |
| 1824 | + | if backgroundEmotes:isVisible() then |
| 1825 | + | doCloseWindowEmoticons() |
| 1826 | + | else |
| 1827 | + | doShowWindowEmoticons() |
| 1828 | + | end |
| 1829 | + | end |
| 1830 | + | |
| 1831 | + | function doChannelListSubmit() |
| 1832 | + | local channelListPanel = channelsWindow.channelList |
| 1833 | + | local openPrivateChannelWith = channelsWindow.openPrivateChannelWith:getText() |
| 1834 | + | if openPrivateChannelWith ~= "" then |
| 1835 | + | if openPrivateChannelWith:lower() ~= g_game.getCharacterName():lower() then |
| 1836 | + | g_game.openPrivateChannel(openPrivateChannelWith) |
| 1837 | + | else |
| 1838 | + | modules.game_textmessage.displayFailureMessage("You cannot create a private chat channel with yourself.") |
| 1839 | + | end |
| 1840 | + | else |
| 1841 | + | local selectedChannelLabel = channelListPanel:getFocusedChild() |
| 1842 | + | if not selectedChannelLabel then return end |
| 1843 | + | local chId = tonumber(selectedChannelLabel.channelId) |
| 1844 | + | if chId == 65535 then |
| 1845 | + | g_game.openOwnChannel() |
| 1846 | + | elseif chId then |
| 1847 | + | g_game.joinChannel(chId) |
| 1848 | + | end |
| 1849 | + | end |
| 1850 | + | channelsWindow:destroy() |
| 1851 | + | end |
| 1852 | + | |
| 1853 | + | function onChannelList(channelList) |
| 1854 | + | if channelsWindow then |
| 1855 | + | channelsWindow:destroy() |
| 1856 | + | end |
| 1857 | + | channelsWindow = g_ui.displayUI("channelswindow") |
| 1858 | + | local channelListPanel = channelsWindow.channelList |
| 1859 | + | channelsWindow.onEnter = doChannelListSubmit |
| 1860 | + | function channelsWindow.onDestroy() |
| 1861 | + | channelsWindow = nil |
| 1862 | + | end |
| 1863 | + | g_keyboard.bindKeyPress("Down", function () |
| 1864 | + | channelListPanel:focusNextChild(KeyboardFocusReason) |
| 1865 | + | end, channelsWindow) |
| 1866 | + | g_keyboard.bindKeyPress("Up", function () |
| 1867 | + | channelListPanel:focusPreviousChild(KeyboardFocusReason) |
| 1868 | + | end, channelsWindow) |
| 1869 | + | for k, v in pairs(channelList) do |
| 1870 | + | local channelId = tonumber(v[1]) |
| 1871 | + | local channelName = v[2] |
| 1872 | + | if #channelName > 0 then |
| 1873 | + | local label = g_ui.createWidget("ChannelListLabel", channelListPanel) |
| 1874 | + | label.channelId = channelId |
| 1875 | + | label:setText(channelName) |
| 1876 | + | label:setPhantom(false) |
| 1877 | + | label.onDoubleClick = doChannelListSubmit |
| 1878 | + | end |
| 1879 | + | end |
| 1880 | + | end |
| 1881 | + | |
| 1882 | + | function loadCommunicationSettings() |
| 1883 | + | communicationSettings.whitelistedPlayers = {} |
| 1884 | + | communicationSettings.ignoredPlayers = {} |
| 1885 | + | local ignoreNode = g_settings.getNode("IgnorePlayers") |
| 1886 | + | |
| 1887 | + | if ignoreNode then |
| 1888 | + | for i = 1, #ignoreNode do |
| 1889 | + | table.insert(communicationSettings.ignoredPlayers, ignoreNode[i]) |
| 1890 | + | end |
| 1891 | + | end |
| 1892 | + | |
| 1893 | + | local whitelistNode = g_settings.getNode("WhitelistedPlayers") |
| 1894 | + | |
| 1895 | + | if whitelistNode then |
| 1896 | + | for i = 1, #whitelistNode do |
| 1897 | + | table.insert(communicationSettings.whitelistedPlayers, whitelistNode[i]) |
| 1898 | + | end |
| 1899 | + | end |
| 1900 | + | |
| 1901 | + | communicationSettings.useIgnoreList = g_settings.getBoolean("UseIgnoreList") |
| 1902 | + | communicationSettings.useWhiteList = g_settings.getBoolean("UseWhiteList") |
| 1903 | + | communicationSettings.privateMessages = g_settings.getBoolean("IgnorePrivateMessages") |
| 1904 | + | communicationSettings.yelling = g_settings.getBoolean("IgnoreYelling") |
| 1905 | + | communicationSettings.allowVIPs = g_settings.getBoolean("AllowVIPs") |
| 1906 | + | end |
| 1907 | + | |
| 1908 | + | function saveCommunicationSettings() |
| 1909 | + | local tmpIgnoreList = {} |
| 1910 | + | local ignoredPlayers = getIgnoredPlayers() |
| 1911 | + | |
| 1912 | + | for i = 1, #ignoredPlayers do |
| 1913 | + | table.insert(tmpIgnoreList, ignoredPlayers[i]) |
| 1914 | + | end |
| 1915 | + | |
| 1916 | + | local tmpWhiteList = {} |
| 1917 | + | local whitelistedPlayers = getWhitelistedPlayers() |
| 1918 | + | |
| 1919 | + | for i = 1, #whitelistedPlayers do |
| 1920 | + | table.insert(tmpWhiteList, whitelistedPlayers[i]) |
| 1921 | + | end |
| 1922 | + | |
| 1923 | + | g_settings.set("UseIgnoreList", communicationSettings.useIgnoreList) |
| 1924 | + | g_settings.set("UseWhiteList", communicationSettings.useWhiteList) |
| 1925 | + | g_settings.set("IgnorePrivateMessages", communicationSettings.privateMessages) |
| 1926 | + | g_settings.set("IgnoreYelling", communicationSettings.yelling) |
| 1927 | + | g_settings.setNode("IgnorePlayers", tmpIgnoreList) |
| 1928 | + | g_settings.setNode("WhitelistedPlayers", tmpWhiteList) |
| 1929 | + | end |
| 1930 | + | |
| 1931 | + | function getIgnoredPlayers() |
| 1932 | + | return communicationSettings.ignoredPlayers |
| 1933 | + | end |
| 1934 | + | |
| 1935 | + | function getWhitelistedPlayers() |
| 1936 | + | return communicationSettings.whitelistedPlayers |
| 1937 | + | end |
| 1938 | + | |
| 1939 | + | function isUsingIgnoreList() |
| 1940 | + | return communicationSettings.useIgnoreList |
| 1941 | + | end |
| 1942 | + | |
| 1943 | + | function isUsingWhiteList() |
| 1944 | + | return communicationSettings.useWhiteList |
| 1945 | + | end |
| 1946 | + | |
| 1947 | + | function isIgnored(name) |
| 1948 | + | return table.find(communicationSettings.ignoredPlayers, name, true) |
| 1949 | + | end |
| 1950 | + | |
| 1951 | + | function addIgnoredPlayer(name) |
| 1952 | + | if isIgnored(name) then |
| 1953 | + | return |
| 1954 | + | end |
| 1955 | + | |
| 1956 | + | table.insert(communicationSettings.ignoredPlayers, name) |
| 1957 | + | end |
| 1958 | + | |
| 1959 | + | function removeIgnoredPlayer(name) |
| 1960 | + | table.removevalue(communicationSettings.ignoredPlayers, name) |
| 1961 | + | end |
| 1962 | + | |
| 1963 | + | function isWhitelisted(name) |
| 1964 | + | return table.find(communicationSettings.whitelistedPlayers, name, true) |
| 1965 | + | end |
| 1966 | + | |
| 1967 | + | function addWhitelistedPlayer(name) |
| 1968 | + | if isWhitelisted(name) then |
| 1969 | + | return |
| 1970 | + | end |
| 1971 | + | |
| 1972 | + | table.insert(communicationSettings.whitelistedPlayers, name) |
| 1973 | + | end |
| 1974 | + | |
| 1975 | + | function removeWhitelistedPlayer(name) |
| 1976 | + | table.removevalue(communicationSettings.whitelistedPlayers, name) |
| 1977 | + | end |
| 1978 | + | |
| 1979 | + | function isIgnoringPrivate() |
| 1980 | + | return communicationSettings.privateMessages |
| 1981 | + | end |
| 1982 | + | |
| 1983 | + | function isIgnoringYelling() |
| 1984 | + | return communicationSettings.yelling |
| 1985 | + | end |
| 1986 | + | |
| 1987 | + | function isAllowingVIPs() |
| 1988 | + | return communicationSettings.allowVIPs |
| 1989 | + | end |
| 1990 | + | |
| 1991 | + | function onClickIgnoreButton() |
| 1992 | + | if communicationWindow then |
| 1993 | + | return |
| 1994 | + | end |
| 1995 | + | |
| 1996 | + | communicationWindow = g_ui.displayUI("communicationwindow") |
| 1997 | + | local ignoreListPanel = communicationWindow.ignoreList |
| 1998 | + | local whiteListPanel = communicationWindow.whiteList |
| 1999 | + | |
| 2000 | + | function communicationWindow.onDestroy() |
| 2001 | + | communicationWindow = nil |
| 2002 | + | end |
| 2003 | + | |
| 2004 | + | local useIgnoreListBox = communicationWindow.checkboxUseIgnoreList |
| 2005 | + | |
| 2006 | + | useIgnoreListBox:setChecked(communicationSettings.useIgnoreList) |
| 2007 | + | |
| 2008 | + | local useWhiteListBox = communicationWindow.checkboxUseWhiteList |
| 2009 | + | |
| 2010 | + | useWhiteListBox:setChecked(communicationSettings.useWhiteList) |
| 2011 | + | |
| 2012 | + | local removeIgnoreButton = communicationWindow.buttonIgnoreRemove |
| 2013 | + | |
| 2014 | + | removeIgnoreButton:disable() |
| 2015 | + | |
| 2016 | + | function ignoreListPanel.onChildFocusChange() |
| 2017 | + | removeIgnoreButton:enable() |
| 2018 | + | end |
| 2019 | + | |
| 2020 | + | function removeIgnoreButton.onClick() |
| 2021 | + | local selection = ignoreListPanel:getFocusedChild() |
| 2022 | + | |
| 2023 | + | if selection then |
| 2024 | + | ignoreListPanel:removeChild(selection) |
| 2025 | + | selection:destroy() |
| 2026 | + | end |
| 2027 | + | |
| 2028 | + | removeIgnoreButton:disable() |
| 2029 | + | end |
| 2030 | + | |
| 2031 | + | local removeWhitelistButton = communicationWindow.buttonWhitelistRemove |
| 2032 | + | |
| 2033 | + | removeWhitelistButton:disable() |
| 2034 | + | |
| 2035 | + | function whiteListPanel.onChildFocusChange() |
| 2036 | + | removeWhitelistButton:enable() |
| 2037 | + | end |
| 2038 | + | |
| 2039 | + | function removeWhitelistButton.onClick() |
| 2040 | + | local selection = whiteListPanel:getFocusedChild() |
| 2041 | + | |
| 2042 | + | if selection then |
| 2043 | + | whiteListPanel:removeChild(selection) |
| 2044 | + | selection:destroy() |
| 2045 | + | end |
| 2046 | + | |
| 2047 | + | removeWhitelistButton:disable() |
| 2048 | + | end |
| 2049 | + | |
| 2050 | + | local newlyIgnoredPlayers = {} |
| 2051 | + | local addIgnoreName = communicationWindow.ignoreNameEdit |
| 2052 | + | local addIgnoreButton = communicationWindow.buttonIgnoreAdd |
| 2053 | + | |
| 2054 | + | local function addIgnoreFunction() |
| 2055 | + | local newEntry = addIgnoreName:getText() |
| 2056 | + | |
| 2057 | + | if newEntry == "" then |
| 2058 | + | return |
| 2059 | + | end |
| 2060 | + | |
| 2061 | + | if table.find(getIgnoredPlayers(), newEntry) then |
| 2062 | + | return |
| 2063 | + | end |
| 2064 | + | |
| 2065 | + | if table.find(newlyIgnoredPlayers, newEntry) then |
| 2066 | + | return |
| 2067 | + | end |
| 2068 | + | |
| 2069 | + | local label = g_ui.createWidget("IgnoreListLabel", ignoreListPanel) |
| 2070 | + | |
| 2071 | + | label:setText(newEntry) |
| 2072 | + | table.insert(newlyIgnoredPlayers, newEntry) |
| 2073 | + | addIgnoreName:setText("") |
| 2074 | + | end |
| 2075 | + | |
| 2076 | + | addIgnoreButton.onClick = addIgnoreFunction |
| 2077 | + | local newlyWhitelistedPlayers = {} |
| 2078 | + | local addWhitelistName = communicationWindow.whitelistNameEdit |
| 2079 | + | local addWhitelistButton = communicationWindow.buttonWhitelistAdd |
| 2080 | + | |
| 2081 | + | local function addWhitelistFunction() |
| 2082 | + | local newEntry = addWhitelistName:getText() |
| 2083 | + | |
| 2084 | + | if newEntry == "" then |
| 2085 | + | return |
| 2086 | + | end |
| 2087 | + | |
| 2088 | + | if table.find(getWhitelistedPlayers(), newEntry) then |
| 2089 | + | return |
| 2090 | + | end |
| 2091 | + | |
| 2092 | + | if table.find(newlyWhitelistedPlayers, newEntry) then |
| 2093 | + | return |
| 2094 | + | end |
| 2095 | + | |
| 2096 | + | local label = g_ui.createWidget("WhiteListLabel", whiteListPanel) |
| 2097 | + | |
| 2098 | + | label:setText(newEntry) |
| 2099 | + | table.insert(newlyWhitelistedPlayers, newEntry) |
| 2100 | + | addWhitelistName:setText("") |
| 2101 | + | end |
| 2102 | + | |
| 2103 | + | addWhitelistButton.onClick = addWhitelistFunction |
| 2104 | + | |
| 2105 | + | function communicationWindow.onEnter() |
| 2106 | + | if addWhitelistName:isFocused() then |
| 2107 | + | addWhitelistFunction() |
| 2108 | + | elseif addIgnoreName:isFocused() then |
| 2109 | + | addIgnoreFunction() |
| 2110 | + | end |
| 2111 | + | end |
| 2112 | + | |
| 2113 | + | local ignorePrivateMessageBox = communicationWindow.checkboxIgnorePrivateMessages |
| 2114 | + | |
| 2115 | + | ignorePrivateMessageBox:setChecked(communicationSettings.privateMessages) |
| 2116 | + | |
| 2117 | + | local ignoreYellingBox = communicationWindow.checkboxIgnoreYelling |
| 2118 | + | |
| 2119 | + | ignoreYellingBox:setChecked(communicationSettings.yelling) |
| 2120 | + | |
| 2121 | + | local allowVIPsBox = communicationWindow.checkboxAllowVIPs |
| 2122 | + | |
| 2123 | + | allowVIPsBox:setChecked(communicationSettings.allowVIPs) |
| 2124 | + | |
| 2125 | + | local saveButton = communicationWindow:recursiveGetChildById("buttonSave") |
| 2126 | + | |
| 2127 | + | function saveButton.onClick() |
| 2128 | + | communicationSettings.ignoredPlayers = {} |
| 2129 | + | |
| 2130 | + | for i = 1, ignoreListPanel:getChildCount() do |
| 2131 | + | addIgnoredPlayer(ignoreListPanel:getChildByIndex(i):getText()) |
| 2132 | + | end |
| 2133 | + | |
| 2134 | + | communicationSettings.whitelistedPlayers = {} |
| 2135 | + | |
| 2136 | + | for i = 1, whiteListPanel:getChildCount() do |
| 2137 | + | addWhitelistedPlayer(whiteListPanel:getChildByIndex(i):getText()) |
| 2138 | + | end |
| 2139 | + | |
| 2140 | + | communicationSettings.useIgnoreList = useIgnoreListBox:isChecked() |
| 2141 | + | communicationSettings.useWhiteList = useWhiteListBox:isChecked() |
| 2142 | + | communicationSettings.yelling = ignoreYellingBox:isChecked() |
| 2143 | + | communicationSettings.privateMessages = ignorePrivateMessageBox:isChecked() |
| 2144 | + | communicationSettings.allowVIPs = allowVIPsBox:isChecked() |
| 2145 | + | |
| 2146 | + | communicationWindow:destroy() |
| 2147 | + | end |
| 2148 | + | |
| 2149 | + | local cancelButton = communicationWindow:recursiveGetChildById("buttonCancel") |
| 2150 | + | |
| 2151 | + | function cancelButton.onClick() |
| 2152 | + | communicationWindow:destroy() |
| 2153 | + | end |
| 2154 | + | |
| 2155 | + | local ignoredPlayers = getIgnoredPlayers() |
| 2156 | + | |
| 2157 | + | for i = 1, #ignoredPlayers do |
| 2158 | + | local label = g_ui.createWidget("IgnoreListLabel", ignoreListPanel) |
| 2159 | + | |
| 2160 | + | label:setText(ignoredPlayers[i]) |
| 2161 | + | end |
| 2162 | + | |
| 2163 | + | local whitelistedPlayers = getWhitelistedPlayers() |
| 2164 | + | |
| 2165 | + | for i = 1, #whitelistedPlayers do |
| 2166 | + | local label = g_ui.createWidget("WhiteListLabel", whiteListPanel) |
| 2167 | + | |
| 2168 | + | label:setText(whitelistedPlayers[i]) |
| 2169 | + | end |
| 2170 | + | end |
| 2171 | + | |
| 2172 | + | function online() |
| 2173 | + | defaultTab = addTab(tr("Default"), true) |
| 2174 | + | serverTab = addTab(tr("Server Log"), false) |
| 2175 | + | |
| 2176 | + | if g_game.getClientVersion() < 862 then |
| 2177 | + | g_keyboard.bindKeyDown("Ctrl+R", openPlayerReportRuleViolationWindow) |
| 2178 | + | end |
| 2179 | + | |
| 2180 | + | local lastChannelsOpen = g_settings.getNode("lastChannelsOpen") |
| 2181 | + | |
| 2182 | + | if lastChannelsOpen then |
| 2183 | + | local savedChannels = lastChannelsOpen[g_game.getCharacterName()] |
| 2184 | + | |
| 2185 | + | if savedChannels then |
| 2186 | + | for channelName, channelId in pairs(savedChannels) do |
| 2187 | + | channelId = tonumber(channelId) |
| 2188 | + | |
| 2189 | + | if channelId ~= -1 and channelId < 100 and not table.find(channels, channelId) then |
| 2190 | + | g_game.joinChannel(channelId) |
| 2191 | + | table.insert(ignoredChannels, channelId) |
| 2192 | + | end |
| 2193 | + | end |
| 2194 | + | end |
| 2195 | + | end |
| 2196 | + | |
| 2197 | + | scheduleEvent(function () |
| 2198 | + | ignoredChannels = {} |
| 2199 | + | end, 3000) |
| 2200 | + | end |
| 2201 | + | |
| 2202 | + | function hide() |
| 2203 | + | g_effects.fadeOut(chatWindow, 200) |
| 2204 | + | scheduleEvent(function () |
| 2205 | + | if not isOnline then |
| 2206 | + | chatWindow:hide() |
| 2207 | + | end |
| 2208 | + | end, 200) |
| 2209 | + | configWindow:hide() |
| 2210 | + | end |
| 2211 | + | |
| 2212 | + | function refreshByUIMode(mode) |
| 2213 | + | local b = chatWindow.background |
| 2214 | + | local tLW = chatWindow.textLineWindow |
| 2215 | + | local cTB = chatWindow.consoleTabBar |
| 2216 | + | local contP = chatWindow.contentPanel |
| 2217 | + | local eB = chatWindow.enterBackground |
| 2218 | + | local pCB = chatWindow.prevChannelButton |
| 2219 | + | local nCB = chatWindow.nextChannelButton |
| 2220 | + | local cCB = chatWindow.closeChannelButton |
| 2221 | + | local cleCB = chatWindow.clearChannelButton |
| 2222 | + | local cB = chatWindow.channelsButton |
| 2223 | + | local iB = chatWindow.ignoreButton |
| 2224 | + | local sMB = chatWindow.sayModeButton |
| 2225 | + | local conOk = configWindow.okButton |
| 2226 | + | local cSB = chatWindow:recursiveGetChildById("consoleScrollBar") |
| 2227 | + | local cSBSlBu = cSB.sliderButton |
| 2228 | + | local cSBDeBu = cSB.decrementButton |
| 2229 | + | local cSBInBu = cSB.incrementButton |
| 2230 | + | local cTBB = cTB:getChildren() |
| 2231 | + | local buttons = { |
| 2232 | + | pCB, |
| 2233 | + | nCB, |
| 2234 | + | cCB, |
| 2235 | + | cleCB, |
| 2236 | + | cB, |
| 2237 | + | iB |
| 2238 | + | } |
| 2239 | + | |
| 2240 | + | b:setImageSource("/images/game/chat/background") |
| 2241 | + | eB:setImageSource("/images/game/chat/textBackground") |
| 2242 | + | configWindow:setImageSource("/images/game/chat/window") |
| 2243 | + | conOk:setImageSource("/images/game/chat/button_rounded") |
| 2244 | + | conOk:setImageBorder(5) |
| 2245 | + | cSBSlBu:setImageSource("/images/game/chat/slider") |
| 2246 | + | cSBDeBu:setImageSource("/images/game/chat/scrollBar") |
| 2247 | + | cSBInBu:setImageSource("/images/game/chat/scrollBar") |
| 2248 | + | |
| 2249 | + | for a = 1, #buttons do |
| 2250 | + | buttons[a]:setImageSource("/images/game/chat/tabBarButtons") |
| 2251 | + | end |
| 2252 | + | |
| 2253 | + | for b = 1, #cTBB do |
| 2254 | + | cTBB[b]:setImageSource("/images/game/chat/channelButtons") |
| 2255 | + | end |
| 2256 | + | end |
| 2257 | + | |
| 2258 | + | function ConfigHotkeys() |
| 2259 | + | -- RESETANDO ATALHOS |
| 2260 | + | -- ...existing code... |
| 2261 | + | -- Agregado: Binding para abrir el chat con la tecla Enter |
| 2262 | + | g_keyboard.bindKeyPress('Enter', function() |
| 2263 | + | if modules.game_chat and modules.game_chat.onOpen then |
| 2264 | + | modules.game_chat.onOpen() -- Ajusta esta llamada según la función que abra el chat |
| 2265 | + | end |
| 2266 | + | end) |
| 2267 | + | -- ...existing code... |
| 2268 | + | end |
| 2269 | + | |
| 2270 | + | emotesTable = { |
| 2271 | + | { type = ":)" }, |
| 2272 | + | { type = ":(" }, |
| 2273 | + | { type = ":D" }, |
| 2274 | + | { type = ":O" }, |
| 2275 | + | { type = ":P" }, |
| 2276 | + | { type = ";)" }, |
| 2277 | + | { type = ":@" }, |
| 2278 | + | { type = ":S" }, |
| 2279 | + | { type = ":Z" }, |
| 2280 | + | { type = ":!" }, |
| 2281 | + | { type = ":?" }, |
| 2282 | + | { type = ":|" }, |
| 2283 | + | { type = ":$" }, |
| 2284 | + | { type = ":X" }, |
| 2285 | + | { type = ":E" }, |
| 2286 | + | { type = ":F" }, |
| 2287 | + | { type = ":H" }, |
| 2288 | + | { type = ":I" }, |
| 2289 | + | { type = ":K" }, |
| 2290 | + | { type = ":L" }, |
| 2291 | + | { type = ":M" }, |
| 2292 | + | { type = ":N" }, |
| 2293 | + | { type = ":Q" }, |
| 2294 | + | { type = ":R" }, |
| 2295 | + | { type = ":T" }, |
| 2296 | + | { type = ":U" }, |
| 2297 | + | { type = ":V" }, |
| 2298 | + | { type = ":Y" }, |
| 2299 | + | { type = ":W" }, |
| 2300 | + | { type = ":G" }, |
| 2301 | + | { type = ":B" }, |
| 2302 | + | { type = ":C" }, |
| 2303 | + | { type = ":A" }, |
| 2304 | + | { type = ":D2" }, |
| 2305 | + | { type = ":O2" }, |
| 2306 | + | { type = ":P2" }, |
| 2307 | + | { type = ":S2" }, |
| 2308 | + | { type = ":Z2" }, |
| 2309 | + | { type = ":!2" }, |
| 2310 | + | { type = ":?2" }, |
| 2311 | + | { type = ":|2" }, |
| 2312 | + | { type = ":$2" }, |
| 2313 | + | { type = ":X2" }, |
| 2314 | + | { type = ":E2" }, |
| 2315 | + | { type = ":F2" }, |
| 2316 | + | { type = ":H2" }, |
| 2317 | + | { type = ":I2" }, |
| 2318 | + | { type = ":K2" }, |
| 2319 | + | { type = ":L" }, |
| 2320 | + | { type = ":M2" }, |
| 2321 | + | { type = ":N2" }, |
| 2322 | + | { type = ":Q2" }, |
| 2323 | + | { type = ":R2" }, |
| 2324 | + | { type = ":T2" }, |
| 2325 | + | { type = ":U2" }, |
| 2326 | + | { type = ":V2" }, |
| 2327 | + | { type = ":Y2" }, |
| 2328 | + | { type = ":W2" }, |
| 2329 | + | { type = ":G2" }, |
| 2330 | + | { type = ":B2" }, |
| 2331 | + | { type = ":C2" }, |
| 2332 | + | { type = ":A2" } |
| 2333 | + | } |
| 2334 | + | |
| 2335 | + | function onOpen() |
| 2336 | + | -- Asegurarse de que el chat esté activo y visible |
| 2337 | + | chatWindow:setPhantom(false) |
| 2338 | + | chatWindow:setFocusable(true) |
| 2339 | + | chatWindow:setVisible(true) |
| 2340 | + | chatWindow:focus() |
| 2341 | + | textEdit:setFocusable(true) |
| 2342 | + | textEdit:setText("") -- opción para reiniciar el campo |
| 2343 | + | textEdit:focus() |
| 2344 | + | end |
| 2345 | + | |
| 2346 | + | function onClose() |
| 2347 | + | -- Se cierra el chat y se reactivan las teclas de movimiento |
| 2348 | + | chatWindow:setPhantom(true) |
| 2349 | + | chatWindow:setFocusable(false) |
| 2350 | + | chatWindow:setVisible(false) |
| 2351 | + | textEdit:setFocusable(false) |
| 2352 | + | modules.game_walking.enableWSAD() |
| 2353 | + | end |
| 2354 | + | |
| 2355 | + | function toggleFullMap() |
| 2356 | + | local gameRootPanel = modules.game_interface.getRootPanel() |
| 2357 | + | if gameRootPanel:isVisible() then |
| 2358 | + | gameRootPanel:hide() |
| 2359 | + | else |
| 2360 | + | gameRootPanel:show() |
| 2361 | + | end |
| 2362 | + | end |
| 2363 | + | |
| 2364 | + | local chatWindow = g_ui.getRootWidget():getChildById('chat') |
| 2365 | + | if chatWindow then |
| 2366 | + | local textEdit = chatWindow:getChildById('textEdit') |
| 2367 | + | if textEdit then |
| 2368 | + | textEdit.onFocusChange = function(widget, focused) |
| 2369 | + | local gameRootPanel = modules.game_interface.getRootPanel() |
| 2370 | + | if focused then |
| 2371 | + | g_keyboard.unbindKeyDown('M', toggleFullMap) |
| 2372 | + | else |
| 2373 | + | g_keyboard.bindKeyDown('M', toggleFullMap, gameRootPanel) |
| 2374 | + | end |
| 2375 | + | end |
| 2376 | + | end |
| 2377 | + | end |