From 36c029fc6916b19d550c3c8e2d061c5b35d8accc Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Thu, 26 Jul 2012 06:12:20 -0300 Subject: [PATCH] Multiprotocol 8.1-9.6 finally working Still have many minor issues, tests are needed No recompilation needed anymore 9.60 messages is not fully implemented --- modules/client/client.lua | 2 +- modules/corelib/const.lua | 22 --- modules/game_battle/battle.lua | 5 +- modules/game_battle/battlebutton.otui | 4 - modules/game_bugreport/bugreport.lua | 2 +- modules/game_console/console.lua | 77 +++++----- modules/game_interface/gameinterface.lua | 6 +- modules/game_minimap/minimap.lua | 2 +- modules/game_playerdeath/playerdeath.lua | 2 +- modules/game_textmessage/protocol.lua | 60 -------- modules/game_textmessage/textmessage.lua | 157 +++++++++------------ modules/game_textmessage/textmessage.otmod | 11 +- modules/game_textmessage/textmessage.otui | 46 ++++-- modules/gamelib/const.lua | 73 ++++++++++ src/otclient/CMakeLists.txt | 1 + src/otclient/const.h | 69 +++++++-- src/otclient/creature.cpp | 9 -- src/otclient/game.cpp | 29 ++-- src/otclient/game.h | 8 +- src/otclient/map.cpp | 2 +- src/otclient/protocolcodes.cpp | 138 ++++++++++++++++++ src/otclient/protocolcodes.h | 154 +------------------- src/otclient/protocolgame.h | 4 +- src/otclient/protocolgameparse.cpp | 112 ++++++++++----- src/otclient/protocolgamesend.cpp | 25 ++-- src/otclient/statictext.cpp | 20 +-- src/otclient/statictext.h | 8 +- src/otclient/tile.cpp | 20 +-- 28 files changed, 566 insertions(+), 502 deletions(-) delete mode 100644 modules/game_textmessage/protocol.lua create mode 100644 src/otclient/protocolcodes.cpp diff --git a/modules/client/client.lua b/modules/client/client.lua index 4572a3b1..0c5cd450 100644 --- a/modules/client/client.lua +++ b/modules/client/client.lua @@ -5,7 +5,7 @@ function Client.reloadScripts() dofile '/otclientrc' local message = tr('All modules and scripts were reloaded.') - modules.game_textmessage.displayEventAdvance(message) + modules.game_textmessage.displayGameMessage(message) print(message) end diff --git a/modules/corelib/const.lua b/modules/corelib/const.lua index a6eba07e..e8c697c9 100644 --- a/modules/corelib/const.lua +++ b/modules/corelib/const.lua @@ -171,28 +171,6 @@ KeyNumpad7 = 148 KeyNumpad8 = 149 KeyNumpad9 = 150 -SpeakSay = 1 -SpeakWhisper = 2 -SpeakYell = 3 -SpeakBroadcast = 4 -SpeakPrivate = 5 -SpeakPrivateRed = 6 -SpeakPrivatePlayerToNpc = 7 -SpeakPrivateNpcToPlayer = 8 -SpeakChannelYellow = 9 -SpeakChannelWhite = 10 -SpeakChannelRed = 11 -SpeakChannelOrange = 12 -SpeakMonsterSay = 13 -SpeakMonsterYell = 14 - -FightOffensive = 1 -FightBalanced = 2 -FightDefensive = 3 - -DontChase = 0 -ChaseOpponent = 1 - ExtendedActivate = 0 ExtendedLocales = 1 ExtendedParticles = 2 diff --git a/modules/game_battle/battle.lua b/modules/game_battle/battle.lua index da9d7e6e..55c1eaf0 100644 --- a/modules/game_battle/battle.lua +++ b/modules/game_battle/battle.lua @@ -32,6 +32,7 @@ table.insert(LifeBarColors, {percentAbove = 3, color = '#3C0000' } ) table.insert(LifeBarColors, {percentAbove = -1, color = '#4F0000' } ) function init() + g_ui.importStyle('battlebutton.otui') battleWindow = g_ui.loadUI('battle.otui', modules.game_interface.getRightPanel()) battleButton = TopMenu.addRightGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', 'battle.png', toggle) battleButton:setOn(true) @@ -173,10 +174,12 @@ function addCreature(creature) local creatureId = creature:getId() if battleButtonsByCreaturesList[creatureId] == nil then - local battleButton = g_ui.loadUI('battlebutton.otui', battlePanel) + local battleButton = g_ui.createWidget('BattleButton', battlePanel) local creatureWidget = battleButton:getChildById('creature') local labelWidget = battleButton:getChildById('label') local lifeBarWidget = battleButton:getChildById('lifeBar') + battleButton.onHoverChange = onbattleButtonHoverChange + battleButton.onMouseRelease = onMouseRelease battleButton:setId('BattleButton_' .. creature:getName():gsub('%s','_')) battleButton.creatureId = creatureId diff --git a/modules/game_battle/battlebutton.otui b/modules/game_battle/battlebutton.otui index eb98da45..df9317d2 100644 --- a/modules/game_battle/battlebutton.otui +++ b/modules/game_battle/battlebutton.otui @@ -1,11 +1,7 @@ BattleButton < UIButton - -BattleButton height: 20 margin-top: 5 fixed-size: true - &onHoverChange: onbattleButtonHoverChange - &onMouseRelease: onMouseRelease &isBattleButton: true UICreature diff --git a/modules/game_bugreport/bugreport.lua b/modules/game_bugreport/bugreport.lua index 2f24588d..70fa2488 100644 --- a/modules/game_bugreport/bugreport.lua +++ b/modules/game_bugreport/bugreport.lua @@ -22,7 +22,7 @@ end function doReport() g_game.reportBug(bugTextEdit:getText()) bugReportWindow:hide() - modules.game_textmessage.displayEventAdvance(tr('Bug report sent.')) + modules.game_textmessage.displayGameMessage(tr('Bug report sent.')) end function show() diff --git a/modules/game_console/console.lua b/modules/game_console/console.lua index cdab27c3..f35af22d 100644 --- a/modules/game_console/console.lua +++ b/modules/game_console/console.lua @@ -1,36 +1,36 @@ 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}, + say = { speakType = MessageModes.Say, color = '#FFFF00' }, + whisper = { speakType = MessageModes.Whisper, color = '#FFFF00' }, + yell = { speakType = MessageModes.Yell, color = '#FFFF00' }, + broadcast = { speakType = MessageModes.GamemasterPrivateFrom, color = '#F55E5E' }, + private = { speakType = MessageModes.PrivateTo, color = '#5FF7F7', private = true }, + privateRed = { speakType = MessageModes.GamemasterTo, color = '#F55E5E', private = true }, + privatePlayerToPlayer = { speakType = MessageModes.PrivateTo, color = '#9F9DFD', private = true }, + privatePlayerToNpc = { speakType = MessageModes.NpcTo, color = '#9F9DFD', private = true, npcChat = true }, + privateNpcToPlayer = { speakType = MessageModes.NpcFrom, color = '#5FF7F7', private = true, npcChat = true }, + channelYellow = { speakType = MessageModes.Channel, color = '#FFFF00' }, + channelWhite = { speakType = MessageModes.ChannelManagement, color = '#FFFFFF' }, + channelRed = { speakType = MessageModes.GamemasterChannel, color = '#F55E5E' }, + channelOrange = { speakType = MessageModes.ChannelHighlight, color = '#FE6500' }, + monsterSay = { speakType = MessageModes.MonsterSay, color = '#FE6500', hideInConsole = true}, + monsterYell = { speakType = MessageModes.MonsterYell, color = '#FE6500', hideInConsole = true}, } SpeakTypes = { - [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, + [MessageModes.Say] = SpeakTypesSettings.say, + [MessageModes.Whisper] = SpeakTypesSettings.whisper, + [MessageModes.Yell] = SpeakTypesSettings.yell, + [MessageModes.GamemasterPrivateFrom] = SpeakTypesSettings.broadcast, + [MessageModes.PrivateFrom] = SpeakTypesSettings.private, + [MessageModes.GamemasterPrivateFrom] = SpeakTypesSettings.privateRed, + [MessageModes.NpcTo] = SpeakTypesSettings.privatePlayerToNpc, + [MessageModes.NpcFrom] = SpeakTypesSettings.privateNpcToPlayer, + [MessageModes.Channel] = SpeakTypesSettings.channelYellow, + [MessageModes.ChannelManagement] = SpeakTypesSettings.channelWhite, + [MessageModes.GamemasterChannel] = SpeakTypesSettings.channelRed, + [MessageModes.ChannelHighlight] = SpeakTypesSettings.channelOrange, + [MessageModes.MonsterSay] = SpeakTypesSettings.monsterSay, + [MessageModes.MonsterYell] = SpeakTypesSettings.monsterYell, } SayModes = { @@ -56,7 +56,7 @@ ignoreNpcMessages = false function init() - connect(g_game, { onCreatureSpeak = onCreatureSpeak, + connect(g_game, { onTalk = onTalk, onChannelList = onChannelList, onOpenChannel = onOpenChannel, onOpenPrivateChannel = onOpenPrivateChannel, @@ -94,7 +94,7 @@ function init() end function terminate() - disconnect(g_game, { onCreatureSpeak = onCreatureSpeak, + disconnect(g_game, { onTalk = onTalk, onChannelList = onChannelList, onOpenChannel = onOpenChannel, onOpenPrivateChannel = onOpenPrivateChannel, @@ -239,7 +239,7 @@ end function addPrivateText(text, speaktype, name, isPrivateCommand, creatureName) local focus = false - if speaktype.speakType == SpeakPrivateNpcToPlayer then + if speaktype.speakType == SpeakNpcFrom then name = 'NPCs' focus = true end @@ -301,9 +301,9 @@ function popupMenu(mousePos, mouseButton, creatureName, text) --TODO select all menu:addOption(tr('Copy message'), function () g_window.setClipboardText(text) end) - if RuleViolation.hasWindowAccess() then + if modules.game_ruleviolation.hasWindowAccess() then menu:addSeparator() - menu:addOption(tr('Rule Violation'), function() RuleViolation.show(creatureName, text:match('.+%:%s(.+)')) end) + menu:addOption(tr('Rule Violation'), function() modules.game_ruleviolation.show(creatureName, text:match('.+%:%s(.+)')) end) end menu:addSeparator() @@ -448,8 +448,8 @@ function applyMessagePrefixies(name, level, message) return message end -function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos) - if ignoreNpcMessages and speaktype == SpeakPrivateNpcToPlayer then return end +function onTalk(name, level, speaktype, message, channelId, creaturePos) + if ignoreNpcMessages and speaktype == SpeakNpcFrom then return end local defaultMessage = speaktype < 3 and true or false speaktype = SpeakTypes[speaktype] if speaktype.hideInConsole then return end @@ -458,11 +458,6 @@ function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos if speaktype.private then addPrivateText(composedMessage, speaktype, name, false, name) - if Options.getOption('showPrivateMessagesOnScreen') then - if(speaktype.speakType ~= SpeakPrivateNpcToPlayer) then - TextMessage.displayPrivate(name .. ':\n' .. message) - end - end else local channel = tr('Default') if not defaultMessage then diff --git a/modules/game_interface/gameinterface.lua b/modules/game_interface/gameinterface.lua index 6b50614a..96826f83 100644 --- a/modules/game_interface/gameinterface.lua +++ b/modules/game_interface/gameinterface.lua @@ -347,9 +347,9 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing) end end - if RuleViolation.hasWindowAccess() then + if modules.game_ruleviolation.hasWindowAccess() then menu:addSeparator() - menu:addOption(tr('Rule Violation'), function() RuleViolation.show(creatureThing:getName()) end) + menu:addOption(tr('Rule Violation'), function() modules.game_ruleviolation.show(creatureThing:getName()) end) end menu:addSeparator() @@ -430,7 +430,7 @@ function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, u if autoWalkPos and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseLeftButton then local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), autoWalkPos, 127) if #dirs == 0 then - modules.game_textmessage.displayStatus(tr('There is no way.')) + modules.game_textmessage.displayStatusMessage(tr('There is no way.')) return true end g_game.autoWalk(dirs) diff --git a/modules/game_minimap/minimap.lua b/modules/game_minimap/minimap.lua index 1c4139ac..2dada8fc 100644 --- a/modules/game_minimap/minimap.lua +++ b/modules/game_minimap/minimap.lua @@ -146,7 +146,7 @@ function onMinimapMouseRelease(self, mousePosition, mouseButton) if tile and mouseButton == MouseLeftButton and self:isPressed() then local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), tile:getPosition(), 127) if #dirs == 0 then - modules.game_textmessage.displayStatus(tr('There is no way.')) + modules.game_textmessage.displayStatusMessage(tr('There is no way.')) return true end g_game.autoWalk(dirs) diff --git a/modules/game_playerdeath/playerdeath.lua b/modules/game_playerdeath/playerdeath.lua index 27811cb1..e3cc1d5c 100644 --- a/modules/game_playerdeath/playerdeath.lua +++ b/modules/game_playerdeath/playerdeath.lua @@ -32,7 +32,7 @@ function displayDeadMessage() return end - modules.game_textmessage.displayEventAdvance(tr('You are dead.')) + modules.game_textmessage.displayGameMessage(tr('You are dead.')) end function openWindow() diff --git a/modules/game_textmessage/protocol.lua b/modules/game_textmessage/protocol.lua deleted file mode 100644 index 29061cef..00000000 --- a/modules/game_textmessage/protocol.lua +++ /dev/null @@ -1,60 +0,0 @@ -function getMessageTypes(version) - if version >= 960 then - perror("TODO: message types for 9.6") - return {} - elseif version >= 861 then - return { - [13] = 'ConsoleOrange', - [14] = 'ConsoleOrange', - [15] = 'Warning', - [16] = 'EventAdvance', - [17] = 'EventDefault', - [18] = 'StatusDefault', - [19] = 'Info', - [20] = 'StatusSmall', - [21] = 'ConsoleBlue', - [22] = 'ConsoleRed' - } - elseif version >= 854 then - return { - [18] = 'ConsoleRed', - [19] = 'ConsoleOrange', - [20] = 'ConsoleOrange', - [21] = 'Warning', - [22] = 'EventAdvance', - [23] = 'EventDefault', - [24] = 'StatusDefault', - [25] = 'Info', - [26] = 'StatusSmall', - [27] = 'ConsoleBlue' - } - else - return { - [18] = 'Warning', - [19] = 'EventAdvance', - [20] = 'EventDefault', - [21] = 'StatusDefault', - [22] = 'Info', - [23] = 'StatusSmall', - [24] = 'ConsoleBlue', - [25] = 'ConsoleRed', - [26] = 'ConsoleOrange', - [27] = 'ConsoleOrange', - } - end -end - -function parseTextMessage(msg) - local msgtype = msg:getU8() - local text = msg:getString() - msgtype = getMessageTypes(g_game.getClientVersion())[msgtype] - signalcall(g_game.onTextMessage, msgtype, text) -end - -function registerProtocol() - ProtocolGame.registerOpcode(GameServerOpcodes.GameServerTextMessage, parseTextMessage) -end - -function unregisterProtocol() - ProtocolGame.unregisterOpcode(GameServerOpcodes.GameServerTextMessage) -end diff --git a/modules/game_textmessage/textmessage.lua b/modules/game_textmessage/textmessage.lua index ea7c74f9..dda14d67 100644 --- a/modules/game_textmessage/textmessage.lua +++ b/modules/game_textmessage/textmessage.lua @@ -1,115 +1,96 @@ +MessageSettings = { + consoleRed = { color = TextColors.red, consoleTab='Default' }, + consoleOrange = { color = TextColors.orange, consoleTab='Default' }, + consoleBlue = { color = TextColors.blue, consoleTab='Default' }, + centerRed = { color = TextColors.red, consoleTab='Server Log', screenTarget='lowCenterLabel' }, + centerGreen = { color = TextColors.green, consoleTab='Server Log', screenTarget='highCenterLabel', consoleOption='showInfoMessagesInConsole' }, + centerWhite = { color = TextColors.white, consoleTab='Server Log', screenTarget='middleCenterLabel', consoleOption='showEventMessagesInConsole' }, + bottomWhite = { color = TextColors.white, consoleTab='Server Log', screenTarget='statusLabel', consoleOption='showEventMessagesInConsole' }, + status = { color = TextColors.white, consoleTab='Server Log', screenTarget='statusLabel', consoleOption='showStatusMessagesInConsole' }, + statusSmall = { color = TextColors.white, screenTarget='statusLabel' }, + private = { color = TextColors.lightblue, screenTarget='privateLabel' } +} + MessageTypes = { - ConsoleRed = { color = '#F55E5E', consoleTab = tr('Default') }, - ConsoleOrange = { color = '#FE6500', consoleTab = tr('Default') }, - ConsoleBlue = { color = '#9F9DFD', consoleTab = tr('Default') }, - Warning = { color = '#F55E5E', consoleTab = tr('Server Log'), labelId = 'warningLabel' }, - Info = { color = '#00EB00', consoleTab = tr('Server Log'), labelId = 'infoLabel', consoleOption = 'showInfoMessagesInConsole' }, - EventAdvance = { color = '#FFFFFF', consoleTab = tr('Server Log'), labelId = 'advanceLabel', consoleOption = 'showEventMessagesInConsole' }, - EventDefault = { color = '#FFFFFF', consoleTab = tr('Server Log'), labelId = 'statusLabel', consoleOption = 'showEventMessagesInConsole' }, - StatusDefault = { color = '#FFFFFF', consoleTab = tr('Server Log'), labelId = 'statusLabel', consoleOption = 'showStatusMessagesInConsole' }, - StatusSmall = { color = '#FFFFFF', labelId = 'statusLabel' }, - Private = { color = '#5FF7F7', labelId = 'privateLabel' } + [MessageModes.MonsterSay] = MessageSettings.orange, + [MessageModes.MonsterYell] = MessageSettings.orange, + [MessageModes.Failure] = MessageSettings.statusSmall, + [MessageModes.Login] = MessageSettings.bottomWhite, + [MessageModes.Game] = MessageSettings.centerWhite, + [MessageModes.Status] = MessageSettings.status, + [MessageModes.Warning] = MessageSettings.centerRed, + [MessageModes.Look] = MessageSettings.centerGreen, + [MessageModes.Loot] = MessageSettings.centerGreen, + [MessageModes.Red] = MessageSettings.consoleRed, + [MessageModes.Blue] = MessageSettings.consoleBlue, + [MessageModes.PrivateFrom] = MessageSettings.private } -centerTextMessagePanel = nil -statusLabel = nil -privateLabel = nil -warningLabel = nil -advanceLabel = nil -infoLabel = nil +messagesPanel = nil function init() - connect(g_game, { - onTextMessage = displayMessage, - onGameStart = clearMessages - }) - registerProtocol() - - g_ui.importStyle('textmessage.otui') - centerTextMessagePanel = g_ui.createWidget('Panel', modules.game_interface.getMapPanel()) - centerTextMessagePanel:setId('centerTextMessagePanel') - - local layout = UIVerticalLayout.create(centerTextMessagePanel) - layout:setFitChildren(true) - centerTextMessagePanel:setLayout(layout) - centerTextMessagePanel:setWidth(360) - centerTextMessagePanel:centerIn('parent') - - warningLabel = createTextMessageLabel('warningLabel', centerTextMessagePanel, 'CenterLabel') - advanceLabel = createTextMessageLabel('advanceLabel', centerTextMessagePanel, 'CenterLabel') - infoLabel = createTextMessageLabel('infoLabel', centerTextMessagePanel, 'CenterLabel') - privateLabel = createTextMessageLabel('privateLabel', modules.game_interface.getMapPanel(), 'TopCenterLabel') - statusLabel = createTextMessageLabel('statusLabel', modules.game_interface.getMapPanel(), 'BottomLabel') + connect(g_game, 'onTextMessage', displayMessage) + connect(g_game, 'onPrivateTalk', onPrivateTalk) + connect(g_game, 'onGameEnd', clearMessages) + messagesPanel = g_ui.loadUI('textmessage.otui', modules.game_interface.getRootPanel()) end function terminate() - disconnect(g_game, { - onTextMessage = display, - onGameStart = clearMessages - }) - unregisterProtocol() - - removeEvent(warningLabel.hideEvent) - removeEvent(advanceLabel.hideEvent) - removeEvent(infoLabel.hideEvent) - removeEvent(privateLabel.hideEvent) - removeEvent(statusLabel.hideEvent) - - centerTextMessagePanel:destroy() - statusLabel:destroy() - privateLabel:destroy() + disconnect(g_game, 'onTextMessage', displayMessage) + disconnect(g_game, 'onPrivateTalk', onPrivateTalk) + disconnect(g_game, 'onGameEnd',clearMessages) + clearMessages() + messagesPanel:destroy() end -function clearMessages() - warningLabel:hide() - advanceLabel:hide() - infoLabel:hide() - privateLabel:hide() - statusLabel:hide() +function calculateVisibleTime(text) + return math.max(#text * 100, 4000) end -function createTextMessageLabel(id, parent, class) - local label = g_ui.createWidget(class, parent) - label:setFont('verdana-11px-rounded') - label:setId(id) - return label -end - -function displayMessage(msgtype, msg, time) +function displayMessage(mode, text) if not g_game.isOnline() then return end - msgtype = MessageTypes[msgtype] - if msgtype.consoleTab ~= nil then - if msgtype.consoleOption == nil or Options.getOption(msgtype.consoleOption) then - modules.game_console.addText(msg, msgtype, msgtype.consoleTab) - end + local msgtype = MessageTypes[mode] + + if not msgtype then + perror('unhandled message mode ' .. mode) + return end - if msgtype.labelId then - local label = modules.game_interface.getMapPanel():recursiveGetChildById(msgtype.labelId) + if msgtype.consoleTab ~= nil and (msgtype.consoleOption == nil or Options.getOption(msgtype.consoleOption)) then + modules.game_console.addText(text, msgtype, tr(msgtype.consoleTab)) + --TODO move to game_console + end - label:setText(msg) + if msgtype.screenTarget then + local label = messagesPanel:recursiveGetChildById(msgtype.screenTarget) + label:setText(text) label:setColor(msgtype.color) - - if not time then - time = math.max(#msg * 100, 4000) - else - time = time * 1000 - end + label:setVisible(true) removeEvent(label.hideEvent) - addEvent(function() label:setVisible(true) end) - label.hideEvent = scheduleEvent(function() label:setVisible(false) end, time) + label.hideEvent = scheduleEvent(function() label:setVisible(false) end, calculateVisibleTime(text)) end end -function displayStatus(msg, time) - displayMessage('StatusSmall', msg) +function displayStatusMessage(text) + displayMessage(MessageModes.Status, text) +end + +function displayGameMessage(text) + displayMessage(MessageModes.Game, text) end -function displayEventAdvance(msg, time) - displayMessage('EventAdvance', msg, time) +function clearMessages() + for _i,child in pairs(messagesPanel:recursiveGetChildren()) do + if child:getId():match('Label') then + child:hide() + removeEvent(child.hideEvent) + end + end end -function displayPrivate(msg, time) - displayMessage('Private', time) +function onPrivateTalk(code, text, speaker, speakerlevel, statmentid) + if Options.getOption('showPrivateMessagesOnScreen') then + displayMessage(code, speaker .. ':\n' .. text) + end end diff --git a/modules/game_textmessage/textmessage.otmod b/modules/game_textmessage/textmessage.otmod index 4595de19..a640e4b0 100644 --- a/modules/game_textmessage/textmessage.otmod +++ b/modules/game_textmessage/textmessage.otmod @@ -4,13 +4,6 @@ Module author: edubart website: www.otclient.info sandboxed: true - - dependencies: - - game_interface - - scripts: - - protocol.lua - - textmessage.lua - + scripts: [ textmessage.lua ] @onLoad: init() - @onUnload: terminate() + @onUnload: terminate() \ No newline at end of file diff --git a/modules/game_textmessage/textmessage.otui b/modules/game_textmessage/textmessage.otui index 4e26dfbb..7af5ed1f 100644 --- a/modules/game_textmessage/textmessage.otui +++ b/modules/game_textmessage/textmessage.otui @@ -1,4 +1,4 @@ -CenterLabel < UILabel +TextMessageLabel < UILabel font: verdana-11px-rounded text-align: center text-wrap: true @@ -6,17 +6,35 @@ CenterLabel < UILabel margin-bottom: 2 visible: false -TopCenterLabel < UILabel - font: verdana-11px-rounded - text-align: center - text-wrap: true - visible: false - anchors.top: parent.top - anchors.bottom: centerTextMessagePanel.top - anchors.horizontalCenter: parent.horizontalCenter - width: 275 +Panel + anchors.fill: gameMapPanel + focusable: false + + Panel + id: centerTextMessagePanel + layout: + type: verticalBox + fit-children: true + width: 360 + anchors.centerIn: parent + + TextMessageLabel + id: highCenterLabel + TextMessageLabel + id: middleCenterLabel + TextMessageLabel + id: lowCenterLabel + + TextMessageLabel + id: privateLabel + anchors.top: parent.top + anchors.bottom: centerTextMessagePanel.top + anchors.horizontalCenter: parent.horizontalCenter + text-auto-resize: false + width: 275 -BottomLabel < CenterLabel - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right + TextMessageLabel + id: statusLabel + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right diff --git a/modules/gamelib/const.lua b/modules/gamelib/const.lua index c0d8d7a3..0e4704fa 100644 --- a/modules/gamelib/const.lua +++ b/modules/gamelib/const.lua @@ -34,6 +34,13 @@ SouthEast = 5 SouthWest = 6 NorthWest = 7 +FightOffensive = 1 +FightBalanced = 2 +FightDefensive = 3 + +DontChase = 0 +ChaseOpponent = 1 + GameExtendedOpcode = 0 GameProtocolChecksum = 1 GameAccountNames = 2 @@ -59,6 +66,72 @@ GameReverseCreatureStack = 21 GameMagicEffectU16 = 22 GamePlayerMarket = 23 +TextColors = { + red = '#f55e5e', --'#c83200' + orange = '#f36500', --'#c87832' + yellow = '#ffff00', --'#e6c832' + green = '#00EB00', --'#3fbe32' + lightblue = '#5ff7f7', + --blue1 = '#6e50dc', + --blue2 = '#3264c8', + --blue3 = '#0096c8', + white = '#ffffff' --'#bebebe' +} + +MessageModes = { + None = 0, + Say = 1, + Whisper = 2, + Yell = 3, + PrivateFrom = 4, + PrivateTo = 5, + ChannelManagement = 6, + Channel = 7, + ChannelHighlight = 8, + Spell = 9, + NpcFrom = 10, + NpcTo = 11, + GamemasterBroadcast = 12, + GamemasterChannel = 13, + GamemasterPrivateFrom = 14, + GamemasterPrivateTo = 15, + Login = 16, + Warning = 17, + Game = 18, + Failure = 19, + Look = 20, + DamageDealed = 21, + DamageReceived = 22, + Heal = 23, + Exp = 24, + DamageOthers = 25, + HealOthers = 26, + ExpOthers = 27, + Status = 28, + Loot = 29, + TradeNpc = 30, + Guild = 31, + PartyManagement = 32, + Party = 33, + BarkLow = 34, + BarkLoud = 35, + Report = 36, + HotkeyUse = 37, + TutorialHint = 38, + Thankyou = 39, + Market = 40, + BeyondLast = 41, + MonsterYell = 42, + MonsterSay = 43, + Red = 44, + Blue = 45, + RVRChannel = 46, + RVRAnswer = 47, + RVRContinue = 48, + Last = 49, + Invalid = 255 +} + OTSERV_RSA = "1091201329673994292788609605089955415282375029027981291234687579" .. "3726629149257644633073969600111060390723088861007265581882535850" .. "3429057592827629436413108566029093628212635953836686562675849720" .. diff --git a/src/otclient/CMakeLists.txt b/src/otclient/CMakeLists.txt index aa339c2d..b1b837a9 100644 --- a/src/otclient/CMakeLists.txt +++ b/src/otclient/CMakeLists.txt @@ -87,6 +87,7 @@ set(otclient_SOURCES ${otclient_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/luavaluecasts.h # net + ${CMAKE_CURRENT_LIST_DIR}/protocolcodes.cpp ${CMAKE_CURRENT_LIST_DIR}/protocolcodes.h ${CMAKE_CURRENT_LIST_DIR}/protocolgame.cpp ${CMAKE_CURRENT_LIST_DIR}/protocolgame.h diff --git a/src/otclient/const.h b/src/otclient/const.h index 7617d521..fbbcd4c4 100644 --- a/src/otclient/const.h +++ b/src/otclient/const.h @@ -255,21 +255,60 @@ namespace Otc IconPz = 16384 }; - enum SpeakType { - SpeakSay = 1, - SpeakWhisper, - SpeakYell, - SpeakBroadcast, - SpeakPrivate, - SpeakPrivateRed, - SpeakPrivatePlayerToNpc, - SpeakPrivateNpcToPlayer, - SpeakChannelYellow, - SpeakChannelWhite, - SpeakChannelRed, - SpeakChannelOrange, - SpeakMonsterSay, - SpeakMonsterYell + enum MessageMode { + MessageNone = 0, + MessageSay = 1, + MessageWhisper = 2, + MessageYell = 3, + MessagePrivateFrom = 4, + MessagePrivateTo = 5, + MessageChannelManagement = 6, + MessageChannel = 7, + MessageChannelHighlight = 8, + MessageSpell = 9, + MessageNpcFrom = 10, + MessageNpcTo = 11, + MessageGamemasterBroadcast = 12, + MessageGamemasterChannel = 13, + MessageGamemasterPrivateFrom = 14, + MessageGamemasterPrivateTo = 15, + MessageLogin = 16, + MessageWarning = 17, + MessageGame = 18, + MessageFailure = 19, + MessageLook = 20, + MessageDamageDealed = 21, + MessageDamageReceived = 22, + MessageHeal = 23, + MessageExp = 24, + MessageDamageOthers = 25, + MessageHealOthers = 26, + MessageExpOthers = 27, + MessageStatus = 28, + MessageLoot = 29, + MessageTradeNpc = 30, + MessageGuild = 31, + MessagePartyManagement = 32, + MessageParty = 33, + MessageBarkLow = 34, + MessageBarkLoud = 35, + MessageReport = 36, + MessageHotkeyUse = 37, + MessageTutorialHint = 38, + MessageThankyou = 39, + MessageMarket = 40, + MessageBeyondLast = 41, + + // deprecated + MessageMonsterYell = 42, + MessageMonsterSay = 43, + MessageRed = 44, + MessageBlue = 45, + MessageRVRChannel = 46, + MessageRVRAnswer = 47, + MessageRVRContinue = 48, + LastMessage = 49, + MessageInvalid = 255, }; enum GameFeature { diff --git a/src/otclient/creature.cpp b/src/otclient/creature.cpp index 376145a8..25ac69d8 100644 --- a/src/otclient/creature.cpp +++ b/src/otclient/creature.cpp @@ -57,15 +57,6 @@ Creature::Creature() : Thing() m_footStep = 0; } -/* -PainterShaderProgramPtr outfitProgram; -int HEAD_COLOR_UNIFORM = 10; -int BODY_COLOR_UNIFORM = 11; -int LEGS_COLOR_UNIFORM = 12; -int FEET_COLOR_UNIFORM = 13; -int MASK_TEXTURE_UNIFORM = 14; -*/ - void Creature::draw(const Point& dest, float scaleFactor, bool animate) { Point animationOffset = animate ? m_walkOffset : Point(0,0); diff --git a/src/otclient/game.cpp b/src/otclient/game.cpp index 7a5c5dca..f59477ba 100644 --- a/src/otclient/game.cpp +++ b/src/otclient/game.cpp @@ -32,6 +32,7 @@ #include #include "luavaluecasts.h" #include "protocolgame.h" +#include "protocolcodes.h" Game g_game; @@ -151,22 +152,22 @@ void Game::processPing() g_lua.callGlobalField("g_game", "onPing"); } -void Game::processTextMessage(const std::string& type, const std::string& message) +void Game::processTextMessage(Otc::MessageMode mode, const std::string& text) { - g_lua.callGlobalField("g_game","onTextMessage", type, message); + g_lua.callGlobalField("g_game", "onTextMessage", mode, text); } -void Game::processCreatureSpeak(const std::string& name, int level, Otc::SpeakType type, const std::string& message, int channelId, const Position& creaturePos) +void Game::processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos) { - if(creaturePos.isValid() && (type == Otc::SpeakSay || type == Otc::SpeakWhisper || type == Otc::SpeakYell - || type == Otc::SpeakMonsterSay || type == Otc::SpeakMonsterYell || type == Otc::SpeakPrivateNpcToPlayer)) + if(pos.isValid() && (mode == Otc::MessageSay || mode == Otc::MessageWhisper || mode == Otc::MessageYell || + mode == Otc::MessageMonsterSay || mode == Otc::MessageMonsterYell || mode == Otc::MessageNpcFrom)) { StaticTextPtr staticText = StaticTextPtr(new StaticText); - staticText->addMessage(name, type, message); - g_map.addThing(staticText, creaturePos); + staticText->addMessage(name, mode, text); + g_map.addThing(staticText, pos); } - g_lua.callGlobalField("g_game", "onCreatureSpeak", name, level, type, message, channelId, creaturePos); + g_lua.callGlobalField("g_game", "onTalk", name, level, mode, text, channelId, pos); } void Game::processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector& items) @@ -769,21 +770,21 @@ void Game::talk(const std::string& message) { if(!canPerformGameAction() || message.empty()) return; - talkChannel(Otc::SpeakSay, 0, message); + talkChannel(Otc::MessageSay, 0, message); } -void Game::talkChannel(Otc::SpeakType speakType, int channelId, const std::string& message) +void Game::talkChannel(Otc::MessageMode mode, int channelId, const std::string& message) { if(!canPerformGameAction() || message.empty()) return; - m_protocolGame->sendTalk(speakType, channelId, "", message); + m_protocolGame->sendTalk(mode, channelId, "", message); } -void Game::talkPrivate(Otc::SpeakType speakType, const std::string& receiver, const std::string& message) +void Game::talkPrivate(Otc::MessageMode mode, const std::string& receiver, const std::string& message) { if(!canPerformGameAction() || receiver.empty() || message.empty()) return; - m_protocolGame->sendTalk(speakType, 0, receiver, message); + m_protocolGame->sendTalk(mode, 0, receiver, message); } void Game::openPrivateChannel(const std::string& receiver) @@ -1145,6 +1146,8 @@ void Game::setClientVersion(int version) m_protocolVersion = version; + Proto::buildMessageModesMap(version); + g_lua.callGlobalField("g_game", "onClientVersionChange", version); } diff --git a/src/otclient/game.h b/src/otclient/game.h index 5cd5ce62..c9f5d336 100644 --- a/src/otclient/game.h +++ b/src/otclient/game.h @@ -60,8 +60,8 @@ protected: void processWalkCancel(Otc::Direction direction); // message related - void processTextMessage(const std::string& type, const std::string& message); // deprecated - void processCreatureSpeak(const std::string& name, int level, Otc::SpeakType type, const std::string& message, int channelId, const Position& creaturePos); + void processTextMessage(Otc::MessageMode mode, const std::string& text); + void processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos); // container related void processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector& items); @@ -155,8 +155,8 @@ public: // talk related void talk(const std::string& message); - void talkChannel(Otc::SpeakType speakType, int channelId, const std::string& message); - void talkPrivate(Otc::SpeakType speakType, const std::string& receiver, const std::string& message); + void talkChannel(Otc::MessageMode mode, int channelId, const std::string& message); + void talkPrivate(Otc::MessageMode mode, const std::string& receiver, const std::string& message); // channel related void openPrivateChannel(const std::string& receiver); diff --git a/src/otclient/map.cpp b/src/otclient/map.cpp index b03006c0..8d1daa94 100644 --- a/src/otclient/map.cpp +++ b/src/otclient/map.cpp @@ -618,7 +618,7 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos) StaticTextPtr cStaticText = *it; if(cStaticText->getPosition() == pos) { // try to combine messages - if(cStaticText->addMessage(staticText->getName(), staticText->getMessageType(), staticText->getFirstMessage())) { + if(cStaticText->addMessage(staticText->getName(), staticText->getMessageMode(), staticText->getFirstMessage())) { mustAdd = false; break; } else { diff --git a/src/otclient/protocolcodes.cpp b/src/otclient/protocolcodes.cpp new file mode 100644 index 00000000..d6460c8c --- /dev/null +++ b/src/otclient/protocolcodes.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "protocolcodes.h" + +namespace Proto { + +std::map messageModesMap; + +void buildMessageModesMap(int version) { + messageModesMap.clear(); + if(version >= 900) { + for(int i=Otc::MessageNone;i<=Otc::MessageBeyondLast;++i) + messageModesMap[i] = i; + } else if(version >= 861) { + messageModesMap[Otc::MessageNone] = 0; + messageModesMap[Otc::MessageSay] = 1; + messageModesMap[Otc::MessageWhisper] = 2; + messageModesMap[Otc::MessageYell] = 3; + messageModesMap[Otc::MessageNpcFrom] = 4; + messageModesMap[Otc::MessageNpcTo] = 5; + messageModesMap[Otc::MessagePrivateFrom] = 6; + messageModesMap[Otc::MessagePrivateTo] = 6; + messageModesMap[Otc::MessageChannelHighlight] = 7; + messageModesMap[Otc::MessageChannel] = 8; + messageModesMap[Otc::MessageGamemasterBroadcast] = 9; + messageModesMap[Otc::MessageGamemasterChannel] = 10; + messageModesMap[Otc::MessageGamemasterPrivateFrom] = 11; + messageModesMap[Otc::MessageGamemasterPrivateTo] = 11; + messageModesMap[Otc::MessageChannelManagement] = 12; + messageModesMap[Otc::MessageMonsterSay] = 13; + messageModesMap[Otc::MessageMonsterYell] = 14; + messageModesMap[Otc::MessageWarning] = 15; + messageModesMap[Otc::MessageGame] = 16; + messageModesMap[Otc::MessageLogin] = 17; + messageModesMap[Otc::MessageStatus] = 18; + messageModesMap[Otc::MessageLook] = 19; + messageModesMap[Otc::MessageFailure] = 20; + messageModesMap[Otc::MessageBlue] = 21; + messageModesMap[Otc::MessageRed] = 22; + } else if(version >= 854) { + messageModesMap[Otc::MessageNone] = 0; + messageModesMap[Otc::MessageSay] = 1; + messageModesMap[Otc::MessageWhisper] = 2; + messageModesMap[Otc::MessageYell] = 3; + messageModesMap[Otc::MessageNpcFrom] = 4; + messageModesMap[Otc::MessageNpcTo] = 5; + messageModesMap[Otc::MessagePrivateFrom] = 6; + messageModesMap[Otc::MessagePrivateTo] = 6; + messageModesMap[Otc::MessageChannel] = 7; + messageModesMap[Otc::MessageChannelManagement] = 8; + messageModesMap[Otc::MessageRVRChannel] = 9; + messageModesMap[Otc::MessageRVRAnswer] = 10; + messageModesMap[Otc::MessageRVRContinue] = 11; + messageModesMap[Otc::MessageGamemasterBroadcast] = 12; + messageModesMap[Otc::MessageGamemasterChannel] = 13; + messageModesMap[Otc::MessageGamemasterPrivateFrom] = 14; + messageModesMap[Otc::MessageGamemasterPrivateTo] = 14; + messageModesMap[Otc::MessageChannelHighlight] = 15; + // 16, 17, 18 ?? + messageModesMap[Otc::MessageRed] = 18; + messageModesMap[Otc::MessageMonsterSay] = 19; + messageModesMap[Otc::MessageMonsterYell] = 20; + messageModesMap[Otc::MessageWarning] = 21; + messageModesMap[Otc::MessageGame] = 22; + messageModesMap[Otc::MessageLogin] = 23; + messageModesMap[Otc::MessageStatus] = 24; + messageModesMap[Otc::MessageLook] = 25; + messageModesMap[Otc::MessageFailure] = 26; + messageModesMap[Otc::MessageBlue] = 27; + } else if(version >= 810) { + messageModesMap[Otc::MessageNone] = 0; + messageModesMap[Otc::MessageSay] = 1; + messageModesMap[Otc::MessageWhisper] = 2; + messageModesMap[Otc::MessageYell] = 3; + messageModesMap[Otc::MessagePrivateFrom] = 4; + messageModesMap[Otc::MessagePrivateTo] = 4; + messageModesMap[Otc::MessageChannel] = 5; + messageModesMap[Otc::MessageRVRChannel] = 6; + messageModesMap[Otc::MessageRVRAnswer] = 7; + messageModesMap[Otc::MessageRVRContinue] = 8; + messageModesMap[Otc::MessageGamemasterBroadcast] = 9; + messageModesMap[Otc::MessageGamemasterChannel] = 10; + messageModesMap[Otc::MessageGamemasterPrivateFrom] = 11; + messageModesMap[Otc::MessageGamemasterPrivateTo] = 11; + messageModesMap[Otc::MessageChannelHighlight] = 12; + // 13, 14, 15 ?? + messageModesMap[Otc::MessageMonsterSay] = 16; + messageModesMap[Otc::MessageMonsterYell] = 17; + messageModesMap[Otc::MessageWarning] = 18; + messageModesMap[Otc::MessageGame] = 19; + messageModesMap[Otc::MessageLogin] = 20; + messageModesMap[Otc::MessageStatus] = 21; + messageModesMap[Otc::MessageLook] = 22; + messageModesMap[Otc::MessageFailure] = 23; + messageModesMap[Otc::MessageBlue] = 24; + messageModesMap[Otc::MessageRed] = 25; + } +} + +Otc::MessageMode translateMessageModeFromServer(uint8 mode) +{ + auto it = std::find_if(messageModesMap.begin(), messageModesMap.end(), [=] (const std::pair& p) { return p.second == mode; }); + if(it != messageModesMap.end()) + return (Otc::MessageMode)it->first; + return Otc::MessageInvalid; +} + +uint8 translateMessageModeToServer(Otc::MessageMode mode) +{ + if(mode < 0 || mode >= Otc::LastMessage) + return Otc::MessageInvalid; + auto it = messageModesMap.find(mode); + if(it != messageModesMap.end()) + return it->second; + return Otc::MessageInvalid; +} + +} \ No newline at end of file diff --git a/src/otclient/protocolcodes.h b/src/otclient/protocolcodes.h index eeb4ecff..a83e5b32 100644 --- a/src/otclient/protocolcodes.h +++ b/src/otclient/protocolcodes.h @@ -39,7 +39,8 @@ namespace Proto { Creature = 99 }; - enum GameServerOpcodes { + enum GameServerOpcodes : uint8 + { GameServerInitGame = 10, GameServerGMActions = 11, GameServerLoginError = 20, @@ -139,7 +140,8 @@ namespace Proto { GameServerShowModalDialog = 250 // 960 }; - enum ClientOpcodes { + enum ClientOpcodes : uint8 + { ClientEnterAccount = 1, ClientEnterGame = 10, ClientLeaveGame = 20, @@ -230,107 +232,6 @@ namespace Proto { ClientAnswerModalDialog = 249 // 960 }; - enum ServerSpeakType { -#if PROTOCOL>=910 - ServerSpeakSay = 1, - ServerSpeakWhisper, - ServerSpeakYell, - ServerSpeakPrivateFrom, // new - ServerSpeakPrivateTo, // new - ServerSpeakChannelManagement, // new - ServerSpeakChannelYellow, - ServerSpeakChannelOrange, - ServerSpeakSpell, // new - ServerSpeakPrivatePlayerToNpc, - ServerSpeakPrivateNpcToPlayer, - ServerSpeakBroadcast, - ServerSpeakChannelRed, - ServerSpeakPrivateRedFrom, // new - ServerSpeakPrivateRedTo, // new - // 16 - 33 - ServerSpeakMonsterSay = 34, - ServerSpeakMonsterYell, - - // unsupported - ServerSpeakRVRChannel = 255, - ServerSpeakRVRAnswer, - ServerSpeakRVRContinue, - ServerSpeakChannelRed2, - ServerSpeakChannelWhite -#elif PROTOCOL>=861 - ServerSpeakSay = 1, - ServerSpeakWhisper, - ServerSpeakYell, - ServerSpeakPrivatePlayerToNpc, - ServerSpeakPrivateNpcToPlayer, - ServerSpeakPrivateTo, - ServerSpeakPrivateFrom = ServerSpeakPrivateTo, - ServerSpeakChannelYellow, - ServerSpeakChannelWhite, - ServerSpeakBroadcast, - ServerSpeakChannelRed, - ServerSpeakPrivateRedTo, - ServerSpeakPrivateRedFrom = ServerSpeakPrivateRedTo, - ServerSpeakChannelOrange, - ServerSpeakMonsterSay, - ServerSpeakMonsterYell, - - // unsupported - ServerSpeakRVRChannel = 255, - ServerSpeakRVRAnswer, - ServerSpeakRVRContinue, - ServerSpeakChannelRed2 -#elif PROTOCOL>=854 - ServerSpeakSay = 1, - ServerSpeakWhisper, - ServerSpeakYell, - ServerSpeakPrivatePlayerToNpc, - ServerSpeakPrivateNpcToPlayer, - ServerSpeakPrivateTo, - ServerSpeakPrivateFrom = ServerSpeakPrivateTo, - ServerSpeakChannelYellow, - ServerSpeakChannelWhite, - ServerSpeakRVRChannel, - ServerSpeakRVRAnswer, - ServerSpeakRVRContinue, - ServerSpeakBroadcast, - ServerSpeakChannelRed, - ServerSpeakPrivateRedTo, - ServerSpeakPrivateRedFrom = ServerSpeakPrivateRedTo, - ServerSpeakChannelOrange, - // 16 - ServerSpeakChannelRed2 = 17, - // 18 - ServerSpeakMonsterSay = 19, - ServerSpeakMonsterYell -#elif PROTOCOL>=810 - ServerSpeakSay = 1, - ServerSpeakWhisper, - ServerSpeakYell, - ServerSpeakPrivateTo, - ServerSpeakPrivateFrom = ServerSpeakPrivateTo, - ServerSpeakChannelYellow, - ServerSpeakRVRChannel, - ServerSpeakRVRAnswer, - ServerSpeakRVRContinue, - ServerSpeakBroadcast, - ServerSpeakChannelRed, - ServerSpeakPrivateRedTo, - ServerSpeakPrivateRedFrom = ServerSpeakPrivateRedTo, - ServerSpeakChannelOrange, - // 13 - ServerSpeakChannelRed2 = 14, - // 15 - ServerSpeakMonsterSay = 16, - ServerSpeakMonsterYell, - - // unsupported - ServerSpeakPrivatePlayerToNpc = 255, - ServerSpeakPrivateNpcToPlayer, - ServerSpeakChannelWhite -#endif - }; - enum CreatureType { CreatureTypePlayer = 0, CreatureTypeMonster, @@ -346,50 +247,9 @@ namespace Proto { NpcEndId = 0xffffffff }; - inline Otc::SpeakType translateSpeakTypeFromServer(int type) { - switch(type) { - case Proto::ServerSpeakSay: return Otc::SpeakSay; - case Proto::ServerSpeakWhisper: return Otc::SpeakWhisper; - case Proto::ServerSpeakYell: return Otc::SpeakYell; - case Proto::ServerSpeakMonsterSay: return Otc::SpeakMonsterSay; - case Proto::ServerSpeakMonsterYell: return Otc::SpeakMonsterYell; - case Proto::ServerSpeakPrivateNpcToPlayer: return Otc::SpeakPrivateNpcToPlayer; - case Proto::ServerSpeakChannelYellow: return Otc::SpeakChannelYellow; - case Proto::ServerSpeakChannelWhite: return Otc::SpeakChannelWhite; - case Proto::ServerSpeakChannelRed: return Otc::SpeakChannelRed; - case Proto::ServerSpeakChannelRed2: return Otc::SpeakChannelRed; - case Proto::ServerSpeakChannelOrange: return Otc::SpeakChannelOrange; - case Proto::ServerSpeakPrivateTo: return Otc::SpeakPrivate; - case Proto::ServerSpeakPrivatePlayerToNpc: return Otc::SpeakPrivate; - case Proto::ServerSpeakBroadcast: return Otc::SpeakBroadcast; - case Proto::ServerSpeakPrivateRedTo: return Otc::SpeakPrivateRed; - default: - g_logger.error(stdext::format("unknown protocol speak type %d", type)); - return Otc::SpeakSay; - } - } - - inline Proto::ServerSpeakType translateSpeakTypeToServer(int type) { - switch(type) { - case Otc::SpeakSay: return Proto::ServerSpeakSay; - case Otc::SpeakWhisper: return Proto::ServerSpeakWhisper; - case Otc::SpeakYell: return Proto::ServerSpeakYell; - case Otc::SpeakBroadcast: return Proto::ServerSpeakBroadcast; - case Otc::SpeakPrivate: return Proto::ServerSpeakPrivateFrom; - case Otc::SpeakPrivateRed: return Proto::ServerSpeakPrivateRedFrom; - case Otc::SpeakPrivatePlayerToNpc: return Proto::ServerSpeakPrivatePlayerToNpc; - case Otc::SpeakPrivateNpcToPlayer: return Proto::ServerSpeakPrivateNpcToPlayer; - case Otc::SpeakChannelYellow: return Proto::ServerSpeakChannelYellow; - case Otc::SpeakChannelWhite: return Proto::ServerSpeakChannelWhite; - case Otc::SpeakChannelRed: return Proto::ServerSpeakChannelRed; - case Otc::SpeakChannelOrange: return Proto::ServerSpeakChannelOrange; - case Otc::SpeakMonsterSay: return Proto::ServerSpeakMonsterSay; - case Otc::SpeakMonsterYell: return Proto::ServerSpeakMonsterYell; - default: - g_logger.error(stdext::format("unknown protocol speak type desc %d", type)); - return Proto::ServerSpeakSay; - } - } + void buildMessageModesMap(int version); + Otc::MessageMode translateMessageModeFromServer(uint8 mode); + uint8 translateMessageModeToServer(Otc::MessageMode mode); } #endif diff --git a/src/otclient/protocolgame.h b/src/otclient/protocolgame.h index 111919e3..b00e016d 100644 --- a/src/otclient/protocolgame.h +++ b/src/otclient/protocolgame.h @@ -72,7 +72,7 @@ public: void sendEditText(uint id, const std::string& text); void sendEditList(uint id, int doorId, const std::string& text); void sendLook(const Position& position, int thingId, int stackpos); - void sendTalk(Otc::SpeakType speakType, int channelId, const std::string& receiver, const std::string& message); + void sendTalk(Otc::MessageMode mode, int channelId, const std::string& receiver, const std::string& message); void sendRequestChannels(); void sendJoinChannel(int channelId); void sendLeaveChannel(int channelId); @@ -169,7 +169,7 @@ private: void parseSpellCooldown(const InputMessagePtr& msg); void parseSpellGroupCooldown(const InputMessagePtr& msg); void parseMultiUseCooldown(const InputMessagePtr& msg); - void parseCreatureSpeak(const InputMessagePtr& msg); + void parseTalk(const InputMessagePtr& msg); void parseChannelList(const InputMessagePtr& msg); void parseOpenChannel(const InputMessagePtr& msg); void parseOpenPrivateChannel(const InputMessagePtr& msg); diff --git a/src/otclient/protocolgameparse.cpp b/src/otclient/protocolgameparse.cpp index fa343758..7fa1d4b8 100644 --- a/src/otclient/protocolgameparse.cpp +++ b/src/otclient/protocolgameparse.cpp @@ -211,7 +211,7 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg) parsePlayerCancelAttack(msg); break; case Proto::GameServerTalk: - parseCreatureSpeak(msg); + parseTalk(msg); break; case Proto::GameServerChannels: parseChannelList(msg); @@ -469,7 +469,6 @@ void ProtocolGame::parseTileTransformThing(const InputMessagePtr& msg) Position pos = thing->getPosition(); int stackpos = thing->getStackpos(); - assert(thing->getStackPriority() == newThing->getStackPriority()); if(!g_map.removeThing(thing)) { g_logger.traceError("unable to remove thing"); @@ -938,51 +937,49 @@ void ProtocolGame::parseMultiUseCooldown(const InputMessagePtr& msg) msg->getU32(); // cooldown } -void ProtocolGame::parseCreatureSpeak(const InputMessagePtr& msg) +void ProtocolGame::parseTalk(const InputMessagePtr& msg) { msg->getU32(); // channel statement guid std::string name = msg->getString(); int level = msg->getU16(); - int speakType = msg->getU8(); + Otc::MessageMode mode = Proto::translateMessageModeFromServer(msg->getU8()); int channelId = 0; - Position creaturePos; - - switch(speakType) { - case Proto::ServerSpeakSay: - case Proto::ServerSpeakWhisper: - case Proto::ServerSpeakYell: - case Proto::ServerSpeakMonsterSay: - case Proto::ServerSpeakMonsterYell: - case Proto::ServerSpeakPrivateNpcToPlayer: - creaturePos = getPosition(msg); + Position pos; + + switch(mode) { + case Otc::MessageSay: + case Otc::MessageWhisper: + case Otc::MessageYell: + case Otc::MessageMonsterSay: + case Otc::MessageMonsterYell: + case Otc::MessageNpcFrom: + case Otc::MessageBarkLow: + case Otc::MessageBarkLoud: + case Otc::MessageSpell: + pos = getPosition(msg); break; - case Proto::ServerSpeakChannelYellow: - case Proto::ServerSpeakChannelWhite: - case Proto::ServerSpeakChannelRed: - case Proto::ServerSpeakChannelRed2: - case Proto::ServerSpeakChannelOrange: + case Otc::MessageChannel: + case Otc::MessageChannelManagement: + case Otc::MessageChannelHighlight: + case Otc::MessageGamemasterChannel: channelId = msg->getU16(); break; - case Proto::ServerSpeakPrivateFrom: - case Proto::ServerSpeakPrivatePlayerToNpc: - case Proto::ServerSpeakBroadcast: - case Proto::ServerSpeakPrivateRedFrom: + case Otc::MessagePrivateFrom: + case Otc::MessageGamemasterBroadcast: + case Otc::MessageGamemasterPrivateFrom: break; - case Proto::ServerSpeakRVRChannel: + case Otc::MessageRVRChannel: msg->getU32(); break; - //case Proto::ServerSpeakChannelManagement: - //case Proto::ServerSpeakSpell: default: - stdext::throw_exception(stdext::format("unknown speak type %d", speakType)); + stdext::throw_exception(stdext::format("unknown message mode %d", mode)); break; } - std::string message = msg->getString(); - Otc::SpeakType type = Proto::translateSpeakTypeFromServer(speakType); + std::string text = msg->getString(); - g_game.processCreatureSpeak(name, level, type, message, channelId, creaturePos); + g_game.processTalk(name, level, mode, text, channelId, pos); } void ProtocolGame::parseChannelList(const InputMessagePtr& msg) @@ -1066,9 +1063,58 @@ void ProtocolGame::parseRuleViolationLock(const InputMessagePtr& msg) void ProtocolGame::parseTextMessage(const InputMessagePtr& msg) { - msg->getU8(); // type - msg->getString(); // message - // this is now handled by game_textmessage module + int code = msg->getU8(); + Otc::MessageMode mode = Proto::translateMessageModeFromServer(code); + std::string text; + + switch(mode) { + case Otc::MessageChannelManagement: { + int channel = msg->getU16(); + text = msg->getString(); + break; + } + case Otc::MessageDamageDealed: + case Otc::MessageDamageReceived: + case Otc::MessageDamageOthers: { + Position pos = getPosition(msg); + uint value = msg->getU32(); + int color = msg->getU8(); + msg->getU32(); // ?? + msg->getU8(); // ?? + text = msg->getString(); + + AnimatedTextPtr animatedText = AnimatedTextPtr(new AnimatedText); + animatedText->setColor(color); + animatedText->setText(stdext::to_string(value)); + g_map.addThing(animatedText, pos); + break; + } + case Otc::MessageHeal: + case Otc::MessageExp: + case Otc::MessageHealOthers: + case Otc::MessageExpOthers: { + Position pos = getPosition(msg); + uint value = msg->getU32(); + int color = msg->getU8(); + msg->getU32(); // ?? + msg->getU8(); // ?? + text = msg->getString(); + + AnimatedTextPtr animatedText = AnimatedTextPtr(new AnimatedText); + animatedText->setColor(color); + animatedText->setText(stdext::to_string(value)); + g_map.addThing(animatedText, pos); + break; + } + case Otc::MessageInvalid: + stdext::throw_exception(stdext::format("unknown message mode %d", mode)); + break; + default: + text = msg->getString(); + break; + } + + g_game.processTextMessage(mode, text); } void ProtocolGame::parseCancelWalk(const InputMessagePtr& msg) diff --git a/src/otclient/protocolgamesend.cpp b/src/otclient/protocolgamesend.cpp index 11f6a0a6..d1af5d5f 100644 --- a/src/otclient/protocolgamesend.cpp +++ b/src/otclient/protocolgamesend.cpp @@ -435,26 +435,33 @@ void ProtocolGame::sendLook(const Position& position, int thingId, int stackpos) send(msg); } -void ProtocolGame::sendTalk(Otc::SpeakType speakType, int channelId, const std::string& receiver, const std::string& message) +void ProtocolGame::sendTalk(Otc::MessageMode mode, int channelId, const std::string& receiver, const std::string& message) { - if(message.length() > 255 || message.length() <= 0) + if(message.empty()) return; - int serverSpeakType = Proto::translateSpeakTypeToServer(speakType); + if(message.length() > 255) { + g_logger.traceError("message too large"); + return; + } OutputMessagePtr msg(new OutputMessage); msg->addU8(Proto::ClientTalk); - msg->addU8(serverSpeakType); + msg->addU8(Proto::translateMessageModeToServer(mode)); - switch(serverSpeakType) { - case Proto::ServerSpeakPrivateFrom: - case Proto::ServerSpeakPrivateRedFrom: + switch(mode) { + case Otc::MessagePrivateTo: + case Otc::MessageGamemasterPrivateTo: msg->addString(receiver); break; - case Proto::ServerSpeakChannelYellow: - case Proto::ServerSpeakChannelRed: + case Otc::MessageChannel: + case Otc::MessageChannelHighlight: + case Otc::MessageChannelManagement: + case Otc::MessageGamemasterChannel: msg->addU16(channelId); break; + default: + break; } msg->addString(message); diff --git a/src/otclient/statictext.cpp b/src/otclient/statictext.cpp index 41355148..fe92e908 100644 --- a/src/otclient/statictext.cpp +++ b/src/otclient/statictext.cpp @@ -47,16 +47,16 @@ void StaticText::drawText(const Point& dest, const Rect& parentRect) //} } -bool StaticText::addMessage(const std::string& name, Otc::SpeakType type, const std::string& message) +bool StaticText::addMessage(const std::string& name, Otc::MessageMode mode, const std::string& text) { //TODO: this could be moved to lua // first message if(m_messages.size() == 0) { m_name = name; - m_messageType = type; + m_mode = mode; } // check if we can really own the message - else if(m_name != name || m_messageType != type) { + else if(m_name != name || m_mode != mode) { return false; } // too many messages @@ -66,7 +66,7 @@ bool StaticText::addMessage(const std::string& name, Otc::SpeakType type, const m_updateEvent = nullptr; } - m_messages.push_back(message); + m_messages.push_back(text); compose(); if(!m_updateEvent) @@ -105,26 +105,26 @@ void StaticText::compose() //TODO: this could be moved to lua std::string text; - if(m_messageType == Otc::SpeakSay) { + if(m_mode == Otc::MessageSay) { text += m_name; text += " says:\n"; m_color = Color(239, 239, 0); - } else if(m_messageType == Otc::SpeakWhisper) { + } else if(m_mode == Otc::MessageWhisper) { text += m_name; text += " whispers:\n"; m_color = Color(239, 239, 0); - } else if(m_messageType == Otc::SpeakYell) { + } else if(m_mode == Otc::MessageYell) { text += m_name; text += " yells:\n"; m_color = Color(239, 239, 0); - } else if(m_messageType == Otc::SpeakMonsterSay || m_messageType == Otc::SpeakMonsterYell) { + } else if(m_mode == Otc::MessageMonsterSay || m_mode == Otc::MessageMonsterYell) { m_color = Color(254, 101, 0); - } else if(m_messageType == Otc::SpeakPrivateNpcToPlayer) { + } else if(m_mode == Otc::MessageNpcFrom) { text += m_name; text += " says:\n"; m_color = Color(95, 247, 247); } else { - g_logger.warning(stdext::format("Unknown speak type: %d", m_messageType)); + g_logger.warning(stdext::format("Unknown speak type: %d", m_mode)); } for(uint i = 0; i < m_messages.size(); ++i) { diff --git a/src/otclient/statictext.h b/src/otclient/statictext.h index 12145d0d..0bf62fbf 100644 --- a/src/otclient/statictext.h +++ b/src/otclient/statictext.h @@ -36,12 +36,12 @@ public: void drawText(const Point& dest, const Rect& parentRect); std::string getName() { return m_name; } - Otc::SpeakType getMessageType() { return m_messageType; } + Otc::MessageMode getMessageMode() { return m_mode; } std::string getFirstMessage() { return m_messages[0]; } - bool isYell() { return m_messageType == Otc::SpeakYell || m_messageType == Otc::SpeakMonsterYell; } + bool isYell() { return m_mode == Otc::MessageYell || m_mode == Otc::MessageMonsterYell; } - bool addMessage(const std::string& name, Otc::SpeakType type, const std::string& message); + bool addMessage(const std::string& name, Otc::MessageMode mode, const std::string& text); StaticTextPtr asStaticText() { return std::static_pointer_cast(shared_from_this()); } bool isStaticText() { return true; } @@ -54,7 +54,7 @@ private: Boolean m_yell; std::deque m_messages; std::string m_name; - Otc::SpeakType m_messageType; + Otc::MessageMode m_mode; Color m_color; CachedText m_cachedText; ScheduledEventPtr m_updateEvent; diff --git a/src/otclient/tile.cpp b/src/otclient/tile.cpp index 3d1eab11..6d66b202 100644 --- a/src/otclient/tile.cpp +++ b/src/otclient/tile.cpp @@ -192,6 +192,17 @@ ThingPtr Tile::addThing(const ThingPtr& thing, int stackPos) if(m_things.size() > MAX_THINGS) removeThing(m_things[MAX_THINGS]); + /* + // check stack priorities + // this code exists to find stackpos bugs faster + int lastPriority = 0; + for(const ThingPtr& thing : m_things) { + int priority = thing->getStackPriority(); + assert(lastPriority <= priority); + lastPriority = priority; + } + */ + update(); return oldObject; } @@ -510,13 +521,4 @@ void Tile::update() if(c != 0) m_minimapColorByte = c; } - - // check stack priorities - // this code exists to find stackpos bugs faster - int lastPriority = 0; - for(const ThingPtr& thing : m_things) { - int priority = thing->getStackPriority(); - assert(lastPriority <= priority); - lastPriority = priority; - } }