restore some game functionallity
* i'm gradually restoring game functionality with the new modules design, though still a lot to do * you can reload all scripts and modules using Ctrl+R shortcut while playing (finally! this is the reason of all this rework) * a bunch of fixes, but new regression too :P * fix performance issue that could lead freezes in the client in older machines * completely new game module with new design * fix crashs in map render * remove uigame.cpp (now every game input is via lua) * enable DEBUG macro by default, with it you are able to view any possible lua leak while running
|  | @ -1,5 +1,12 @@ | |||
| Client = {} | ||||
| 
 | ||||
| function Client.reloadScripts() | ||||
|   dofile 'otclientrc.lua' | ||||
|   reloadModules() | ||||
|   TextMessage.displayEventAdvance('All modules and scripts were reloaded.') | ||||
|   print('All modules and scripts were reloaded.') | ||||
| end | ||||
| 
 | ||||
| function Client.init() | ||||
|   g_window.setMinimumSize({ width = 600, height = 480 }) | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ Module | |||
|     - client_terminal | ||||
|     - client_modulemanager | ||||
|     - client_entergame | ||||
|     - game | ||||
| 
 | ||||
|   @onLoad: | | ||||
|     dofile 'client' | ||||
|  |  | |||
|  | @ -11,7 +11,10 @@ function Background.init() | |||
|   local clientVersionLabel = background:getChildById('clientVersionLabel') | ||||
|   clientVersionLabel:setText('OTClient ' .. g_app.getVersion() .. '\n' .. | ||||
|                              'Built on ' .. g_app.getBuildDate()) | ||||
|   Effects.fadeIn(clientVersionLabel, 1500) | ||||
| 
 | ||||
|   if not g_game.isOnline() then | ||||
|     Effects.fadeIn(clientVersionLabel, 1500) | ||||
|   end | ||||
| 
 | ||||
|   connect(g_game, { onGameStart = Background.hide }) | ||||
|   connect(g_game, { onGameEnd = Background.show }) | ||||
|  |  | |||
|  | @ -11,12 +11,12 @@ Panel | |||
|   focusable: false | ||||
| 
 | ||||
|   UILabel | ||||
|     background-color: #00000099 | ||||
|     id: clientVersionLabel | ||||
|     background-color: #00000099 | ||||
|     anchors.right: parent.right | ||||
|     anchors.bottom: parent.bottom | ||||
|     text-offset: 4 2 | ||||
|     height: 32 | ||||
|     width: 120 | ||||
|     color: #ffffff | ||||
|     font: verdana-11px-monochrome | ||||
|     font: verdana-11px-monochrome | ||||
|  |  | |||
|  | @ -52,7 +52,6 @@ local function tryLogin(charInfo, tries) | |||
|   Settings.set('lastUsedCharacter', charInfo.characterName) | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| function onGameLoginError(message) | ||||
|   CharacterList.destroyLoadBox() | ||||
|   local errorBox = displayErrorBox("Login Error", "Login error: " .. message) | ||||
|  | @ -67,6 +66,10 @@ end | |||
| 
 | ||||
| -- public functions | ||||
| function CharacterList.init() | ||||
|   charactersWindow = displayUI('characterlist.otui') | ||||
|   charactersWindow:hide() | ||||
|   characterList = charactersWindow:getChildById('characterList') | ||||
|   charactersWindow.onKeyPress = onCharactersWindowKeyPress | ||||
|   connect(g_game, { onLoginError = onGameLoginError }) | ||||
|   connect(g_game, { onConnectionError = onGameConnectionError }) | ||||
|   connect(g_game, { onGameStart = CharacterList.destroyLoadBox }) | ||||
|  | @ -74,11 +77,13 @@ function CharacterList.init() | |||
| end | ||||
| 
 | ||||
| function CharacterList.terminate() | ||||
|   disconnect(g_game, { onLoginError = onGameLoginError }) | ||||
|   disconnect(g_game, { onConnectionError = onGameConnectionError }) | ||||
|   disconnect(g_game, { onGameStart = CharacterList.destroyLoadBox }) | ||||
|   disconnect(g_game, { onGameEnd = CharacterList.show }) | ||||
|   characterList = nil | ||||
|   if charactersWindow then | ||||
|     charactersWindow:destroy() | ||||
|     charactersWindow = nil | ||||
|   end | ||||
|   charactersWindow:destroy() | ||||
|   charactersWindow = nil | ||||
|   if loadBox then | ||||
|     g_game.cancelLogin() | ||||
|     loadBox:destroy() | ||||
|  | @ -88,14 +93,9 @@ function CharacterList.terminate() | |||
| end | ||||
| 
 | ||||
| function CharacterList.create(characters, premDays) | ||||
|   if charactersWindow then | ||||
|     charactersWindow:destroy() | ||||
|   end | ||||
| 
 | ||||
|   charactersWindow = displayUI('characterlist.otui') | ||||
|   characterList = charactersWindow:getChildById('characterList') | ||||
|   CharacterList.show() | ||||
|   characterList:destroyChildren() | ||||
|   local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel') | ||||
|   connect(charactersWindow, {onKeyPress = onCharactersWindowKeyPress }) | ||||
| 
 | ||||
|   local focusLabel | ||||
|   for i,characterInfo in ipairs(characters) do | ||||
|  |  | |||
|  | @ -184,12 +184,8 @@ function Terminal.executeCommand(command) | |||
| 
 | ||||
|   -- detect and convert commands with simple syntax | ||||
|   local realCommand | ||||
|   if commandEnv[command] then | ||||
|     if type(commandEnv[command]) == "function" then | ||||
|       realCommand = command .. '()' | ||||
|     else | ||||
|       realCommand = 'print(' .. command .. ')' | ||||
|     end | ||||
|   if string.sub(command, 1, 1) == '=' then | ||||
|     realCommand = 'print(' .. string.sub(command,2) .. ')' | ||||
|   else | ||||
|     realCommand = command | ||||
|   end | ||||
|  |  | |||
|  | @ -30,25 +30,27 @@ end | |||
| 
 | ||||
| -- public functions | ||||
| function TopMenu.init() | ||||
|   connect(g_game, { onGameStart = TopMenu.showGameButtons, | ||||
|                     onGameEnd = TopMenu.hideGameButtons }) | ||||
| 
 | ||||
|   topMenu = displayUI('topmenu.otui') | ||||
| 
 | ||||
|   leftButtonsPanel = topMenu:getChildById('leftButtonsPanel') | ||||
|   rightButtonsPanel = topMenu:getChildById('rightButtonsPanel') | ||||
|   gameButtonsPanel = topMenu:getChildById('gameButtonsPanel') | ||||
| 
 | ||||
|   connect(g_game, { onGameStart = TopMenu.showGameButtons, | ||||
|                     onGameEnd = TopMenu.hideGameButtons }) | ||||
| end | ||||
| 
 | ||||
| function TopMenu.terminate() | ||||
|   disconnect(g_game, { onGameStart = TopMenu.showGameButtons, | ||||
|                        onGameEnd = TopMenu.hideGameButtons }) | ||||
| 
 | ||||
|   leftButtonsPanel = nil | ||||
|   rightButtonsPanel = nil | ||||
|   gameButtonsPanel = nil | ||||
| 
 | ||||
|   topMenu:destroy() | ||||
|   topMenu = nil | ||||
| 
 | ||||
|   disconnect(g_game, { onGameStart = TopMenu.showGameButtons, | ||||
|                        onGameEnd = TopMenu.hideGameButtons }) | ||||
| 
 | ||||
|   TopMenu = nil | ||||
| end | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,10 +10,12 @@ Module | |||
|     dofile 'ext/table' | ||||
|     dofile 'ext/string' | ||||
|     dofile 'ext/os' | ||||
| 
 | ||||
|     dofile 'math/point' | ||||
|     dofile 'math/size' | ||||
|     dofile 'math/color' | ||||
|     dofile 'math/rect' | ||||
| 
 | ||||
|     dofile 'const' | ||||
|     dofile 'util' | ||||
|     dofile 'globals' | ||||
|  | @ -35,8 +37,4 @@ Module | |||
|     dofile 'widgets/uitabbar' | ||||
|     dofile 'widgets/uipopupmenu' | ||||
|     dofile 'widgets/uiwindow' | ||||
|     --dofile 'widgets/uiminiwindow' | ||||
|     --dofile 'widgets/uiminiwindowcontainer' | ||||
|     dofile 'widgets/uimessagebox' | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -68,5 +68,3 @@ end | |||
| function reloadModules() | ||||
|   g_modules.reloadModules() | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -70,8 +70,8 @@ local function onWidgetKeyDown(widget, keyCode, keyboardModifiers) | |||
| end | ||||
| 
 | ||||
| local function onWidgetKeyPress(widget, keyCode, keyboardModifiers, autoRepeatTicks) | ||||
|   local keyComboDesc = determineKeyComboDesc(keyCode, keyboardModifiers) | ||||
|   if keyCode == KeyUnknown then return false end | ||||
|   local keyComboDesc = determineKeyComboDesc(keyCode, keyboardModifiers) | ||||
|   local comboConf = widget.boundKeyPressCombos[keyComboDesc] | ||||
|   if comboConf and (autoRepeatTicks >= comboConf.autoRepeatDelay or autoRepeatTicks == 0) and comboConf.callback then | ||||
|     comboConf.callback() | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| Mouse = {} | ||||
| 
 | ||||
| function Mouse.setTargetCursor() | ||||
|   g_window.setMouseCursor('/core_styles/icons/targetcursor.png', {x=9,y=9}) | ||||
|   g_window.setMouseCursor('/core_styles/cursors/targetcursor.png', {x=9,y=9}) | ||||
| end | ||||
| 
 | ||||
| function Mouse.restoreCursor() | ||||
|  |  | |||
|  | @ -36,7 +36,8 @@ function UITabBar:addTab(text, panel) | |||
|   tab.tabBar = self | ||||
|   tab:setText(text) | ||||
|   tab:setWidth(tab:getTextSize().width + tab:getPaddingLeft() + tab:getPaddingRight()) | ||||
|   connect(tab, { onClick = onTabClick }) | ||||
|   tab.onClick = onTabClick | ||||
|   tab.onDestroy = function() tab.tabPanel:destroy() end | ||||
| 
 | ||||
|   table.insert(self.tabs, tab) | ||||
|   if #self.tabs == 1 then | ||||
|  |  | |||
|  | @ -23,9 +23,7 @@ Module | |||
|     importStyle 'styles/tabbars.otui' | ||||
|     importStyle 'styles/windows.otui' | ||||
|     importStyle 'styles/listboxes.otui' | ||||
|     importStyle 'styles/items.otui' | ||||
|     importStyle 'styles/creatures.otui' | ||||
|     importStyle 'styles/popupmenus.otui' | ||||
|     importStyle 'styles/comboboxes.otui' | ||||
|     importStyle 'styles/spinboxes.otui' | ||||
|     importStyle 'styles/messagebox.otui' | ||||
|     importStyle 'styles/messageboxes.otui' | ||||
|  |  | |||
| Before Width: | Height: | Size: 932 B | 
|  | @ -18,7 +18,7 @@ Button < UIButton | |||
|     color: #f0ad4d88 | ||||
|     image-color: #ffffff88 | ||||
| 
 | ||||
