tibia-client/modules/game_console/console.lua

369 lines
12 KiB
Lua
Raw Normal View History

Console = {}
-- private variables
2012-02-03 05:32:39 +01:00
local SpeakTypesSettings = {
say = { speakType = SpeakSay, color = '#FFFF00' },
whisper = { speakType = SpeakWhisper, color = '#FFFF00' },
yell = { speakType = SpeakYell, color = '#FFFF00' },
broadcast = { speakType = SpeakBroadcast, color = '#F55E5E' },
private = { speakType = SpeakPrivate, color = '#5FF7F7', private = true },
privateRed = { speakType = SpeakPrivateRed, color = '#F55E5E', private = true },
privatePlayerToPlayer = { speakType = SpeakPrivate, color = '#9F9DFD', private = true },
privatePlayerToNpc = { speakType = SpeakPrivatePlayerToNpc, color = '#9F9DFD', private = true, npcChat = true },
privateNpcToPlayer = { speakType = SpeakPrivateNpcToPlayer, color = '#5FF7F7', private = true, npcChat = true },
channelYellow = { speakType = SpeakChannelYellow, color = '#FFFF00' },
channelWhite = { speakType = SpeakChannelWhite, color = '#FFFFFF' },
channelRed = { speakType = SpeakChannelRed, color = '#F55E5E' },
channelOrange = { speakType = SpeakChannelOrange, color = '#FE6500' },
monsterSay = { speakType = SpeakMonsterSay, color = '#FE6500', hideInConsole = true},
monsterYell = { speakType = SpeakMonsterYell, color = '#FE6500', hideInConsole = true},
}
local SpeakTypes = {
2012-02-03 06:24:45 +01:00
[SpeakSay] = SpeakTypesSettings.say,
[SpeakWhisper] = SpeakTypesSettings.whisper,
[SpeakYell] = SpeakTypesSettings.yell,
[SpeakBroadcast] = SpeakTypesSettings.broadcast,
[SpeakPrivate] = SpeakTypesSettings.private,
[SpeakPrivateRed] = SpeakTypesSettings.privateRed,
[SpeakPrivatePlayerToNpc] = SpeakTypesSettings.privatePlayerToNpc,
[SpeakPrivateNpcToPlayer] = SpeakTypesSettings.privateNpcToPlayer,
[SpeakChannelYellow] = SpeakTypesSettings.channelYellow,
[SpeakChannelWhite] = SpeakTypesSettings.channelWhite,
[SpeakChannelRed] = SpeakTypesSettings.channelRed,
[SpeakChannelOrange] = SpeakTypesSettings.channelOrange,
[SpeakMonsterSay] = SpeakTypesSettings.monsterSay,
[SpeakMonsterYell] = SpeakTypesSettings.monsterYell,
}
local SayModes = {
[1] = { speakTypeDesc = 'whisper', icon = '/core_styles/icons/whisper.png' },
2012-02-04 03:11:18 +01:00
[2] = { speakTypeDesc = 'say', icon = '/core_styles/icons/say.png' },
[3] = { speakTypeDesc = 'yell', icon = '/core_styles/icons/yell.png' }
}
local consolePanel
local consoleBuffer
local consoleTabBar
2012-01-14 02:37:15 +01:00
local consoleLineEdit
local channels
local messageHistory = { }
local currentMessageIndex = 0
local MaxHistory = 1000
2012-01-14 02:37:15 +01:00
-- private functions
local function navigateMessageHistory(step)
local numCommands = #messageHistory
if numCommands > 0 then
currentMessageIndex = math.min(math.max(currentMessageIndex + step, 0), numCommands)
if currentMessageIndex > 0 then
local command = messageHistory[numCommands - currentMessageIndex + 1]
consoleLineEdit:setText(command)
else
consoleLineEdit:clearText()
end
end
end
2012-01-14 02:37:15 +01:00
function applyMessagePrefixies(name, level, message)
if name then
if Options.showLevelsInConsole and level > 0 then
message = name .. ' [' .. level .. ']: ' .. message
else
message = name .. ': ' .. message
end
end
return message
end
-- public functions
function Console.create()
consolePanel = displayUI('console.otui', { parent = Game.gameBottomPanel } )
2012-01-14 02:37:15 +01:00
consoleLineEdit = consolePanel:getChildById('consoleLineEdit')
consoleBuffer = consolePanel:getChildById('consoleBuffer')
consoleTabBar = consolePanel:getChildById('consoleTabBar')
consoleTabBar:setContentWidget(consoleBuffer)
2012-01-14 02:37:15 +01:00
channels = {}
Console.addChannel('Default', 0)
2012-02-03 05:32:39 +01:00
Console.addTab('Server Log', false)
2012-02-04 03:11:18 +01:00
Hotkeys.bindKeyDown('Shift+Up', function() navigateMessageHistory(1) end, consolePanel)
Hotkeys.bindKeyDown('Shift+Down', function() navigateMessageHistory(-1) end, consolePanel)
Hotkeys.bindKeyDown('Tab', function() consoleTabBar:selectNextTab() end, consolePanel)
Hotkeys.bindKeyDown('Shift+Tab', function() consoleTabBar:selectPrevTab() end, consolePanel)
Hotkeys.bindKeyDown('Enter', Console.sendCurrentMessage, consolePanel)
2012-02-04 03:11:18 +01:00
2012-02-03 06:24:45 +01:00
-- apply buttom functions after loaded
connect(consolePanel:getChildById('nextChannelButton'), { onClick = function() consoleTabBar:selectNextTab() end } )
connect(consolePanel:getChildById('prevChannelButton'), { onClick = function() consoleTabBar:selectPrevTab() end } )
connect(consoleTabBar, { onTabChange = Console.onTabChange })
2012-02-04 03:11:18 +01:00
2012-02-03 06:24:45 +01:00
-- tibia like hotkeys
2012-02-03 05:32:39 +01:00
Hotkeys.bindKeyDown('Ctrl+O', Game.requestChannels)
2012-02-04 03:11:18 +01:00
Hotkeys.bindKeyDown('Ctrl+E', Console.removeCurrentTab)
end
function Console.destroy()
consolePanel:destroy()
consolePanel = nil
end
2012-02-03 05:32:39 +01:00
function Console.addTab(name, focus)
2012-01-14 02:37:15 +01:00
local tab = consoleTabBar:addTab(name)
2012-02-03 05:32:39 +01:00
if focus then
consoleTabBar:selectTab(tab)
2012-02-03 05:32:39 +01:00
else
consoleTabBar:blinkTab(tab)
2012-02-03 05:32:39 +01:00
end
2012-01-14 02:37:15 +01:00
return tab
end
2012-02-03 05:32:39 +01:00
function Console.onTabChange(tabBar, tab)
2012-02-03 06:24:45 +01:00
if tab:getText() == "Default" or tab:getText() == "Server Log" then
consolePanel:getChildById('closeChannelButton'):disable()
else
consolePanel:getChildById('closeChannelButton'):enable()
end
2012-02-03 05:32:39 +01:00
end
function Console.removeCurrentTab()
local tab = consoleTabBar:getCurrentTab()
if tab:getText() == "Default" or tab:getText() == "Server Log" then return end
2012-02-04 03:11:18 +01:00
2012-02-03 05:32:39 +01:00
consoleTabBar:removeTab(tab)
-- notificate the server that we are leaving the channel
if tab.channelId then
Game.leaveChannel(tab.channelId)
elseif tab:getText() == "NPCs" then
Game.closeNpcChannel()
end
2012-02-03 05:32:39 +01:00
end
2012-01-14 02:37:15 +01:00
function Console.getTab(name)
return consoleTabBar:getTab(name)
end
function Console.getCurrentTab()
return consoleTabBar:getCurrentTab()
end
function Console.addChannel(name, id)
channels[id] = name
2012-02-03 05:32:39 +01:00
local tab = Console.addTab(name, true)
2012-01-14 02:37:15 +01:00
tab.channelId = id
return tab
end
function Console.addPrivateText(text, speaktype, name, isPrivateCommand)
local focus = false
if speaktype.speakType == SpeakPrivateNpcToPlayer then
name = 'NPCs'
focus = true
end
2012-01-14 02:37:15 +01:00
local privateTab = Console.getTab(name)
if privateTab == nil then
if Options.showPrivateMessagesInConsole or (isPrivateCommand and not privateTab) then
2012-01-14 02:37:15 +01:00
privateTab = Console.getTab('Default')
else
privateTab = Console.addTab(name, focus)
2012-01-14 02:37:15 +01:00
end
privateTab.npcChat = speaktype.npcChat
elseif focus then
consoleTabBar:selectTab(privateTab)
2012-01-14 02:37:15 +01:00
end
Console.addTabText(text, speaktype, privateTab)
end
function Console.addText(text, speaktype, tabName)
local tab = Console.getTab(tabName)
if tab ~= nil then
Console.addTabText(text, speaktype, tab)
end
2012-01-14 02:37:15 +01:00
end
function Console.addTabText(text, speaktype, tab)
2012-01-09 00:28:49 +01:00
if Options.showTimestampsInConsole then
text = os.date('%H:%M') .. ' ' .. text
end
2012-01-14 21:14:40 +01:00
local panel = consoleTabBar:getTabPanel(tab)
local label = createWidget('ConsoleLabel', panel)
label:setText(text)
2012-01-14 02:37:15 +01:00
label:setColor(speaktype.color)
consoleTabBar:blinkTab(tab)
2012-01-14 21:14:40 +01:00
if panel:getChildCount() > 10 then
panel:removeChild(panel:getFirstChild())
end
end
2012-01-14 02:37:15 +01:00
function Console.sendCurrentMessage()
local message = consoleLineEdit:getText()
if #message == 0 then return end
consoleLineEdit:clearText()
2012-01-14 06:54:20 +01:00
-- get current channel
2012-01-14 02:37:15 +01:00
local tab = Console.getCurrentTab()
-- handling chat commands
local originalMessage = message
local chatCommandSayMode
local chatCommandPrivate
2012-02-03 22:37:42 +01:00
local chatCommandPrivateReady
2012-02-04 03:11:18 +01:00
local chatCommandMessage = message:match("^%#y (.*)")
if chatCommandMessage ~= nil then chatCommandSayMode = 'yell' end -- player used yell command
message = chatCommandMessage or message
2012-02-04 03:11:18 +01:00
local chatCommandMessage = message:match("^%#w (.*)")
if chatCommandMessage ~= nil then chatCommandSayMode = 'whisper' end -- player used whisper
message = chatCommandMessage or message
2012-02-04 03:11:18 +01:00
local findIni, findEnd, chatCommandInitial, chatCommandPrivate, chatCommandEnd, chatCommandMessage = message:find("([%*%@])(.+)([%*%@])(.*)")
if findIni ~= nil and findIni == 1 then -- player used private chat command
if chatCommandInitial == chatCommandEnd then
chatCommandPrivateRepeat = false
if chatCommandInitial == "*" then
consoleLineEdit:setText('*'.. chatCommandPrivate .. '* ')
2012-02-04 03:11:18 +01:00
end
message = chatCommandMessage:trim()
2012-02-03 22:37:42 +01:00
chatCommandPrivateReady = true
end
end
2012-02-04 03:11:18 +01:00
message = message:gsub("^(%s*)(.*)","%2") -- remove space characters from message init
if #message == 0 then return end
-- add new command to history
currentMessageIndex = 0
table.insert(messageHistory, originalMessage)
if #messageHistory > MaxHistory then
table.remove(messageHistory, 1)
end
2012-02-04 03:11:18 +01:00
2012-01-14 06:54:20 +01:00
-- when talking on server log, the message goes to default channel
local name = tab:getText()
if name == 'Server Log' then
tab = Console.getTab('Default')
name = 'Default'
2012-01-14 02:37:15 +01:00
end
2012-01-14 06:54:20 +01:00
local speaktypedesc
2012-01-14 02:37:15 +01:00
2012-02-03 22:37:42 +01:00
if tab.channelId and not chatCommandPrivateReady then
2012-01-14 06:54:20 +01:00
if tab.channelId == 0 then
speaktypedesc = chatCommandSayMode or SayModes[consolePanel:getChildById('sayModeButton').sayMode].speakTypeDesc
if speaktypedesc ~= 'say' then Console.sayModeChange(2) end -- head back to say mode
2012-01-14 06:54:20 +01:00
else
2012-01-14 02:37:15 +01:00
speaktypedesc = 'channelYellow'
end
2012-02-03 05:32:39 +01:00
Game.talkChannel(SpeakTypesSettings[speaktypedesc].speakType, tab.channelId, message)
2012-01-14 02:37:15 +01:00
return
else
local isPrivateCommand = false
2012-02-03 22:37:42 +01:00
if chatCommandPrivateReady then
speaktypedesc = 'privatePlayerToPlayer'
name = chatCommandPrivate
isPrivateCommand = true
elseif tab.npcChat then
2012-02-03 05:32:39 +01:00
speaktypedesc = 'privatePlayerToNpc'
2012-01-14 06:54:20 +01:00
else
2012-02-03 05:32:39 +01:00
speaktypedesc = 'privatePlayerToPlayer'
2012-01-14 06:54:20 +01:00
end
2012-02-04 03:11:18 +01:00
2012-01-14 06:54:20 +01:00
2012-02-03 05:32:39 +01:00
local speaktype = SpeakTypesSettings[speaktypedesc]
2012-01-14 02:37:15 +01:00
local player = Game.getLocalPlayer()
2012-02-03 05:32:39 +01:00
Game.talkPrivate(speaktype.speakType, name, message)
2012-01-14 06:54:20 +01:00
2012-01-14 02:37:15 +01:00
message = applyMessagePrefixies(player:getName(), player:getLevel(), message)
Console.addPrivateText(message, speaktype, name, isPrivateCommand)
end
end
function Console.sayModeChange(sayMode)
local buttom = consolePanel:getChildById('sayModeButton')
if sayMode == nil then
sayMode = buttom.sayMode + 1
end
2012-02-04 03:11:18 +01:00
if sayMode > #SayModes then sayMode = 1 end
buttom:setIcon(SayModes[sayMode].icon)
2012-02-04 03:11:18 +01:00
buttom.sayMode = sayMode
end
-- hooked events
2012-02-03 05:32:39 +01:00
local function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos)
speaktype = SpeakTypes[speaktype]
2012-01-09 06:23:39 +01:00
if speaktype.hideInConsole then return end
2012-01-14 02:37:15 +01:00
message = applyMessagePrefixies(name, level, message)
if speaktype.private then
Console.addPrivateText(message, speaktype, name, false)
2012-01-14 02:37:15 +01:00
else
local channel = channels[channelId]
if channel then
Console.addText(message, speaktype, channel)
else
-- server sent a message on a channel that we are not aware of, must leave it
Game.leaveChannel(channelId)
end
end
2012-01-14 02:37:15 +01:00
end
2012-01-14 02:37:15 +01:00
local function onOpenChannel(channelId, channelName)
Console.addChannel(channelName, channelId)
end
2012-02-03 05:32:39 +01:00
local function onOpenPrivateChannel(receiver)
local privateTab = Console.getTab(receiver)
if privateTab == nil then
Console.addTab(receiver, true)
end
end
2012-02-04 03:11:18 +01:00
local function doChannelListSubmit(channelsWindow)
2012-01-14 02:37:15 +01:00
local channelListPanel = channelsWindow:getChildById('channelList')
local openPrivateChannelWith = channelsWindow:getChildById('openPrivateChannelWith'):getText()
2012-02-03 06:24:45 +01:00
if openPrivateChannelWith ~= '' then
Game.openPrivateChannel(openPrivateChannelWith)
else
local selectedChannelLabel = channelListPanel:getFocusedChild()
if not selectedChannelLabel then return end
Game.joinChannel(selectedChannelLabel.channelId)
end
channelsWindow:destroy()
end
local function onChannelList(channelList)
local channelsWindow = displayUI('channelswindow.otui')
local channelListPanel = channelsWindow:getChildById('channelList')
connect(channelsWindow, { onEnter = function () doChannelListSubmit(channelsWindow) end } )
2012-02-04 03:11:18 +01:00
2012-01-14 02:37:15 +01:00
for k,v in pairs(channelList) do
local channelId = v[1]
local channelName = v[2]
if channelId ~= 0 and #channelName > 0 then
local label = createWidget('ChannelListLabel', channelListPanel)
label.channelId = channelId
label:setText(channelName)
2012-02-04 03:11:18 +01:00
label:setPhantom(false)
connect(label, { onMouseDoubleClick = function () doChannelListSubmit(channelsWindow) end } )
2012-01-14 02:37:15 +01:00
end
end
end
connect(Game, { onLogin = Console.create,
onLogout = Console.destroy,
2012-01-14 02:37:15 +01:00
onCreatureSpeak = onCreatureSpeak,
onChannelList = onChannelList,
2012-02-03 05:32:39 +01:00
onOpenChannel = onOpenChannel,
2012-02-03 06:24:45 +01:00
onOpenPrivateChannel = onOpenPrivateChannel})