| ConsoleButton < UIButton | ||||
| TabButton < UIButton | ||||
|   size: 20 20 | ||||
|   image-source: /core_styles/styles/images/tabbutton.png | ||||
|   image-color: white | ||||
|  |  | |||
|  | @ -42,4 +42,4 @@ ComboBox < UIComboBox | |||
|     image-clip: 0 20 89 20 | ||||
| 
 | ||||
|   $on: | ||||
|     image-clip: 0 40 89 20 | ||||
|     image-clip: 0 40 89 20 | ||||
|  |  | |||
|  | @ -4,4 +4,3 @@ ProgressBar < UIProgressBar | |||
|   border: 1 black | ||||
|   image: /core_styles/styles/images/progressbar.png | ||||
|   image-border: 1 | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,4 +3,4 @@ HorizontalSeparator < UIWidget | |||
|   image-border-top: 2 | ||||
|   height: 2 | ||||
|   phantom: true | ||||
|   focusable: false | ||||
|   focusable: false | ||||
|  |  | |||
|  | @ -31,4 +31,4 @@ TabBarButton < UIButton | |||
|     color: #80c7f8 | ||||
| 
 | ||||
|   $on !checked: | ||||
|     color: #F55E5E | ||||
|     color: #F55E5E | ||||
|  |  | |||
|  | @ -22,24 +22,3 @@ Window < UIWindow | |||
| 
 | ||||
| MainWindow < Window | ||||
|   anchors.centerIn: parent | ||||
| 
 | ||||
| MiniWindow < UIMiniWindow | ||||
|   font: verdana-11px-antialised | ||||
|   //icon: /core_styles/icons/login.png | ||||
|   icon-rect: 4 4 16 16 | ||||
|   width: 192 | ||||
|   height: 200 | ||||
|   text-offset: 26 5 | ||||
|   text-align: topLeft | ||||
|   margin-top: 2 | ||||
|   margin-left: 6 | ||||
|   margin-right: 6 | ||||
|   move-policy: free updated | ||||
|   image-source: /core_styles/styles/images/mini_window.png | ||||
|   image-border: 4 | ||||
|   image-border-top: 23 | ||||
|   padding: 25 8 2 8 | ||||
| 
 | ||||
|   $on: | ||||
|     height: 24 | ||||
|     image-border-bottom: 1 | ||||
|  | @ -0,0 +1,24 @@ | |||
| SkullNone = 0 | ||||
| SkullYellow = 1 | ||||
| SkullGreen = 2 | ||||
| SkullWhite = 3 | ||||
| SkullRed = 4 | ||||
| SkullBlack = 5 | ||||
| SkullOrange = 6 | ||||
| 
 | ||||
| ShieldNone = 0 | ||||
| ShieldWhiteYellow = 1 | ||||
| ShieldWhiteBlue = 2 | ||||
| ShieldBlue = 3 | ||||
| ShieldYellow = 4 | ||||
| ShieldBlueSharedExp = 5 | ||||
| ShieldYellowSharedExp = 6 | ||||
| ShieldBlueNoSharedExpBlink = 7 | ||||
| ShieldYellowNoSharedExpBlink = 8 | ||||
| ShieldBlueNoSharedExp = 9 | ||||
| ShieldYellowNoSharedExp = 10 | ||||
| 
 | ||||
| EmblemNone = 0 | ||||
| EmblemGreen = 1 | ||||
| EmblemRed = 2 | ||||
| EmblemBlue = 3 | ||||
|  | @ -25,51 +25,51 @@ EmblemBlue = 3 | |||
| 
 | ||||
| function getSkullImagePath(skullId) | ||||
|   if skullId == SkullYellow then | ||||
|     return 'images/skull_yellow.png' | ||||
|     return 'icons/skull_yellow.png' | ||||
|   elseif skullId == SkullGreen then | ||||
|     return 'images/skull_green.png' | ||||
|     return 'icons/skull_green.png' | ||||
|   elseif skullId == SkullWhite then | ||||
|     return 'images/skull_white.png' | ||||
|     return 'icons/skull_white.png' | ||||
|   elseif skullId == SkullRed then | ||||
|     return 'images/skull_red.png' | ||||
|     return 'icons/skull_red.png' | ||||
|   elseif skullId == SkullBlack then | ||||
|     return 'images/skull_black.png' | ||||
|     return 'icons/skull_black.png' | ||||
|   elseif skullId == SkullOrange then | ||||
|     return 'images/skull_orange.png' | ||||
|     return 'icons/skull_orange.png' | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| function getShieldImagePathAndBlink(shieldId) | ||||
|   if shieldId == ShieldWhiteYellow then | ||||
|     return 'images/shield_yellow_white.png', false | ||||
|     return 'icons/shield_yellow_white.png', false | ||||
|   elseif shieldId == ShieldWhiteBlue then | ||||
|     return 'images/shield_blue_white.png', false | ||||
|     return 'icons/shield_blue_white.png', false | ||||
|   elseif shieldId == ShieldBlue then | ||||
|     return 'images/shield_blue.png', false | ||||
|     return 'icons/shield_blue.png', false | ||||
|   elseif shieldId == ShieldYellow then | ||||
|     return 'images/shield_yellow.png', false | ||||
|     return 'icons/shield_yellow.png', false | ||||
|   elseif shieldId == ShieldBlueSharedExp then | ||||
|     return 'images/shield_blue_shared.png', false | ||||
|     return 'icons/shield_blue_shared.png', false | ||||
|   elseif shieldId == ShieldYellowSharedExp then | ||||
|     return 'images/shield_yellow_shared.png', false | ||||
|     return 'icons/shield_yellow_shared.png', false | ||||
|   elseif shieldId == ShieldBlueNoSharedExpBlink then | ||||
|     return 'images/shield_blue_not_shared.png', true | ||||
|     return 'icons/shield_blue_not_shared.png', true | ||||
|   elseif shieldId == ShieldYellowNoSharedExpBlink then | ||||
|     return 'images/shield_yellow_not_shared.png', true | ||||
|     return 'icons/shield_yellow_not_shared.png', true | ||||
|   elseif shieldId == ShieldBlueNoSharedExp then | ||||
|     return 'images/shield_blue_not_shared.png', false | ||||
|     return 'icons/shield_blue_not_shared.png', false | ||||
|   elseif shieldId == ShieldYellowNoSharedExp then | ||||
|     return 'images/shield_yellow_not_shared.png', false | ||||
|     return 'icons/shield_yellow_not_shared.png', false | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| function getEmblemImagePath(emblemId) | ||||
|   if emblemId == EmblemGreen then | ||||
|     return 'images/emblem_green.png' | ||||
|     return 'icons/emblem_green.png' | ||||
|   elseif emblemId == EmblemRed then | ||||
|     return 'images/emblem_red.png' | ||||
|     return 'icons/emblem_red.png' | ||||
|   elseif emblemId == EmblemBlue then | ||||
|     return 'images/emblem_blue.png' | ||||
|     return 'icons/emblem_blue.png' | ||||
|   end | ||||
| end | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,11 +7,26 @@ Module | |||
| 
 | ||||
|   dependencies: | ||||
|     - game_tibiafiles | ||||
|     - client_background | ||||
|     //- game_shaders | ||||
| 
 | ||||
|   onLoad: | | ||||
|     dofile 'game' | ||||
|     dofile 'thing' | ||||
|   load-later: | ||||
|     - game_textmessage | ||||
|     - game_console | ||||
| 
 | ||||
|   @onLoad: | | ||||
|     importStyle 'styles/items.otui' | ||||
|     importStyle 'styles/creatures.otui' | ||||
|     importStyle 'styles/miniwindow.otui' | ||||
|     importStyle 'styles/countwindow.otui' | ||||
| 
 | ||||
|     dofile 'const' | ||||
| 
 | ||||
|     dofile 'widgets/uigamemap' | ||||
| 
 | ||||
|     dofile 'gameinterface' | ||||
|     dofile 'creature' | ||||
|     dofile 'player' | ||||
|     dofile 'map' | ||||
|     GameInterface.init() | ||||
| 
 | ||||
|   @onUnload: | | ||||
|     GameInterface.terminate() | ||||
|  |  | |||
|  | @ -0,0 +1,295 @@ | |||
| GameInterface = {} | ||||
| 
 | ||||
| local WALK_AUTO_REPEAT_DELAY = 90 | ||||
| local gameRootPanel | ||||
| local gameMapPanel | ||||
| local gameRightPanel | ||||
| local gameLeftPanel | ||||
| local gameBottomPanel | ||||
| local logoutButton | ||||
| 
 | ||||
| function GameInterface.init() | ||||
|   connect(g_game, { onGameStart = GameInterface.show }, true) | ||||
|   connect(g_game, { onGameEnd = GameInterface.hide }, true) | ||||
| 
 | ||||
|   gameRootPanel = displayUI('gameinterface.otui') | ||||
|   gameRootPanel:hide() | ||||
|   gameRootPanel:lower() | ||||
| 
 | ||||
|   gameMapPanel = gameRootPanel:getChildById('gameMapPanel') | ||||
|   gameRightPanel = gameRootPanel:getChildById('gameRightPanel') | ||||
|   gameLeftPanel = gameRootPanel:getChildById('gameLeftPanel') | ||||
|   gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel') | ||||
| 
 | ||||
|   logoutButton = TopMenu.addRightButton('logoutButton', 'Logout', 'images/logout.png', GameInterface.tryLogout) | ||||
|   logoutButton:hide() | ||||
| 
 | ||||
|   Keyboard.bindKeyPress('Up', function() g_game.walk(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Right', function() g_game.walk(East) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Down', function() g_game.walk(South) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Left', function() g_game.walk(West) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Numpad8', function() g_game.walk(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Numpad9', function() g_game.walk(NorthEast) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Numpad6', function() g_game.walk(East) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Numpad3', function() g_game.walk(SouthEast) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Numpad2', function() g_game.walk(South) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Numpad1', function() g_game.walk(SouthWest) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Numpad4', function() g_game.walk(West) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Numpad7', function() g_game.walk(NorthWest) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Ctrl+Up', function() g_game.turn(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Ctrl+Right', function() g_game.turn(East) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Ctrl+Down', function() g_game.turn(South) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Ctrl+Left', function() g_game.turn(West) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Ctrl+Numpad8', function() g_game.turn(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Ctrl+Numpad6', function() g_game.turn(East) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Ctrl+Numpad2', function() g_game.turn(South) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Ctrl+Numpad4', function() g_game.turn(West) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
|   Keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) | ||||
| 
 | ||||
|   if g_game.isOnline() then | ||||
|     GameInterface.show() | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| function GameInterface.terminate() | ||||
|   disconnect(g_game, { onGameStart = GameInterface.show }) | ||||
|   disconnect(g_game, { onGameEnd = GameInterface.hide }) | ||||
| 
 | ||||
|   logoutButton:destroy() | ||||
|   logoutButton = nil | ||||
|   gameRootPanel:destroy() | ||||
|   gameRootPanel = nil | ||||
|   gameMapPanel = nil | ||||
|   gameRightPanel = nil | ||||
|   gameLeftPanel = nil | ||||
|   gameBottomPanel = nil | ||||
|   GameInterface = nil | ||||
| end | ||||
| 
 | ||||
| function GameInterface.show() | ||||
|   g_app.onClose = GameInterface.tryExit | ||||
|   logoutButton:show() | ||||
|   Background.hide() | ||||
|   gameRootPanel:show() | ||||
|   gameRootPanel:focus() | ||||
|   gameMapPanel:followCreature(g_game.getLocalPlayer()) | ||||
| end | ||||
| 
 | ||||
| function GameInterface.hide() | ||||
|   gameRootPanel:hide() | ||||
|   logoutButton:hide() | ||||
|   Background.show() | ||||
|   g_app.onClose = nil | ||||
| end | ||||
| 
 | ||||
| function GameInterface.tryExit() | ||||
|   if g_game.isOnline() then | ||||
|     g_game.forceLogout() | ||||
|     scheduleEvent(exit, 10) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| function GameInterface.tryLogout() | ||||
|   if g_game.isOnline() then | ||||
|     g_game.safeLogout() | ||||
|     return true | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| function GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatureThing) | ||||
|   local menu = createWidget('PopupMenu') | ||||
| 
 | ||||
|   if lookThing then | ||||
|     menu:addOption('Look', function() g_game.look(lookThing) end) | ||||
|   end | ||||
| 
 | ||||
|   if useThing then | ||||
|     if useThing:isContainer() then | ||||
|       if useThing:isInsideContainer() then | ||||
|         menu:addOption('Open', function() g_game.open(useThing, useThing:getContainerId()) end) | ||||
|         menu:addOption('Open in new window', function() g_game.open(useThing, Containers.getFreeContainerId()) end) | ||||
|       else | ||||
|         menu:addOption('Open', function() g_game.open(useThing, Containers.getFreeContainerId()) end) | ||||
|       end | ||||
|     else | ||||
|       if useThing:isMultiUse() then | ||||
|         menu:addOption('Use with ...', function() g_game.startUseWith(useThing) end) | ||||
|       else | ||||
|         menu:addOption('Use', function() g_game.use(useThing) end) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     if useThing:isRotateable() then | ||||
|       menu:addOption('Rotate', function() g_game.rotate(useThing) end) | ||||
|     end | ||||
| 
 | ||||
|   end | ||||
| 
 | ||||
|   if lookThing and not lookThing:asCreature() and not lookThing:isNotMoveable() and lookThing:isPickupable() then | ||||
|     menu:addSeparator() | ||||
|     menu:addOption('Trade with ...', function() print('trade with') end) | ||||
|   end | ||||
| 
 | ||||
|   -- check for move up | ||||
| 
 | ||||
|   if creatureThing then | ||||
|     menu:addSeparator() | ||||
| 
 | ||||
|     if creatureThing:asLocalPlayer() then | ||||
|       menu:addOption('Set Outfit', function() g_game.requestOutfit() end) | ||||
| 
 | ||||
|       if creatureThing:isPartyMember() --[[and not fighting]] then | ||||
|         if creatureThing:isPartyLeader() then | ||||
|           if creatureThing:isPartySharedExperienceActive() then | ||||
|             menu:addOption('Disable Shared Experience', function() g_game.partyShareExperience(false) end) | ||||
|           else | ||||
|             menu:addOption('Enable Shared Experience', function() g_game.partyShareExperience(true) end) | ||||
|           end | ||||
|         end | ||||
|         menu:addOption('Leave Party', function() g_game.partyLeave() end) | ||||
|       end | ||||
| 
 | ||||
|     else | ||||
|       local localPlayer = g_game.getLocalPlayer() | ||||
|       if localPlayer then | ||||
|         if g_game.getAttackingCreature() ~= creatureThing then | ||||
|           menu:addOption('Attack', function() g_game.attack(creatureThing) end) | ||||
|         else | ||||
|           menu:addOption('Stop Attack', function() g_game.cancelAttack() end) | ||||
|         end | ||||
| 
 | ||||
|         if g_game.getFollowingCreature() ~= creatureThing then | ||||
|           menu:addOption('Follow', function() g_game.follow(creatureThing) end) | ||||
|         else | ||||
|           menu:addOption('Stop Follow', function() g_game.cancelFollow() end) | ||||
|         end | ||||
| 
 | ||||
|         if creatureThing:asPlayer() then | ||||
|           menu:addSeparator() | ||||
|           menu:addOption('Message to ' .. creatureThing:getName(), function() print('message') end) | ||||
|           menu:addOption('Add to VIP list', function() g_game.addVip(creatureThing:getName()) end) | ||||
| 
 | ||||
|           local localPlayerShield = localPlayer:asCreature():getShield() | ||||
|           local creatureShield = creatureThing:getShield() | ||||
| 
 | ||||
|           if localPlayerShield == ShieldNone or localPlayerShield == ShieldWhiteBlue then | ||||
|             if creatureShield == ShieldWhiteYellow then | ||||
|               menu:addOption('Join ' .. creatureThing:getName() .. '\'s Party', function() g_game.partyJoin(creatureThing:getId()) end) | ||||
|             else | ||||
|               menu:addOption('Invite to Party', function() g_game.partyInvite(creatureThing:getId()) end) | ||||
|             end | ||||
|           elseif localPlayerShield == ShieldWhiteYellow then | ||||
|             if creatureShield == ShieldWhiteBlue then | ||||
|               menu:addOption('Revoke ' .. creatureThing:getName() .. '\'s Invitation', function() g_game.partyRevokeInvitation(creatureThing:getId()) end) | ||||
|             end | ||||
|           elseif localPlayerShield == ShieldYellow or localPlayerShield == ShieldYellowSharedExp or localPlayerShield == ShieldYellowNoSharedExpBlink or localPlayerShield == ShieldYellowNoSharedExp then | ||||
|             if creatureShield == ShieldWhiteBlue then | ||||
|               menu:addOption('Revoke ' .. creatureThing:getName() .. '\'s Invitation', function() g_game.partyRevokeInvitation(creatureThing:getId()) end) | ||||
|             elseif creatureShield == ShieldBlue or creatureShield == ShieldBlueSharedExp or creatureShield == ShieldBlueNoSharedExpBlink or creatureShield == ShieldBlueNoSharedExp then | ||||
|               menu:addOption('Pass Leadership to ' .. creatureThing:getName(), function() g_game.partyPassLeadership(creatureThing:getId()) end) | ||||
|             else | ||||
|               menu:addOption('Invite to Party', function() g_game.partyInvite(creatureThing:getId()) end) | ||||
|             end | ||||
|           end | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     menu:addSeparator() | ||||
|     menu:addOption('Copy Name', function() g_window.setClipboardText(creatureThing:getName()) end) | ||||
| 
 | ||||
|   end | ||||
| 
 | ||||
|   menu:display(menuPosition) | ||||
| end | ||||
| 
 | ||||
| function GameInterface.processMouseAction(menuPosition, mouseButton, autoWalk, lookThing, useThing, creatureThing, multiUseThing) | ||||
|   local keyboardModifiers = g_window.getKeyboardModifiers() | ||||
| 
 | ||||
|   if autoWalk and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseLeftButton then | ||||
|     -- todo auto walk | ||||
|     return true | ||||
|   end | ||||
| 
 | ||||
|   if not Options.classicControl then | ||||
|     if keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton then | ||||
|       GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatureThing) | ||||
|       return true | ||||
|     elseif lookThing and keyboardModifiers == KeyboardShiftModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then | ||||
|       g_game.look(lookThing) | ||||
|       return true | ||||
|     elseif useThing and keyboardModifiers == KeyboardCtrlModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then | ||||
|       if useThing:isContainer() then | ||||
|         if useThing:isInsideContainer() then | ||||
|           g_game.open(useThing, useThing:getContainerId()) | ||||
|           return true | ||||
|         else | ||||
|           g_game.open(useThing, Containers.getFreeContainerId()) | ||||
|         return true | ||||
|         end | ||||
|       elseif useThing:isMultiUse() then | ||||
|         g_game.startUseWith(useThing) | ||||
|         return true | ||||
|       else | ||||
|         g_game.use(useThing) | ||||
|         return true | ||||
|       end | ||||
|       return true | ||||
|     elseif creatureThing and keyboardModifiers == KeyboardAltModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then | ||||
|       g_game.attack(creatureThing) | ||||
|       return true | ||||
|     end | ||||
|   else | ||||
|     if multiUseThing and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton then | ||||
|       if multiUseThing:asCreature() then | ||||
|         g_game.attack(multiUseThing:asCreature()) | ||||
|         return true | ||||
|       elseif multiUseThing:isContainer() then | ||||
|         if multiUseThing:isInsideContainer() then | ||||
|           g_game.open(multiUseThing, multiUseThing:getContainerId()) | ||||
|           return true | ||||
|         else | ||||
|           g_game.open(multiUseThing, Containers.getFreeContainerId()) | ||||
|           return true | ||||
|         end | ||||
|       elseif multiUseThing:isMultiUse() then | ||||
|         g_game.startUseWith(multiUseThing) | ||||
|         return true | ||||
|       else | ||||
|         g_game.use(multiUseThing) | ||||
|       end | ||||
|       return true | ||||
|     elseif lookThing and keyboardModifiers == KeyboardShiftModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then | ||||
|       g_game.look(lookThing) | ||||
|       return true | ||||
|     elseif useThing and keyboardModifiers == KeyboardCtrlModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then | ||||
|       GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatureThing) | ||||
|       return true | ||||
|     elseif creatureThing and keyboardModifiers == KeyboardAltModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then | ||||
|       g_game.attack(creatureThing) | ||||
|       return true | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   return false | ||||
| end | ||||
| 
 | ||||
| function GameInterface.getRootPanel() | ||||
|   return gameRootPanel | ||||
| end | ||||
| 
 | ||||
| function GameInterface.getMapPanel() | ||||
|   return gameMapPanel | ||||
| end | ||||
| 
 | ||||
| function GameInterface.getRightPanel() | ||||
|   return gameRightPanel | ||||
| end | ||||
| 
 | ||||
| function GameInterface.getLeftPanel() | ||||
|   return gameLeftPanel | ||||
| end | ||||
| 
 | ||||
| function GameInterface.getBottomPanel() | ||||
|   return gameBottomPanel | ||||
| end | ||||
|  | @ -0,0 +1,53 @@ | |||
| GameSidePanel < Panel | ||||
|   image-source: images/sidepanel.png | ||||
|   image-border: 4 | ||||
| 
 | ||||
| GameBottomPanel < Panel | ||||
|   image-source: images/bottompanel.png | ||||
|   image-border: 4 | ||||
| 
 | ||||
| GameMapPanel < UIGameMap | ||||
|   padding: 4 | ||||
|   image-source: images/mappanel.png | ||||
|   image-border: 4 | ||||
| 
 | ||||
| UIWidget | ||||
|   id: gameRootPanel | ||||
|   anchors.fill: parent | ||||
|   anchors.top: topMenu.bottom | ||||
| 
 | ||||
|   GameSidePanel | ||||
|     id: gameRightPanel | ||||
|     width: 190 | ||||
|     layout: verticalBox | ||||
|     anchors.right: parent.right | ||||
|     anchors.top: parent.top | ||||
|     anchors.bottom: parent.bottom | ||||
| 
 | ||||
|   GameSidePanel | ||||
|     id: gameLeftPanel | ||||
|     width: 190 | ||||
|     layout: verticalBox | ||||
|     anchors.left: parent.left | ||||
|     anchors.top: parent.top | ||||
|     anchors.bottom: parent.bottom | ||||
| 
 | ||||
|   GameBottomPanel | ||||
|     id: gameBottomPanel | ||||
|     height: 170 | ||||
|     anchors.left: gameLeftPanel.right | ||||
|     anchors.right: gameRightPanel.left | ||||
|     anchors.bottom: parent.bottom | ||||
| 
 | ||||
|   GameMapPanel | ||||
|     id: gameMapPanel | ||||
|     anchors.left: gameLeftPanel.right | ||||
|     anchors.right: gameRightPanel.left | ||||
|     anchors.top: parent.top | ||||
|     anchors.bottom: gameBottomPanel.top | ||||
|     focusable: false | ||||
| 
 | ||||
|   UIWidget | ||||
|     id: mouseGrabber | ||||
|     focusable: false | ||||
|     visible: false | ||||
| Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B | 
| Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 381 B | 
| Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B | 
| Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 352 B | 
| Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 522 B | 
| Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 516 B | 
| Before Width: | Height: | Size: 404 B After Width: | Height: | Size: 404 B | 
| Before Width: | Height: | Size: 377 B After Width: | Height: | Size: 377 B | 
| Before Width: | Height: | Size: 512 B After Width: | Height: | Size: 512 B | 
| Before Width: | Height: | Size: 494 B After Width: | Height: | Size: 494 B | 
| Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 407 B | 
| Before Width: | Height: | Size: 482 B After Width: | Height: | Size: 482 B | 
| Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 438 B | 
| Before Width: | Height: | Size: 445 B After Width: | Height: | Size: 445 B | 
| Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 421 B | 
| Before Width: | Height: | Size: 437 B After Width: | Height: | Size: 437 B | 
| Before Width: | Height: | Size: 437 B After Width: | Height: | Size: 437 B | 
| Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB | 
| Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B | 
| Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB | 
| Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB | 
| Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB | 
|  | @ -0,0 +1,41 @@ | |||
| CountWindow < MainWindow | ||||
|   id: countWindow | ||||
|   text: Move Staackable Item | ||||
|   size: 196 112 | ||||
|   @onEscape: self:destroy() | ||||
| 
 | ||||
|   Label | ||||
|     text: Amount: | ||||
|     width: 64 | ||||
|     anchors.left: parent.left | ||||
|     anchors.top: parent.top | ||||
|     margin-top: 2 | ||||
| 
 | ||||
|   SpinBox | ||||
|     id: spinbox | ||||
|     anchors.left: prev.right | ||||
|     anchors.right: parent.right | ||||
|     anchors.top: parent.top | ||||
| 
 | ||||
|   HorizontalSeparator | ||||
|     id: separator | ||||
|     anchors.left: parent.left | ||||
|     anchors.right: parent.right | ||||
|     anchors.bottom: next.top | ||||
|     margin-bottom: 10 | ||||
| 
 | ||||
|   Button | ||||
|     id: buttonOk | ||||
|     text: Ok | ||||
|     width: 64 | ||||
|     anchors.right: next.left | ||||
|     anchors.bottom: parent.bottom | ||||
|     margin-right: 10 | ||||
| 
 | ||||
|   Button | ||||
|     id: buttonCancel | ||||
|     text: Cancel | ||||
|     width: 64 | ||||
|     anchors.right: parent.right | ||||
|     anchors.bottom: parent.bottom | ||||
|     @onClick: self:getParent():destroy() | ||||
|  | @ -0,0 +1,20 @@ | |||
| MiniWindow < UIMiniWindow | ||||
|   font: verdana-11px-antialised | ||||
|   //icon: /core_styles/icons/login.png | ||||
|   icon-rect: 4 4 16 16 | ||||
|   width: 192 | ||||
|   height: 200 | ||||
|   text-offset: 26 5 | ||||
|   text-align: topLeft | ||||
|   margin-top: 2 | ||||
|   margin-left: 6 | ||||
|   margin-right: 6 | ||||
|   move-policy: free updated | ||||
|   image-source: /core_styles/styles/images/mini_window.png | ||||
|   image-border: 4 | ||||
|   image-border-top: 23 | ||||
|   padding: 25 8 2 8 | ||||
| 
 | ||||
|   $on: | ||||
|     height: 24 | ||||
|     image-border-bottom: 1 | ||||
|  | @ -0,0 +1,2 @@ | |||
| UICountWindow = {} | ||||
| 
 | ||||
|  | @ -0,0 +1,64 @@ | |||
| UIGameMap = extends(UIMap) | ||||
| 
 | ||||
| function UIGameMap.create() | ||||
|   local gameMap = UIGameMap.internalCreate() | ||||
|   return gameMap | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| function UIGameMap:onDragEnter(mousePos) | ||||
|   local tile = self:getTile(mousePos) | ||||
|   if not tile then return false end | ||||
| 
 | ||||
|   local thing = tile:getTopMoveThing() | ||||
|   if not thing then return false end | ||||
| 
 | ||||
|   self.parsed = false | ||||
|   self.currentDragThing = thing | ||||
|   Mouse.setTargetCursor() | ||||
|   return true | ||||
| end | ||||
| 
 | ||||
| function UIGameMap:onDragLeave(droppedWidget, mousePos) | ||||
|   if not self.parsed then | ||||
|     self.currentDragThing = nil | ||||
|   end | ||||
| 
 | ||||
|   Mouse.restoreCursor() | ||||
|   return true | ||||
| end | ||||
| 
 | ||||
| function UIGameMap:onDrop(widget, mousePos) | ||||
|   if not widget or not widget.currentDragThing then return false end | ||||
| 
 | ||||
|   local tile = self:getTile(mousePos) | ||||
|   if not tile then return false end | ||||
| 
 | ||||
|   local count = widget.currentDragThing:getCount() | ||||
|   if widget.currentDragThing:isStackable() and count > 1 then | ||||
|     widget.parsed = true | ||||
|     local moveWindow = createWidget('CountWindow', rootWidget) | ||||
|     local spinbox = moveWindow:getChildById('spinbox') | ||||
|     spinbox:setMaximum(count) | ||||
|     spinbox:setMinimum(1) | ||||
|     spinbox:setCurrentIndex(count) | ||||
| 
 | ||||
|     local okButton = moveWindow:getChildById('buttonOk') | ||||
|     okButton.onClick = function() | ||||
|       g_game.move(widget.currentDragThing, tile:getPosition(), spinbox:getCurrentIndex()) | ||||
|       okButton:getParent():destroy() | ||||
|       widget.currentDragThing = nil | ||||
|     end | ||||
|     moveWindow.onEnter = okButton.onClick | ||||
|   else | ||||
|     g_game.move(widget.currentDragThing, tile:getPosition(), 1) | ||||
|   end | ||||
| 
 | ||||
|   return true | ||||
| end | ||||
| 
 | ||||
| function UIGameMap:onMouseRelease(mousePosition, mouseButton) | ||||
|   local tile = self:getTile(mousePosition) | ||||
|   if tile and GameInterface.processMouseAction(mousePosition, mouseButton, nil, tile:getTopLookThing(), tile:getTopUseThing(), tile:getTopCreature(), tile:getTopMultiUseThing()) then return true end | ||||
|   return false | ||||
| end | ||||
|  | @ -33,14 +33,17 @@ function UIItem:onDrop(widget, mousePos) | |||
|   local count = widget.currentDragThing:getCount() | ||||
|   if widget.currentDragThing:isStackable() and count > 1 then | ||||
|     widget.parsed = true | ||||
|     local moveWindow = displayUI('/game/movewindow.otui') | ||||
|     local countWindow = createWidget('CountWindow', rootWidget) | ||||
|     local spinbox = moveWindow:getChildById('spinbox') | ||||
|     spinbox:setMaximum(count) | ||||
|     spinbox:setMinimum(1) | ||||
|     spinbox:setCurrentIndex(count) | ||||
| 
 | ||||
|     local okButton = moveWindow:getChildById('buttonOk') | ||||
|     okButton.onClick = function() g_game.move(widget.currentDragThing, pos, spinbox:getCurrentIndex()) okButton:getParent():destroy() widget.currentDragThing = nil end | ||||
|     okButton.onClick = function() | ||||
|       g_game.move(widget.currentDragThing, pos, spinbox:getCurrentIndex()) okButton:getParent():destroy() | ||||
|       widget.currentDragThing = nil | ||||
|     end | ||||
|     moveWindow.onEnter = okButton.onClick | ||||
|   else | ||||
|     g_game.move(widget.currentDragThing, pos, 1) | ||||
|  | @ -53,4 +53,4 @@ MainWindow | |||
|     width: 64 | ||||
|     anchors.right: parent.right | ||||
|     anchors.bottom: parent.bottom | ||||
|     @onClick: self:getParent():destroy() | ||||
|     @onClick: self:getParent():destroy() | ||||
|  | @ -76,9 +76,83 @@ function applyMessagePrefixies(name, level, message) | |||
|   return message | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| -- hooked events | ||||
| local function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos) | ||||
|   speaktype = SpeakTypes[speaktype] | ||||
|   if speaktype.hideInConsole then return end | ||||
| 
 | ||||
|   message = applyMessagePrefixies(name, level, message) | ||||
| 
 | ||||
|   if speaktype.private then | ||||
|     Console.addPrivateText(message, speaktype, name, false) | ||||
|   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 | ||||
|       g_game.leaveChannel(channelId) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| local function onOpenChannel(channelId, channelName) | ||||
|   Console.addChannel(channelName, channelId) | ||||
| end | ||||
| 
 | ||||
| local function onOpenPrivateChannel(receiver) | ||||
|   local privateTab = Console.getTab(receiver) | ||||
|   if privateTab == nil then | ||||
|     Console.addTab(receiver, true) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| local function doChannelListSubmit(channelsWindow) | ||||
|   local channelListPanel = channelsWindow:getChildById('channelList') | ||||
|   local openPrivateChannelWith = channelsWindow:getChildById('openPrivateChannelWith'):getText() | ||||
|   if openPrivateChannelWith ~= '' then | ||||
|     g_game.openPrivateChannel(openPrivateChannelWith) | ||||
|   else | ||||
|     local selectedChannelLabel = channelListPanel:getFocusedChild() | ||||
|     if not selectedChannelLabel then return end | ||||
|     g_game.joinChannel(selectedChannelLabel.channelId) | ||||
|   end | ||||
|   channelsWindow:destroy() | ||||
| end | ||||
| 
 | ||||
| local function onChannelList(channelList) | ||||
|   local channelsWindow = displayUI('channelswindow.otui') | ||||
|   local channelListPanel = channelsWindow:getChildById('channelList') | ||||
|   channelsWindow.onEnter = function() doChannelListSubmit(channelsWindow) end | ||||
|   Keyboard.bindKeyPress('Down', function() channelListPanel:focusNextChild(KeyboardFocusReason) end, channelsWindow) | ||||
|   Keyboard.bindKeyPress('Up', function() channelListPanel:focusPreviousChild(KeyboardFocusReason) end, channelsWindow) | ||||
| 
 | ||||
|   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) | ||||
| 
 | ||||
|       label:setPhantom(false) | ||||
|       label.onDoubleClick = function() doChannelListSubmit(channelsWindow) end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| -- public functions | ||||
| function Console.create() | ||||
|   consolePanel = displayUI('console.otui', g_game.gameBottomPanel) | ||||
| function Console.init() | ||||
|   connect(g_game, { onCreatureSpeak = onCreatureSpeak, | ||||
|                     onChannelList = onChannelList, | ||||
|                     onOpenChannel = onOpenChannel, | ||||
|                     onOpenPrivateChannel = onOpenPrivateChannel}) | ||||
| 
 | ||||
|   consolePanel = displayUI('console.otui', GameInterface.getBottomPanel()) | ||||
|   consoleLineEdit = consolePanel:getChildById('consoleLineEdit') | ||||
|   consoleBuffer = consolePanel:getChildById('consoleBuffer') | ||||
|   consoleTabBar = consolePanel:getChildById('consoleTabBar') | ||||
|  | @ -88,25 +162,42 @@ function Console.create() | |||
|   Console.addChannel('Default', 0) | ||||
|   Console.addTab('Server Log', false) | ||||
| 
 | ||||
|   Keyboard.bindKeyDown('Shift+Up', function() navigateMessageHistory(1) end, consolePanel) | ||||
|   Keyboard.bindKeyDown('Shift+Down', function() navigateMessageHistory(-1) end, consolePanel) | ||||
|   Keyboard.bindKeyDown('Tab', function() consoleTabBar:selectNextTab() end, consolePanel) | ||||
|   Keyboard.bindKeyDown('Shift+Tab', function() consoleTabBar:selectPrevTab() end, consolePanel) | ||||
|   Keyboard.bindKeyPress('Shift+Up', function() navigateMessageHistory(1) end, consolePanel) | ||||
|   Keyboard.bindKeyPress('Shift+Down', function() navigateMessageHistory(-1) end, consolePanel) | ||||
|   Keyboard.bindKeyPress('Tab', function() consoleTabBar:selectNextTab() end, consolePanel) | ||||
|   Keyboard.bindKeyPress('Shift+Tab', function() consoleTabBar:selectPrevTab() end, consolePanel) | ||||
|   Keyboard.bindKeyDown('Enter', Console.sendCurrentMessage, consolePanel) | ||||
| 
 | ||||
|   -- 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 }) | ||||
|   consolePanel:getChildById('nextChannelButton').onClick = function() consoleTabBar:selectNextTab() end | ||||
|   consolePanel:getChildById('prevChannelButton').onClick = function() consoleTabBar:selectPrevTab() end | ||||
|   consoleTabBar.onTabChange = Console.onTabChange | ||||
| 
 | ||||
|   -- tibia like hotkeys | ||||
|   Keyboard.bindKeyDown('Ctrl+O', g_game.requestChannels) | ||||
|   Keyboard.bindKeyDown('Ctrl+E', Console.removeCurrentTab) | ||||
| end | ||||
| 
 | ||||
| function Console.destroy() | ||||
| function Console.terminate() | ||||
|   disconnect(g_game, { onCreatureSpeak = onCreatureSpeak, | ||||
|                        onChannelList = onChannelList, | ||||
|                        onOpenChannel = onOpenChannel, | ||||
|                        onOpenPrivateChannel = onOpenPrivateChannel }) | ||||
| 
 | ||||
|   for channelid, channelname in ipairs(channels) do | ||||
|     g_game.leaveChannel(channelid) | ||||
|   end | ||||
| 
 | ||||
|   Keyboard.unbindKeyDown('Ctrl+O') | ||||
|   Keyboard.unbindKeyDown('Ctrl+E') | ||||
| 
 | ||||
|   consolePanel:destroy() | ||||
|   consolePanel = nil | ||||
|   consoleLineEdit = nil | ||||
|   consoleBuffer = nil | ||||
|   consoleTabBar = nil | ||||
| 
 | ||||
|   Console = nil | ||||
| end | ||||
| 
 | ||||
| function Console.setLineEditText(text) | ||||
|  | @ -117,7 +208,7 @@ function Console.addTab(name, focus) | |||
|   local tab = consoleTabBar:addTab(name) | ||||
|   if focus then | ||||
|     consoleTabBar:selectTab(tab) | ||||
|   else | ||||
|   elseif name ~= 'Server Log' then | ||||
|     consoleTabBar:blinkTab(tab) | ||||
|   end | ||||
|   return tab | ||||
|  | @ -299,75 +390,3 @@ function Console.sayModeChange(sayMode) | |||
|   buttom:setIcon(SayModes[sayMode].icon) | ||||
|   buttom.sayMode = sayMode | ||||
| end | ||||
| 
 | ||||
| -- hooked events | ||||
| local function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos) | ||||
|   speaktype = SpeakTypes[speaktype] | ||||
|   if speaktype.hideInConsole then return end | ||||
| 
 | ||||
|   message = applyMessagePrefixies(name, level, message) | ||||
| 
 | ||||
|   if speaktype.private then | ||||
|     Console.addPrivateText(message, speaktype, name, false) | ||||
|   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 | ||||
|       g_game.leaveChannel(channelId) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| local function onOpenChannel(channelId, channelName) | ||||
|   Console.addChannel(channelName, channelId) | ||||
| end | ||||
| 
 | ||||
| local function onOpenPrivateChannel(receiver) | ||||
|   local privateTab = Console.getTab(receiver) | ||||
|   if privateTab == nil then | ||||
|     Console.addTab(receiver, true) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| local function doChannelListSubmit(channelsWindow) | ||||
|   local channelListPanel = channelsWindow:getChildById('channelList') | ||||
|   local openPrivateChannelWith = channelsWindow:getChildById('openPrivateChannelWith'):getText() | ||||
|   if openPrivateChannelWith ~= '' then | ||||
|     g_game.openPrivateChannel(openPrivateChannelWith) | ||||
|   else | ||||
|     local selectedChannelLabel = channelListPanel:getFocusedChild() | ||||
|     if not selectedChannelLabel then return end | ||||
|     g_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 } ) | ||||
| 
 | ||||
|   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) | ||||
| 
 | ||||
|       label:setPhantom(false) | ||||
|       connect(label, { onDoubleClick = function () doChannelListSubmit(channelsWindow) end } ) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| connect(g_game, { onGameStart = Console.create, | ||||
|                 onGameEnd = Console.destroy, | ||||
|                 onCreatureSpeak = onCreatureSpeak, | ||||
|                 onChannelList = onChannelList, | ||||
|                 onOpenChannel = onOpenChannel, | ||||
|                 onOpenPrivateChannel = onOpenPrivateChannel}) | ||||
|  | @ -3,5 +3,14 @@ Module | |||
|   description: Manage chat window | ||||
|   author: OTClient team | ||||
|   website: https://github.com/edubart/otclient | ||||
|   onLoad: | | ||||
|   reloadable: true | ||||
| 
 | ||||
|   dependecies: | ||||
|     - game | ||||
| 
 | ||||
|   @onLoad: | | ||||
|     dofile 'console' | ||||
|     Console.init() | ||||
| 
 | ||||
|   @onUnload: | | ||||
|     Console.terminate() | ||||
|  | @ -14,7 +14,7 @@ Panel | |||
|   id: consolePanel | ||||
|   anchors.fill: parent | ||||
| 
 | ||||
|   ConsoleButton | ||||
|   TabButton | ||||
|     id: prevChannelButton | ||||
|     icon: /core_styles/icons/leftarrow.png | ||||
|     anchors.left: parent.left | ||||
|  | @ -30,7 +30,7 @@ Panel | |||
|     anchors.right: next.left | ||||
|     margin-left: 5 | ||||
| 
 | ||||
|   ConsoleButton | ||||
|   TabButton | ||||
|     id: nextChannelButton | ||||
|     icon: /core_styles/icons/rightarrow.png | ||||
|     anchors.right: next.left | ||||
|  | @ -38,7 +38,7 @@ Panel | |||
|     margin-right: 5 | ||||
|     margin-top: 6 | ||||
| 
 | ||||
|   ConsoleButton | ||||
|   TabButton | ||||
|     id: closeChannelButton | ||||
|     tooltip: Close this channel (Ctrl+E) | ||||
|     icon: /core_styles/icons/closechannel.png | ||||
|  | @ -49,7 +49,7 @@ Panel | |||
|     margin-top: 6 | ||||
|     @onClick: Console.removeCurrentTab() | ||||
| 
 | ||||
|   ConsoleButton | ||||
|   TabButton | ||||
|     id: channelsButton | ||||
|     tooltip: Open new channel (Ctrl+O) | ||||
|     icon: /core_styles/icons/channels.png | ||||
|  | @ -71,7 +71,7 @@ Panel | |||
|     margin-top: 4 | ||||
|     focusable: false | ||||
| 
 | ||||
|   ConsoleButton | ||||
|   TabButton | ||||
|     id: sayModeButton | ||||
|     icon: /core_styles/icons/say.png | ||||
|     tooltip: Adjust volume | ||||
|  | @ -91,5 +91,4 @@ Panel | |||
|     margin-right: 6 | ||||
|     margin-left: 6 | ||||
|     margin-bottom: 6 | ||||
|     always-active: true | ||||
|     focusable: false | ||||
|     shift-navigation: true | ||||
|  | @ -17,7 +17,7 @@ local MessageTypes = { | |||
| } | ||||
| 
 | ||||
| local centerTextMessagePanel | ||||
| local centerLabel | ||||
| local bottomStatusLabel | ||||
| 
 | ||||
| -- private functions | ||||
| local function displayMessage(msgtype, msg, time) | ||||
|  | @ -30,17 +30,17 @@ local function displayMessage(msgtype, msg, time) | |||
|   end | ||||
| 
 | ||||
|   if msgtype.labelId  then | ||||
|     local label = g_game.gameMapPanel:recursiveGetChildById(msgtype.labelId) | ||||
|     local label = GameInterface.getMapPanel():recursiveGetChildById(msgtype.labelId) | ||||
| 
 | ||||
|     label:setVisible(true) | ||||
|     label:setText(msg) | ||||
|     label:setColor(msgtype.color) | ||||
|     label:resizeToText() | ||||
| 
 | ||||
|     if msgtype.wrap then | ||||
|       label:setWidth(label:getParent():getWidth()) | ||||
|       label:wrapText() | ||||
|       label:setHeight(label:getTextSize().height) | ||||
|     else | ||||
|       label:resizeToText() | ||||
|     end | ||||
| 
 | ||||
|     if not time then | ||||
|  | @ -49,6 +49,7 @@ local function displayMessage(msgtype, msg, time) | |||
|       time = time * 1000 | ||||
|     end | ||||
|     removeEvent(label.hideEvent) | ||||
|     addEvent(function() label:setVisible(true) end) | ||||
|     label.hideEvent = scheduleEvent(function() label:setVisible(false) end, time) | ||||
|   end | ||||
| end | ||||
|  | @ -64,10 +65,14 @@ local function createTextMessageLabel(id, parent) | |||
| end | ||||
| 
 | ||||
| -- public functions | ||||
| function TextMessage.init() | ||||
|   connect(g_game, { onDeath = TextMessage.displayDeadMessage, | ||||
|                     onTextMessage = TextMessage.display, | ||||
|                     onGameStart = TextMessage.clearMessages }) | ||||
| 
 | ||||
| function TextMessage.create() | ||||
|   centerTextMessagePanel = createWidget('Panel', g_game.gameMapPanel) | ||||
|   centerTextMessagePanel = createWidget('Panel', GameInterface.getMapPanel()) | ||||
|   centerTextMessagePanel:setId('centerTextMessagePanel') | ||||
| 
 | ||||
|   local layout = UIVerticalLayout.create(centerTextMessagePanel) | ||||
|   layout:setFitChildren(true) | ||||
|   centerTextMessagePanel:setLayout(layout) | ||||
|  | @ -78,13 +83,31 @@ function TextMessage.create() | |||
|   createTextMessageLabel('centerAdvance', centerTextMessagePanel) | ||||
|   createTextMessageLabel('centerInfo', centerTextMessagePanel) | ||||
| 
 | ||||
|   bottomStatusLabel = createTextMessageLabel('bottomStatus', g_game.gameMapPanel) | ||||
|   bottomStatusLabel = createTextMessageLabel('bottomStatus', GameInterface.getMapPanel()) | ||||
|   bottomStatusLabel:setHeight(16) | ||||
|   bottomStatusLabel:addAnchor(AnchorBottom, 'parent', AnchorBottom) | ||||
|   bottomStatusLabel:addAnchor(AnchorLeft, 'parent', AnchorLeft) | ||||
|   bottomStatusLabel:addAnchor(AnchorRight, 'parent', AnchorRight) | ||||
| end | ||||
| 
 | ||||
| function TextMessage.terminate() | ||||
|   disconnect(g_game, { onDeath = TextMessage.displayDeadMessage, | ||||
|                        onTextMessage = TextMessage.display, | ||||
|                        onGameStart = TextMessage.clearMessages }) | ||||
|   centerTextMessagePanel:destroy() | ||||
|   centerTextMessagePanel = nil | ||||
|   bottomStatusLabel:destroy() | ||||
|   bottomStatusLabel = nil | ||||
|   TextMessage = nil | ||||
| end | ||||
| 
 | ||||
| function TextMessage.clearMessages() | ||||
|   GameInterface.getMapPanel():recursiveGetChildById('centerWarning'):hide() | ||||
|   GameInterface.getMapPanel():recursiveGetChildById('centerAdvance'):hide() | ||||
|   GameInterface.getMapPanel():recursiveGetChildById('centerInfo'):hide() | ||||
|   GameInterface.getMapPanel():recursiveGetChildById('bottomStatus'):hide() | ||||
| end | ||||
| 
 | ||||
| function TextMessage.displayStatus(msg, time) | ||||
|   displayMessage(MessageTypes.warning, msg) | ||||
| end | ||||
|  | @ -100,18 +123,8 @@ function TextMessage.display(msgtypedesc, msg) | |||
|   end | ||||
| end | ||||
| 
 | ||||
| -- hooked events | ||||
| local function onGameDeath() | ||||
|   local advanceLabel = g_game.gameMapPanel:recursiveGetChildById('centerAdvance') | ||||
| function TextMessage.displayDeadMessage() | ||||
|   local advanceLabel = GameInterface.getMapPanel():recursiveGetChildById('centerAdvance') | ||||
|   if advanceLabel:isVisible() then return end | ||||
|   TextMessage.displayEventAdvance('You are dead.') | ||||
| end | ||||
| 
 | ||||
| local function onGameTextMessage(msgtypedesc, msg) | ||||
|   TextMessage.display(msgtypedesc, msg) | ||||
| end | ||||
| 
 | ||||
| connect(g_game, { onGameStart = TextMessage.create, | ||||
|                 onGameEnd = TextMessage.destroy, | ||||
|                 onDeath = onGameDeath, | ||||
|                 onTextMessage = onGameTextMessage }) | ||||
|  | @ -3,5 +3,14 @@ Module | |||
|   description: Manage game text messages | ||||
|   author: OTClient team | ||||
|   website: https://github.com/edubart/otclient | ||||
|   onLoad: | | ||||
|   reloadable: true | ||||
| 
 | ||||
|   dependecies: | ||||
|     - game | ||||
| 
 | ||||
|   @onLoad: | | ||||
|     dofile 'textmessage' | ||||
|     TextMessage.init() | ||||
| 
 | ||||
|   @onUnload: | | ||||
|     TextMessage.terminate() | ||||
|  | @ -0,0 +1,17 @@ | |||
| Module | ||||
|   name: game | ||||
|   description: Create the game interface, where the ingame stuff starts | ||||
|   author: OTClient team | ||||
|   website: https://github.com/edubart/otclient | ||||
|   reloadable: true | ||||
| 
 | ||||
|   dependencies: | ||||
|     - game_tibiafiles | ||||
|     //- game_shaders | ||||
| 
 | ||||
|   onLoad: | | ||||
|     dofile 'game' | ||||
|     dofile 'thing' | ||||
|     dofile 'creature' | ||||
|     dofile 'player' | ||||
|     dofile 'map' | ||||
|  | @ -1,4 +1,4 @@ | |||
| MainWindow | ||||
| CountWindow < MainWindow | ||||
|   text: Move Item | ||||
|   size: 196 112 | ||||
|   @onEscape: self:destroy() | ||||
|  | @ -455,4 +455,4 @@ function HotkeysManager.hotkeyCapture(widget, keyCode, keyboardModifiers) | |||
|   hotkeysWindow:getChildById('assignWindow'):getChildById('addButton'):enable() | ||||
| 
 | ||||
|   return true | ||||
| end | ||||
| end | ||||
|  |  | |||
|  | @ -156,4 +156,4 @@ MainWindow | |||
|     width: 64 | ||||
|     anchors.right: parent.right | ||||
|     anchors.bottom: parent.bottom | ||||
|     @onClick: HotkeysManager.hide() | ||||
|     @onClick: HotkeysManager.hide() | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| GameSidePanel < UIMiniWindowContainer | ||||
|   image-source: /core_styles/styles/images/sidepanel.png | ||||
|   image-source: images/sidepanel.png | ||||
|   image-border: 4 | ||||
| 
 | ||||
| GameBottomPanel < Panel | ||||
|   image-source: /core_styles/styles/images/bottompanel.png | ||||
|   image-source: images/bottompanel.png | ||||
|   image-border: 4 | ||||
| 
 | ||||
| GameMapPanel < UIMap | ||||
|   padding: 4 | ||||
|   image-source: /core_styles/styles/images/mappanel.png | ||||
|   image-source: images/mappanel.png | ||||
|   image-border: 4 | ||||
| 
 | ||||
| UIGame | ||||
|  | @ -16,7 +16,7 @@ UIGame | |||
|   anchors.fill: parent | ||||
|   anchors.top: topMenu.bottom | ||||
| 
 | ||||
|   InterfacePanel | ||||
|   GameSidePanel | ||||
|     id: gameRightPanel | ||||
|     width: 190 | ||||
|     layout: verticalBox | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| -- this file use loaded after everything is loaded and initialized | ||||
| -- this file is loaded after all modules are loaded and initialized | ||||
| -- you can place any custom user code here | ||||
| -- you | ||||
| 
 | ||||
| Keyboard.bindKeyDown('F1', function() g_game.talk('exura gran') end) | ||||
| Keyboard.bindKeyDown('F2', function() g_game.talk('exori mort') end) | ||||
|  | @ -7,12 +8,4 @@ Keyboard.bindKeyDown('F3', function() g_game.talk('exori frigo') end) | |||
| Keyboard.bindKeyDown('F4', function() g_game.talk('exevo vis hur') end) | ||||
| Keyboard.bindKeyDown('F5', function() g_game.talk('utani gran hur') end) | ||||
| Keyboard.bindKeyDown('F6', function() g_game.talk('exani tera') end) | ||||
| 
 | ||||
| local function reload() | ||||
|   dofile('otclientrc.lua') | ||||
|   TextMessage.displayEventAdvance('Script otclientrc.lua reloaded.') | ||||
|   print('Script otclient.rc lua reloaded') | ||||
| end | ||||
| Keyboard.bindKeyDown('Ctrl+R', reload) | ||||
| 
 | ||||
| rcloaded = true | ||||
| Keyboard.bindKeyDown('Ctrl+R', Client.reloadScripts) | ||||
|  |  | |||
|  | @ -50,15 +50,6 @@ IF(CMAKE_COMPILER_IS_GNUCXX) | |||
|     SET(CMAKE_CXX_LINK_FLAGS           "${CMAKE_CXX_LINK_FLAGS} -static-libgcc -static-libstdc++ -Wl,--as-needed") | ||||
| ENDIF(CMAKE_COMPILER_IS_GNUCXX) | ||||
| 
 | ||||
| IF(CMAKE_BUILD_TYPE STREQUAL "Debug") | ||||
|     ADD_DEFINITIONS(-DDEBUG) | ||||
| ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug") | ||||
| 
 | ||||
| IF(CMAKE_BUILD_TYPE STREQUAL "Release") | ||||
|     # NDEBUG disable asserts | ||||
|     ADD_DEFINITIONS(-DNDEBUG) | ||||
| ENDIF(CMAKE_BUILD_TYPE STREQUAL "Release") | ||||
| 
 | ||||
| MESSAGE(STATUS "Build type: " ${CMAKE_BUILD_TYPE}) | ||||
| IF(USE_OPENGL_ES2) | ||||
|     MESSAGE(STATUS "Renderer: OpenGL ES 2.0") | ||||
|  | @ -66,6 +57,18 @@ ELSE(USE_OPENGL_ES2) | |||
|     MESSAGE(STATUS "Renderer: OpenGL") | ||||
| ENDIF(USE_OPENGL_ES2) | ||||
| 
 | ||||
| IF(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") | ||||
|     ADD_DEFINITIONS(-DDEBUG) | ||||
|     MESSAGE(STATUS "Debug information: ON") | ||||
| ELSE() | ||||
|     MESSAGE(STATUS "Debug information: OFF") | ||||
| ENDIF() | ||||
| 
 | ||||
| IF(CMAKE_BUILD_TYPE STREQUAL "Release") | ||||
|     # NDEBUG disable asserts | ||||
|     ADD_DEFINITIONS(-DNDEBUG) | ||||
| ENDIF(CMAKE_BUILD_TYPE STREQUAL "Release") | ||||
| 
 | ||||
| IF(CRASH_HANDLER) | ||||
|     ADD_DEFINITIONS(-DCRASH_HANDLER) | ||||
|     MESSAGE(STATUS "Crash handler: ON") | ||||
|  |  | |||
|  | @ -219,10 +219,7 @@ void Application::poll() | |||
| 
 | ||||
| void Application::close() | ||||
| { | ||||
|     g_lua.getGlobalField("g_app", "onClose"); | ||||
|     if(!g_lua.isNil()) | ||||
|         g_lua.protectedCall(); | ||||
|     else | ||||
|     if(!g_lua.callGlobalField<bool>("g_app", "onClose")) | ||||
|         exit(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -362,6 +362,7 @@ void Application::registerLuaFunctions() | |||
|     g_lua.bindClassMemberFunction<UILineEdit>("setTextHidden", &UILineEdit::setTextHidden); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("setAlwaysActive", &UILineEdit::setAlwaysActive); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("setValidCharacters", &UILineEdit::setValidCharacters); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("setShiftNavigation", &UILineEdit::setShiftNavigation); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("moveCursor", &UILineEdit::moveCursor); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("appendText", &UILineEdit::appendText); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("removeCharacter", &UILineEdit::removeCharacter); | ||||
|  | @ -372,6 +373,7 @@ void Application::registerLuaFunctions() | |||
|     g_lua.bindClassMemberFunction<UILineEdit>("isCursorEnabled", &UILineEdit::isCursorEnabled); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("isAlwaysActive", &UILineEdit::isAlwaysActive); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("isTextHidden", &UILineEdit::isTextHidden); | ||||
|     g_lua.bindClassMemberFunction<UILineEdit>("isShiftNavigation", &UILineEdit::isShiftNavigation); | ||||
| 
 | ||||
|     // UIFrameCounter
 | ||||
|     g_lua.registerClass<UIFrameCounter, UIWidget>(); | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ UILineEdit::UILineEdit() | |||
|     m_textHorizontalMargin = 0; | ||||
|     m_textHidden = false; | ||||
|     m_alwaysActive = false; | ||||
|     m_shiftNavigation = false; | ||||
|     blinkCursor(); | ||||
| } | ||||
| 
 | ||||
|  | @ -407,8 +408,8 @@ void UILineEdit::onStyleApply(const std::string& styleName, const OTMLNodePtr& s | |||
|             setTextHorizontalMargin(node->value<int>()); | ||||
|         else if(node->tag() == "always-active") | ||||
|             setAlwaysActive(node->value<bool>()); | ||||
|         //else if(node->tag() == "disable-arrow-navitation")
 | ||||
|         //    setArrowNavigation(node->value<bool>());
 | ||||
|         else if(node->tag() == "shift-navigation") | ||||
|             setShiftNavigation(node->value<bool>()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -434,28 +435,46 @@ bool UILineEdit::onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeat | |||
|     if(UIWidget::onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks)) | ||||
|         return true; | ||||
| 
 | ||||
|     if(keyCode == Fw::KeyDelete) // erase right character
 | ||||
|         removeCharacter(true); | ||||
|     else if(keyCode == Fw::KeyBackspace) // erase left character { | ||||
|         removeCharacter(false); | ||||
|     else if(keyCode == Fw::KeyRight) // move cursor right
 | ||||
|         moveCursor(true); | ||||
|     else if(keyCode == Fw::KeyLeft) // move cursor left
 | ||||
|         moveCursor(false); | ||||
|     else if(keyCode == Fw::KeyHome) // move cursor to first character
 | ||||
|         setCursorPos(0); | ||||
|     else if(keyCode == Fw::KeyEnd) // move cursor to last character
 | ||||
|         setCursorPos(m_text.length()); | ||||
|     else if(keyCode == Fw::KeyV && keyboardModifiers == Fw::KeyboardCtrlModifier) | ||||
|         appendText(g_window.getClipboardText()); | ||||
|     else if(keyCode == Fw::KeyTab) { | ||||
|         if(!m_alwaysActive) { | ||||
|     if(keyboardModifiers == Fw::KeyboardNoModifier) { | ||||
|         if(keyCode == Fw::KeyDelete) { // erase right character
 | ||||
|             removeCharacter(true); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyBackspace) { // erase left character {
 | ||||
|             removeCharacter(false); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyRight && !m_shiftNavigation) { // move cursor right
 | ||||
|             moveCursor(true); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyLeft && !m_shiftNavigation) { // move cursor left
 | ||||
|             moveCursor(false); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyHome) { // move cursor to first character
 | ||||
|             setCursorPos(0); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyEnd) { // move cursor to last character
 | ||||
|             setCursorPos(m_text.length()); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyTab && !m_shiftNavigation) { | ||||
|             if(UIWidgetPtr parent = getParent()) | ||||
|                 parent->focusNextChild(Fw::KeyboardFocusReason); | ||||
|             return true; | ||||
|         } | ||||
|     } else | ||||
|         return false; | ||||
|     return true; | ||||
|     } else if(keyboardModifiers == Fw::KeyboardCtrlModifier) { | ||||
|         if(keyCode == Fw::KeyV) { | ||||
|             appendText(g_window.getClipboardText()); | ||||
|             return true; | ||||
|         } | ||||
|     } else if(keyboardModifiers == Fw::KeyboardShiftModifier) { | ||||
|         if(keyCode == Fw::KeyRight && m_shiftNavigation) { // move cursor right
 | ||||
|             moveCursor(true); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyLeft && m_shiftNavigation) { // move cursor left
 | ||||
|             moveCursor(false); | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool UILineEdit::onKeyText(const std::string& keyText) | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ public: | |||
|     void setTextHidden(bool hidden); | ||||
|     void setAlwaysActive(bool enable); | ||||
|     void setValidCharacters(const std::string validCharacters) { m_validCharacters = validCharacters; } | ||||
|     void setShiftNavigation(bool enable) { m_shiftNavigation = enable; } | ||||
| 
 | ||||
|     void moveCursor(bool right); | ||||
|     void appendText(std::string text); | ||||
|  | @ -55,6 +56,7 @@ public: | |||
|     bool isCursorEnabled() { return m_cursorPos != -1; } | ||||
|     bool isAlwaysActive() { return m_alwaysActive; } | ||||
|     bool isTextHidden() { return m_textHidden; } | ||||
|     bool isShiftNavigation() { return m_shiftNavigation; } | ||||
| 
 | ||||
| protected: | ||||
|     virtual void onTextChange(const std::string& text, const std::string& oldText); | ||||
|  | @ -77,6 +79,7 @@ private: | |||
|     int m_textHorizontalMargin; | ||||
|     bool m_textHidden; | ||||
|     bool m_alwaysActive; | ||||
|     bool m_shiftNavigation; | ||||
|     std::string m_validCharacters; | ||||
| 
 | ||||
|     std::vector<Rect> m_glyphsCoords; | ||||
|  |  | |||
|  | @ -319,7 +319,12 @@ UIWidgetPtr UIManager::loadUI(const std::string& file, const UIWidgetPtr& parent | |||
|         return nullptr; | ||||
|     } | ||||
| } | ||||
| /*
 | ||||
| UIWidgetPtr UIManager::loadWidgetFromStyle() | ||||
| { | ||||
| 
 | ||||
| } | ||||
| */ | ||||
| UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent) | ||||
| { | ||||
|     OTMLNodePtr originalStyleNode = getStyle(widgetNode->tag()); | ||||
|  |  | |||
|  | @ -206,7 +206,7 @@ void UIWidget::removeChild(UIWidgetPtr child) | |||
| 
 | ||||
|         g_ui.onWidgetDisappear(child); | ||||
|     } else | ||||
|         logError("Attempt to remove an unknown child from a UIWidget"); | ||||
|         logError("attempt to remove an unknown child from a UIWidget"); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -637,11 +637,12 @@ void UIWidget::destroy() | |||
| 
 | ||||
|     // remove itself from parent
 | ||||
|     if(UIWidgetPtr parent = getParent()) { | ||||
|         if(parent->hasChild(asUIWidget())) | ||||
|             parent->removeChild(asUIWidget()); | ||||
|         assert(parent->hasChild(asUIWidget())); | ||||
|         parent->removeChild(asUIWidget()); | ||||
|     } | ||||
| 
 | ||||
|     destroyChildren(); | ||||
|     m_focusedChild = nullptr; | ||||
| 
 | ||||
|     callLuaField("onDestroy"); | ||||
| 
 | ||||
|  | @ -649,12 +650,13 @@ void UIWidget::destroy() | |||
| 
 | ||||
| #ifdef DEBUG | ||||
|     auto self = asUIWidget(); | ||||
|     g_lua.collectGarbage(); | ||||
|     if(self != g_ui.getRootWidget()) { | ||||
|         g_eventDispatcher.scheduleEvent([self] { | ||||
|             g_lua.collectGarbage(); | ||||
|             if(self->getUseCount() != 1) | ||||
|                 logWarning("widget '", self->getId(), "' destroyed but still have ", self->getUseCount()-1, " reference(s) left"); | ||||
|         }, 100); | ||||
|         }, 500); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  |  | |||
|  | @ -51,6 +51,9 @@ void UIWidget::drawText(const Rect& screenCoords) | |||
|     if(m_text.length() == 0 || m_color.a() == 0) | ||||
|         return; | ||||
| 
 | ||||
| #if 0 | ||||
|     //TODO: creating framebuffers on the fly was slowing down the render
 | ||||
|     // we should use vertex arrys instead of this method
 | ||||
|     Size boxSize = screenCoords.size(); | ||||
|     if(boxSize != m_textCachedBoxSize || m_textMustRecache) { | ||||
|         if(!m_textFramebuffer) | ||||
|  | @ -73,6 +76,11 @@ void UIWidget::drawText(const Rect& screenCoords) | |||
| 
 | ||||
|     g_painter.setColor(m_color); | ||||
|     m_textFramebuffer->draw(screenCoords); | ||||
| #else | ||||
|     Rect textRect = screenCoords; | ||||
|     textRect.translate(m_textOffset); | ||||
|     m_font->renderText(m_text, textRect, m_textAlign, m_color); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void UIWidget::onTextChange(const std::string& text, const std::string& oldText) | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ SET(otclient_SOURCES ${otclient_SOURCES} | |||
|     ${CMAKE_CURRENT_LIST_DIR}/core/thingstype.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/core/spritemanager.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/core/item.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/core/container.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/core/tile.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/core/thing.cpp | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/core/creature.cpp | ||||
|  |  | |||
|  | @ -0,0 +1,23 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 "container.h" | ||||
|  | @ -20,17 +20,16 @@ | |||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef UIGAME_H | ||||
| #define UIGAME_H | ||||
| #ifndef CONTAINER_H | ||||
| #define CONTAINER_H | ||||
| 
 | ||||
| #include "declarations.h" | ||||
| #include <framework/ui/uiwidget.h> | ||||
| 
 | ||||
| class UIGame : public UIWidget | ||||
| class Container | ||||
| { | ||||
| protected: | ||||
|     bool onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks); | ||||
|     bool onKeyText(const std::string& keyText); | ||||
| public: | ||||
|     Container(); | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  | @ -31,6 +31,7 @@ class MapView; | |||
| class Tile; | ||||
| class Thing; | ||||
| class Item; | ||||
| class Container; | ||||
| class Creature; | ||||
| class Monster; | ||||
| class Npc; | ||||
|  | @ -45,6 +46,7 @@ typedef std::shared_ptr<MapView> MapViewPtr; | |||
| typedef std::shared_ptr<Tile> TilePtr; | ||||
| typedef std::shared_ptr<Thing> ThingPtr; | ||||
| typedef std::shared_ptr<Item> ItemPtr; | ||||
| typedef std::shared_ptr<Container> ContainerPtr; | ||||
| typedef std::shared_ptr<Creature> CreaturePtr; | ||||
| typedef std::shared_ptr<Monster> MonsterPtr; | ||||
| typedef std::shared_ptr<Npc> NpcPtr; | ||||
|  |  | |||
|  | @ -764,7 +764,6 @@ void Game::setSafeFight(bool on) | |||
|     m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void Game::inspectNpcTrade(const ItemPtr& item) | ||||
| { | ||||
|     if(!canPerformGameAction() || !item) | ||||
|  |  | |||
|  | @ -216,6 +216,7 @@ public: | |||
|     bool isAttacking() { return !!m_attackingCreature; } | ||||
|     bool isFollowing() { return !!m_followingCreature; } | ||||
| 
 | ||||
|     ContainerPtr getContainer(int index) { return m_containers[index]; } | ||||
|     CreaturePtr getAttackingCreature() { return m_attackingCreature; } | ||||
|     CreaturePtr getFollowingCreature() { return m_followingCreature; } | ||||
|     int getServerBeat() { return m_serverBeat; } | ||||
|  | @ -231,6 +232,7 @@ private: | |||
|     CreaturePtr m_attackingCreature; | ||||
|     CreaturePtr m_followingCreature; | ||||
|     ProtocolGamePtr m_protocolGame; | ||||
|     std::map<int, ContainerPtr> m_containers; | ||||
|     bool m_dead; | ||||
|     int m_serverBeat; | ||||
|     Otc::FightModes m_fightMode; | ||||
|  |  | |||
|  | @ -36,12 +36,17 @@ | |||
| 
 | ||||
| MapView::MapView() | ||||
| { | ||||
|     m_viewRange = NEAR_VIEW; | ||||
|     m_lockedFirstVisibleFloor = -1; | ||||
|     m_cachedFirstVisibleFloor = 0; | ||||
|     m_cachedLastVisibleFloor = 7; | ||||
|     m_customCameraPosition.z = 7; | ||||
| 
 | ||||
|     Size frameBufferSize(std::min(g_graphics.getMaxTextureSize(), (int)DEFAULT_FRAMBUFFER_WIDTH), | ||||
|                          std::min(g_graphics.getMaxTextureSize(), (int)DEFAULT_FRAMBUFFER_HEIGHT)); | ||||
| 
 | ||||
|     m_framebuffer = FrameBufferPtr(new FrameBuffer(frameBufferSize)); | ||||
|     m_framebuffer->setClearColor(Fw::black); | ||||
|     m_lockedFirstVisibleFloor = -1; | ||||
|     setVisibleDimension(Size(15, 11)); | ||||
| 
 | ||||
|     m_shaderProgram = PainterShaderProgramPtr(new PainterShaderProgram); | ||||
|  | @ -374,7 +379,6 @@ void MapView::unlockFirstVisibleFloor() | |||
| void MapView::followCreature(const CreaturePtr& creature) | ||||
| { | ||||
|     m_followingCreature = creature; | ||||
|     m_customCameraPosition = Position(); | ||||
|     requestVisibleTilesCacheUpdate(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -93,7 +93,6 @@ public: | |||
|     MapViewPtr asMapView() { return std::static_pointer_cast<MapView>(shared_from_this()); } | ||||
| 
 | ||||
| private: | ||||
|     int m_drawFlags; | ||||
|     int m_lockedFirstVisibleFloor; | ||||
|     int m_cachedFirstVisibleFloor; | ||||
|     int m_cachedLastVisibleFloor; | ||||
|  | @ -102,7 +101,6 @@ private: | |||
|     Size m_visibleDimension; | ||||
|     Point m_virtualCenterOffset; | ||||
|     Position m_customCameraPosition; | ||||
|     Position m_framebufferCenterPosition; | ||||
|     Boolean<true> m_mustUpdateVisibleTilesCache; | ||||
|     Boolean<true> m_mustDrawVisibleTilesCache; | ||||
|     Boolean<true> m_mustCleanFramebuffer; | ||||
|  |  | |||
|  | @ -0,0 +1,23 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 "player.h" | ||||
|  | @ -31,6 +31,10 @@ public: | |||
|     Player() { } | ||||
|     virtual ~Player() { } | ||||
| 
 | ||||
|     bool isPartyMember() { return (m_shield != 0); } | ||||
|     bool isPartyLeader() { return (m_shield & Otc::ShieldYellow); }  | ||||
|     bool isPartySharedExperienceActive() { return false; } | ||||
| 
 | ||||
|     PlayerPtr asPlayer() { return std::static_pointer_cast<Player>(shared_from_this()); } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| #include <framework/graphics/graphics.h> | ||||
| #include "map.h" | ||||
| #include "tile.h" | ||||
| #include "game.h" | ||||
| 
 | ||||
| Thing::Thing() | ||||
| { | ||||
|  | @ -53,6 +54,13 @@ const TilePtr& Thing::getTile() | |||
|     return g_map.getTile(m_position); | ||||
| } | ||||
| 
 | ||||
| ContainerPtr Thing::getParentContainer() | ||||
| { | ||||
|     if(m_position.x == 0xFFFF && m_position.y & 0x40) | ||||
|         return g_game.getContainer(m_position.z); | ||||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
| int Thing::getStackpos() | ||||
| { | ||||
|     if(m_position.x == 65535 && asItem()) // is inside a container
 | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ public: | |||
|     Position getPosition() { return m_position; } | ||||
|     int getStackPriority(); | ||||
|     const TilePtr& getTile(); | ||||
|     ContainerPtr getParentContainer(); | ||||
|     int getStackpos(); | ||||
| 
 | ||||
|     ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); } | ||||
|  |  | |||
|  | @ -305,6 +305,7 @@ void OTClient::registerLuaFunctions() | |||
| 
 | ||||
|     g_lua.registerClass<UIMap, UIWidget>(); | ||||
|     g_lua.bindClassStaticFunction<UIMap>("create", []{ return UIMapPtr(new UIMap); } ); | ||||
|     g_lua.bindClassMemberFunction<UIMap>("followCreature", &UIMap::followCreature); | ||||
|     g_lua.bindClassMemberFunction<UIMap>("getTile", &UIMap::getTile); | ||||
|     g_lua.bindClassMemberFunction<UIMap>("zoomIn", &UIMap::zoomIn); | ||||
|     g_lua.bindClassMemberFunction<UIMap>("zoomOut", &UIMap::zoomOut); | ||||
|  |  | |||
|  | @ -1,117 +0,0 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 "uigame.h" | ||||
| #include <otclient/core/game.h> | ||||
| #include <framework/ui/uilineedit.h> | ||||
| #include <framework/platform/platformwindow.h> | ||||
| 
 | ||||
| bool UIGame::onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks) | ||||
| { | ||||
|     if(UIWidget::onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks)) | ||||
|         return true; | ||||
| 
 | ||||
|     UILineEditPtr chatLineEdit = std::dynamic_pointer_cast<UILineEdit>(getParent()->recursiveGetChildById("consoleLineEdit")); | ||||
| 
 | ||||
|     //TODO: move this whole shit to lua
 | ||||
|     if(keyboardModifiers == Fw::KeyboardNoModifier) { | ||||
|         if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) { | ||||
|             g_game.walk(Otc::North); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyRight || keyCode == Fw::KeyNumpad6) { | ||||
|             g_game.walk(Otc::East); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyDown || keyCode == Fw::KeyNumpad2) { | ||||
|             g_game.walk(Otc::South); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyLeft || keyCode == Fw::KeyNumpad4) { | ||||
|             g_game.walk(Otc::West); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyNumpad9) { | ||||
|             g_game.walk(Otc::NorthEast); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyNumpad3) { | ||||
|             g_game.walk(Otc::SouthEast); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyNumpad1) { | ||||
|             g_game.walk(Otc::SouthWest); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyNumpad7) { | ||||
|             g_game.walk(Otc::NorthWest); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyDelete) { | ||||
|             chatLineEdit->removeCharacter(true); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyBackspace) { | ||||
|             chatLineEdit->removeCharacter(false); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyRight) { | ||||
|             chatLineEdit->moveCursor(true); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyLeft) { | ||||
|             chatLineEdit->moveCursor(false); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyHome) { | ||||
|             chatLineEdit->setCursorPos(0); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyEnd) { | ||||
|             chatLineEdit->setCursorPos(chatLineEdit->getText().length()); | ||||
|             return true; | ||||
|         } | ||||
|     } else if(keyboardModifiers == Fw::KeyboardCtrlModifier) { | ||||
|         if(keyCode == Fw::KeyUp || keyCode == Fw::KeyNumpad8) { | ||||
|             g_game.turn(Otc::North); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyRight || keyCode == Fw::KeyNumpad6) { | ||||
|             g_game.turn(Otc::East); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyDown || keyCode == Fw::KeyNumpad2) { | ||||
|             g_game.turn(Otc::South); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyLeft || keyCode == Fw::KeyNumpad4) { | ||||
|             g_game.turn(Otc::West); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyV) { | ||||
|             chatLineEdit->appendText(g_window.getClipboardText()); | ||||
|         } | ||||
|     } else if(keyboardModifiers == Fw::KeyboardShiftModifier) { | ||||
|         if(keyCode == Fw::KeyRight || keyCode == Fw::KeyNumpad6) { | ||||
|             chatLineEdit->moveCursor(true); | ||||
|             return true; | ||||
|         } else if(keyCode == Fw::KeyLeft || keyCode == Fw::KeyNumpad4) { | ||||
|             chatLineEdit->moveCursor(false); | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool UIGame::onKeyText(const std::string& keyText) | ||||
| { | ||||
|     if(UIWidget::onKeyText(keyText)) | ||||
|         return true; | ||||
| 
 | ||||
|     UILineEditPtr chatLineEdit = std::dynamic_pointer_cast<UILineEdit>(getParent()->recursiveGetChildById("consoleLineEdit")); | ||||
|     chatLineEdit->appendText(keyText); | ||||
|     return true; | ||||
| } | ||||
|  | @ -33,7 +33,6 @@ UIMap::UIMap() | |||
|     m_dragable = true; | ||||
|     m_mapView = MapViewPtr(new MapView); | ||||
|     g_map.addMapView(m_mapView); | ||||
|     m_mapView->followCreature(g_game.getLocalPlayer()); | ||||
| } | ||||
| 
 | ||||
| UIMap::~UIMap() | ||||
|  | @ -96,6 +95,11 @@ void UIMap::zoomOut() | |||
|     m_mapRect.moveCenter(m_rect.center()); | ||||
| } | ||||
| 
 | ||||
| void UIMap::followCreature(const CreaturePtr& creature) | ||||
| { | ||||
|     m_mapView->followCreature(creature); | ||||
| } | ||||
| 
 | ||||
| void UIMap::setCameraPosition(const Position& pos) | ||||
| { | ||||
|     m_mapView->setCameraPosition(pos); | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ public: | |||
| 
 | ||||
|     void zoomIn(); | ||||
|     void zoomOut(); | ||||
|     void followCreature(const CreaturePtr& creature); | ||||
|     void setCameraPosition(const Position& pos); | ||||
| 
 | ||||
|     TilePtr getTile(const Point& mousePos); | ||||
|  |  | |||
 Eduardo Bart
						Eduardo Bart