diff --git a/modules/client/client.lua b/modules/client/client.lua index 36288807..ca7725a8 100644 --- a/modules/client/client.lua +++ b/modules/client/client.lua @@ -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 }) diff --git a/modules/client/client.otmod b/modules/client/client.otmod index 893587d0..a3a8ea28 100644 --- a/modules/client/client.otmod +++ b/modules/client/client.otmod @@ -14,6 +14,7 @@ Module - client_terminal - client_modulemanager - client_entergame + - game @onLoad: | dofile 'client' diff --git a/modules/client_background/background.lua b/modules/client_background/background.lua index 420418a9..1c41201b 100644 --- a/modules/client_background/background.lua +++ b/modules/client_background/background.lua @@ -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 }) diff --git a/modules/client_background/background.otui b/modules/client_background/background.otui index 17ecdee6..210d788e 100644 --- a/modules/client_background/background.otui +++ b/modules/client_background/background.otui @@ -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 \ No newline at end of file + font: verdana-11px-monochrome diff --git a/modules/client_entergame/characterlist.lua b/modules/client_entergame/characterlist.lua index 33412f64..a5762102 100644 --- a/modules/client_entergame/characterlist.lua +++ b/modules/client_entergame/characterlist.lua @@ -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 diff --git a/modules/client_terminal/terminal.lua b/modules/client_terminal/terminal.lua index 9dccd91e..d41d1e56 100644 --- a/modules/client_terminal/terminal.lua +++ b/modules/client_terminal/terminal.lua @@ -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 diff --git a/modules/client_topmenu/topmenu.lua b/modules/client_topmenu/topmenu.lua index 3ae4502f..5fa5576a 100644 --- a/modules/client_topmenu/topmenu.lua +++ b/modules/client_topmenu/topmenu.lua @@ -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 diff --git a/modules/core_lib/core_lib.otmod b/modules/core_lib/core_lib.otmod index 9992a42a..c572c817 100644 --- a/modules/core_lib/core_lib.otmod +++ b/modules/core_lib/core_lib.otmod @@ -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' - - diff --git a/modules/core_lib/globals.lua b/modules/core_lib/globals.lua index 2e98cfac..592fe6ed 100644 --- a/modules/core_lib/globals.lua +++ b/modules/core_lib/globals.lua @@ -68,5 +68,3 @@ end function reloadModules() g_modules.reloadModules() end - - diff --git a/modules/core_lib/keyboard.lua b/modules/core_lib/keyboard.lua index ded616c7..5434e1e7 100644 --- a/modules/core_lib/keyboard.lua +++ b/modules/core_lib/keyboard.lua @@ -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() diff --git a/modules/core_lib/mouse.lua b/modules/core_lib/mouse.lua index 57a3123d..8d5bda90 100644 --- a/modules/core_lib/mouse.lua +++ b/modules/core_lib/mouse.lua @@ -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() diff --git a/modules/core_lib/widgets/uitabbar.lua b/modules/core_lib/widgets/uitabbar.lua index 243a1ada..4f1709ab 100644 --- a/modules/core_lib/widgets/uitabbar.lua +++ b/modules/core_lib/widgets/uitabbar.lua @@ -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 diff --git a/modules/core_styles/core_styles.otmod b/modules/core_styles/core_styles.otmod index 63c16445..b27e4d91 100644 --- a/modules/core_styles/core_styles.otmod +++ b/modules/core_styles/core_styles.otmod @@ -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' diff --git a/modules/core_styles/icons/exit.png b/modules/core_styles/icons/exit.png deleted file mode 100644 index 7af7112d..00000000 Binary files a/modules/core_styles/icons/exit.png and /dev/null differ diff --git a/modules/core_styles/styles/buttons.otui b/modules/core_styles/styles/buttons.otui index 55a0e8e6..f8b40464 100644 --- a/modules/core_styles/styles/buttons.otui +++ b/modules/core_styles/styles/buttons.otui @@ -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 diff --git a/modules/core_styles/styles/comboboxes.otui b/modules/core_styles/styles/comboboxes.otui index 245ff3e1..b6759ac8 100644 --- a/modules/core_styles/styles/comboboxes.otui +++ b/modules/core_styles/styles/comboboxes.otui @@ -42,4 +42,4 @@ ComboBox < UIComboBox image-clip: 0 20 89 20 $on: - image-clip: 0 40 89 20 \ No newline at end of file + image-clip: 0 40 89 20 diff --git a/modules/core_styles/styles/messagebox.otui b/modules/core_styles/styles/messageboxes.otui similarity index 100% rename from modules/core_styles/styles/messagebox.otui rename to modules/core_styles/styles/messageboxes.otui diff --git a/modules/core_styles/styles/progressbars.otui b/modules/core_styles/styles/progressbars.otui index 57ce896d..e5f41c9a 100644 --- a/modules/core_styles/styles/progressbars.otui +++ b/modules/core_styles/styles/progressbars.otui @@ -4,4 +4,3 @@ ProgressBar < UIProgressBar border: 1 black image: /core_styles/styles/images/progressbar.png image-border: 1 - diff --git a/modules/core_styles/styles/separators.otui b/modules/core_styles/styles/separators.otui index 59d23a4a..985518a5 100644 --- a/modules/core_styles/styles/separators.otui +++ b/modules/core_styles/styles/separators.otui @@ -3,4 +3,4 @@ HorizontalSeparator < UIWidget image-border-top: 2 height: 2 phantom: true - focusable: false \ No newline at end of file + focusable: false diff --git a/modules/core_styles/styles/tabbars.otui b/modules/core_styles/styles/tabbars.otui index 4d5b6b31..7a09f6b3 100644 --- a/modules/core_styles/styles/tabbars.otui +++ b/modules/core_styles/styles/tabbars.otui @@ -31,4 +31,4 @@ TabBarButton < UIButton color: #80c7f8 $on !checked: - color: #F55E5E \ No newline at end of file + color: #F55E5E diff --git a/modules/core_styles/styles/windows.otui b/modules/core_styles/styles/windows.otui index 14d10555..aadd2990 100644 --- a/modules/core_styles/styles/windows.otui +++ b/modules/core_styles/styles/windows.otui @@ -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 \ No newline at end of file diff --git a/modules/game/const.lua b/modules/game/const.lua new file mode 100644 index 00000000..cc712f29 --- /dev/null +++ b/modules/game/const.lua @@ -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 diff --git a/modules/game/creature.lua b/modules/game/creature.lua index 4c915423..830bb3da 100644 --- a/modules/game/creature.lua +++ b/modules/game/creature.lua @@ -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 diff --git a/modules/game/game.otmod b/modules/game/game.otmod index 5dcf5858..4cbe2a59 100644 --- a/modules/game/game.otmod +++ b/modules/game/game.otmod @@ -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() diff --git a/modules/game/gameinterface.lua b/modules/game/gameinterface.lua new file mode 100644 index 00000000..dcb5cbf8 --- /dev/null +++ b/modules/game/gameinterface.lua @@ -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 diff --git a/modules/game/gameinterface.otui b/modules/game/gameinterface.otui new file mode 100644 index 00000000..fe41b0b0 --- /dev/null +++ b/modules/game/gameinterface.otui @@ -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 diff --git a/modules/game/images/emblem_blue.png b/modules/game/icons/emblem_blue.png similarity index 100% rename from modules/game/images/emblem_blue.png rename to modules/game/icons/emblem_blue.png diff --git a/modules/game/images/emblem_green.png b/modules/game/icons/emblem_green.png similarity index 100% rename from modules/game/images/emblem_green.png rename to modules/game/icons/emblem_green.png diff --git a/modules/game/images/emblem_red.png b/modules/game/icons/emblem_red.png similarity index 100% rename from modules/game/images/emblem_red.png rename to modules/game/icons/emblem_red.png diff --git a/modules/game/images/shield_blue.png b/modules/game/icons/shield_blue.png similarity index 100% rename from modules/game/images/shield_blue.png rename to modules/game/icons/shield_blue.png diff --git a/modules/game/images/shield_blue_not_shared.png b/modules/game/icons/shield_blue_not_shared.png similarity index 100% rename from modules/game/images/shield_blue_not_shared.png rename to modules/game/icons/shield_blue_not_shared.png diff --git a/modules/game/images/shield_blue_shared.png b/modules/game/icons/shield_blue_shared.png similarity index 100% rename from modules/game/images/shield_blue_shared.png rename to modules/game/icons/shield_blue_shared.png diff --git a/modules/game/images/shield_blue_white.png b/modules/game/icons/shield_blue_white.png similarity index 100% rename from modules/game/images/shield_blue_white.png rename to modules/game/icons/shield_blue_white.png diff --git a/modules/game/images/shield_yellow.png b/modules/game/icons/shield_yellow.png similarity index 100% rename from modules/game/images/shield_yellow.png rename to modules/game/icons/shield_yellow.png diff --git a/modules/game/images/shield_yellow_not_shared.png b/modules/game/icons/shield_yellow_not_shared.png similarity index 100% rename from modules/game/images/shield_yellow_not_shared.png rename to modules/game/icons/shield_yellow_not_shared.png diff --git a/modules/game/images/shield_yellow_shared.png b/modules/game/icons/shield_yellow_shared.png similarity index 100% rename from modules/game/images/shield_yellow_shared.png rename to modules/game/icons/shield_yellow_shared.png diff --git a/modules/game/images/shield_yellow_white.png b/modules/game/icons/shield_yellow_white.png similarity index 100% rename from modules/game/images/shield_yellow_white.png rename to modules/game/icons/shield_yellow_white.png diff --git a/modules/game/images/skull_black.png b/modules/game/icons/skull_black.png similarity index 100% rename from modules/game/images/skull_black.png rename to modules/game/icons/skull_black.png diff --git a/modules/game/images/skull_green.png b/modules/game/icons/skull_green.png similarity index 100% rename from modules/game/images/skull_green.png rename to modules/game/icons/skull_green.png diff --git a/modules/game/images/skull_orange.png b/modules/game/icons/skull_orange.png similarity index 100% rename from modules/game/images/skull_orange.png rename to modules/game/icons/skull_orange.png diff --git a/modules/game/images/skull_red.png b/modules/game/icons/skull_red.png similarity index 100% rename from modules/game/images/skull_red.png rename to modules/game/icons/skull_red.png diff --git a/modules/game/images/skull_white.png b/modules/game/icons/skull_white.png similarity index 100% rename from modules/game/images/skull_white.png rename to modules/game/icons/skull_white.png diff --git a/modules/game/images/skull_yellow.png b/modules/game/icons/skull_yellow.png similarity index 100% rename from modules/game/images/skull_yellow.png rename to modules/game/icons/skull_yellow.png diff --git a/modules/old/game_interface/images/bottompanel.png b/modules/game/images/bottompanel.png similarity index 100% rename from modules/old/game_interface/images/bottompanel.png rename to modules/game/images/bottompanel.png diff --git a/modules/core_styles/icons/logout.png b/modules/game/images/logout.png similarity index 100% rename from modules/core_styles/icons/logout.png rename to modules/game/images/logout.png diff --git a/modules/old/game_interface/images/mappanel.png b/modules/game/images/mappanel.png similarity index 100% rename from modules/old/game_interface/images/mappanel.png rename to modules/game/images/mappanel.png diff --git a/modules/old/game_interface/images/miniwindow.png b/modules/game/images/miniwindow.png similarity index 100% rename from modules/old/game_interface/images/miniwindow.png rename to modules/game/images/miniwindow.png diff --git a/modules/old/game_interface/images/sidepanel.png b/modules/game/images/sidepanel.png similarity index 100% rename from modules/old/game_interface/images/sidepanel.png rename to modules/game/images/sidepanel.png diff --git a/modules/game/styles/countwindow.otui b/modules/game/styles/countwindow.otui new file mode 100644 index 00000000..eb40d20e --- /dev/null +++ b/modules/game/styles/countwindow.otui @@ -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() diff --git a/modules/core_styles/styles/creatures.otui b/modules/game/styles/creatures.otui similarity index 100% rename from modules/core_styles/styles/creatures.otui rename to modules/game/styles/creatures.otui diff --git a/modules/core_styles/styles/items.otui b/modules/game/styles/items.otui similarity index 100% rename from modules/core_styles/styles/items.otui rename to modules/game/styles/items.otui diff --git a/modules/game/styles/miniwindow.otui b/modules/game/styles/miniwindow.otui new file mode 100644 index 00000000..8729dae7 --- /dev/null +++ b/modules/game/styles/miniwindow.otui @@ -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 diff --git a/modules/old/game_interface/uiminiwindow.lua b/modules/game/uiminiwindow.lua similarity index 100% rename from modules/old/game_interface/uiminiwindow.lua rename to modules/game/uiminiwindow.lua diff --git a/modules/game/widgets/uicountwindow.lua b/modules/game/widgets/uicountwindow.lua new file mode 100644 index 00000000..ae33df27 --- /dev/null +++ b/modules/game/widgets/uicountwindow.lua @@ -0,0 +1,2 @@ +UICountWindow = {} + diff --git a/modules/game/widgets/uigamemap.lua b/modules/game/widgets/uigamemap.lua new file mode 100644 index 00000000..597f7be3 --- /dev/null +++ b/modules/game/widgets/uigamemap.lua @@ -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 diff --git a/modules/old/game_interface/uiitem.lua b/modules/game/widgets/uiitem.lua similarity index 88% rename from modules/old/game_interface/uiitem.lua rename to modules/game/widgets/uiitem.lua index 42ee50a3..481f1d43 100644 --- a/modules/old/game_interface/uiitem.lua +++ b/modules/game/widgets/uiitem.lua @@ -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) diff --git a/modules/old/game_interface/uiminiwindowcontainer.lua b/modules/game/widgets/uiminiwindowcontainer.lua similarity index 100% rename from modules/old/game_interface/uiminiwindowcontainer.lua rename to modules/game/widgets/uiminiwindowcontainer.lua diff --git a/modules/old/game_console/channelswindow.otui b/modules/game_console/channelswindow.otui similarity index 96% rename from modules/old/game_console/channelswindow.otui rename to modules/game_console/channelswindow.otui index daeebade..e118f42a 100644 --- a/modules/old/game_console/channelswindow.otui +++ b/modules/game_console/channelswindow.otui @@ -53,4 +53,4 @@ MainWindow width: 64 anchors.right: parent.right anchors.bottom: parent.bottom - @onClick: self:getParent():destroy() \ No newline at end of file + @onClick: self:getParent():destroy() diff --git a/modules/old/game_console/console.lua b/modules/game_console/console.lua similarity index 85% rename from modules/old/game_console/console.lua rename to modules/game_console/console.lua index 9a04eb19..eeaadd25 100644 --- a/modules/old/game_console/console.lua +++ b/modules/game_console/console.lua @@ -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}) \ No newline at end of file diff --git a/modules/old/game_console/console.otmod b/modules/game_console/console.otmod similarity index 56% rename from modules/old/game_console/console.otmod rename to modules/game_console/console.otmod index 0d802b99..09cb1d28 100644 --- a/modules/old/game_console/console.otmod +++ b/modules/game_console/console.otmod @@ -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() diff --git a/modules/old/game_console/console.otui b/modules/game_console/console.otui similarity index 94% rename from modules/old/game_console/console.otui rename to modules/game_console/console.otui index 1ce659f2..dd9d095c 100644 --- a/modules/old/game_console/console.otui +++ b/modules/game_console/console.otui @@ -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 \ No newline at end of file + shift-navigation: true diff --git a/modules/old/game_textmessage/textmessage.lua b/modules/game_textmessage/textmessage.lua similarity index 70% rename from modules/old/game_textmessage/textmessage.lua rename to modules/game_textmessage/textmessage.lua index d028914a..4fc39084 100644 --- a/modules/old/game_textmessage/textmessage.lua +++ b/modules/game_textmessage/textmessage.lua @@ -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 }) diff --git a/modules/old/game_textmessage/textmessage.otmod b/modules/game_textmessage/textmessage.otmod similarity index 57% rename from modules/old/game_textmessage/textmessage.otmod rename to modules/game_textmessage/textmessage.otmod index 7d285664..8ebf958f 100644 --- a/modules/old/game_textmessage/textmessage.otmod +++ b/modules/game_textmessage/textmessage.otmod @@ -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() diff --git a/modules/old/game_textmessage/textmessage.otui b/modules/game_textmessage/textmessage.otui similarity index 100% rename from modules/old/game_textmessage/textmessage.otui rename to modules/game_textmessage/textmessage.otui diff --git a/modules/game/game.lua b/modules/old/game/game.lua similarity index 100% rename from modules/game/game.lua rename to modules/old/game/game.lua diff --git a/modules/old/game/game.otmod b/modules/old/game/game.otmod new file mode 100644 index 00000000..5dcf5858 --- /dev/null +++ b/modules/old/game/game.otmod @@ -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' diff --git a/modules/game/game.otui b/modules/old/game/game.otui similarity index 100% rename from modules/game/game.otui rename to modules/old/game/game.otui diff --git a/modules/game/map.lua b/modules/old/game/map.lua similarity index 100% rename from modules/game/map.lua rename to modules/old/game/map.lua diff --git a/modules/game/movewindow.otui b/modules/old/game/movewindow.otui similarity index 96% rename from modules/game/movewindow.otui rename to modules/old/game/movewindow.otui index 9e0438f8..85fcc27c 100644 --- a/modules/game/movewindow.otui +++ b/modules/old/game/movewindow.otui @@ -1,4 +1,4 @@ -MainWindow +CountWindow < MainWindow text: Move Item size: 196 112 @onEscape: self:destroy() diff --git a/modules/game/player.lua b/modules/old/game/player.lua similarity index 100% rename from modules/game/player.lua rename to modules/old/game/player.lua diff --git a/modules/game/thing.lua b/modules/old/game/thing.lua similarity index 100% rename from modules/game/thing.lua rename to modules/old/game/thing.lua diff --git a/modules/old/game_hotkeys/hotkeys_manager.lua b/modules/old/game_hotkeys/hotkeys_manager.lua index 2371096f..6a1b0e67 100644 --- a/modules/old/game_hotkeys/hotkeys_manager.lua +++ b/modules/old/game_hotkeys/hotkeys_manager.lua @@ -455,4 +455,4 @@ function HotkeysManager.hotkeyCapture(widget, keyCode, keyboardModifiers) hotkeysWindow:getChildById('assignWindow'):getChildById('addButton'):enable() return true -end \ No newline at end of file +end diff --git a/modules/old/game_hotkeys/hotkeys_manager.otui b/modules/old/game_hotkeys/hotkeys_manager.otui index 7b3b6369..52ba6325 100644 --- a/modules/old/game_hotkeys/hotkeys_manager.otui +++ b/modules/old/game_hotkeys/hotkeys_manager.otui @@ -156,4 +156,4 @@ MainWindow width: 64 anchors.right: parent.right anchors.bottom: parent.bottom - @onClick: HotkeysManager.hide() \ No newline at end of file + @onClick: HotkeysManager.hide() diff --git a/modules/old/game_interface/gameinterface.otui b/modules/old/game_interface/gameinterface.otui index 1bfb7f9e..96b12a5f 100644 --- a/modules/old/game_interface/gameinterface.otui +++ b/modules/old/game_interface/gameinterface.otui @@ -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 diff --git a/modules/otclientrc.lua b/modules/otclientrc.lua index 83b7ac0c..5eacb642 100644 --- a/modules/otclientrc.lua +++ b/modules/otclientrc.lua @@ -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) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 910baed9..0dc08ef8 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -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") diff --git a/src/framework/application.cpp b/src/framework/application.cpp index 9eba169b..7295c94d 100644 --- a/src/framework/application.cpp +++ b/src/framework/application.cpp @@ -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("g_app", "onClose")) exit(); } diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 1952d865..7511e3d8 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -362,6 +362,7 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("setTextHidden", &UILineEdit::setTextHidden); g_lua.bindClassMemberFunction("setAlwaysActive", &UILineEdit::setAlwaysActive); g_lua.bindClassMemberFunction("setValidCharacters", &UILineEdit::setValidCharacters); + g_lua.bindClassMemberFunction("setShiftNavigation", &UILineEdit::setShiftNavigation); g_lua.bindClassMemberFunction("moveCursor", &UILineEdit::moveCursor); g_lua.bindClassMemberFunction("appendText", &UILineEdit::appendText); g_lua.bindClassMemberFunction("removeCharacter", &UILineEdit::removeCharacter); @@ -372,6 +373,7 @@ void Application::registerLuaFunctions() g_lua.bindClassMemberFunction("isCursorEnabled", &UILineEdit::isCursorEnabled); g_lua.bindClassMemberFunction("isAlwaysActive", &UILineEdit::isAlwaysActive); g_lua.bindClassMemberFunction("isTextHidden", &UILineEdit::isTextHidden); + g_lua.bindClassMemberFunction("isShiftNavigation", &UILineEdit::isShiftNavigation); // UIFrameCounter g_lua.registerClass(); diff --git a/src/framework/ui/uilineedit.cpp b/src/framework/ui/uilineedit.cpp index 035096bd..c87bbbd1 100644 --- a/src/framework/ui/uilineedit.cpp +++ b/src/framework/ui/uilineedit.cpp @@ -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()); else if(node->tag() == "always-active") setAlwaysActive(node->value()); - //else if(node->tag() == "disable-arrow-navitation") - // setArrowNavigation(node->value()); + else if(node->tag() == "shift-navigation") + setShiftNavigation(node->value()); } } @@ -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) diff --git a/src/framework/ui/uilineedit.h b/src/framework/ui/uilineedit.h index 319b9317..4922e710 100644 --- a/src/framework/ui/uilineedit.h +++ b/src/framework/ui/uilineedit.h @@ -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 m_glyphsCoords; diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index 9dbc48b6..70215d7b 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -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()); diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 2044f269..29b14773 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -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 } diff --git a/src/framework/ui/uiwidgettext.cpp b/src/framework/ui/uiwidgettext.cpp index 1089368d..cb371179 100644 --- a/src/framework/ui/uiwidgettext.cpp +++ b/src/framework/ui/uiwidgettext.cpp @@ -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) diff --git a/src/otclient/CMakeLists.txt b/src/otclient/CMakeLists.txt index d6148735..976a6b78 100644 --- a/src/otclient/CMakeLists.txt +++ b/src/otclient/CMakeLists.txt @@ -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 diff --git a/src/otclient/core/container.cpp b/src/otclient/core/container.cpp new file mode 100644 index 00000000..df12527a --- /dev/null +++ b/src/otclient/core/container.cpp @@ -0,0 +1,23 @@ +/* + * 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 "container.h" diff --git a/src/otclient/ui/uigame.h b/src/otclient/core/container.h similarity index 83% rename from src/otclient/ui/uigame.h rename to src/otclient/core/container.h index 5ae1e7ba..f29a5b42 100644 --- a/src/otclient/ui/uigame.h +++ b/src/otclient/core/container.h @@ -20,17 +20,16 @@ * THE SOFTWARE. */ -#ifndef UIGAME_H -#define UIGAME_H +#ifndef CONTAINER_H +#define CONTAINER_H #include "declarations.h" -#include -class UIGame : public UIWidget +class Container { -protected: - bool onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks); - bool onKeyText(const std::string& keyText); +public: + Container(); + }; #endif diff --git a/src/otclient/core/declarations.h b/src/otclient/core/declarations.h index 78c46fd5..15ccb338 100644 --- a/src/otclient/core/declarations.h +++ b/src/otclient/core/declarations.h @@ -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 MapViewPtr; typedef std::shared_ptr TilePtr; typedef std::shared_ptr ThingPtr; typedef std::shared_ptr ItemPtr; +typedef std::shared_ptr ContainerPtr; typedef std::shared_ptr CreaturePtr; typedef std::shared_ptr MonsterPtr; typedef std::shared_ptr NpcPtr; diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index 7b1c15cd..d49bd4fb 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -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) diff --git a/src/otclient/core/game.h b/src/otclient/core/game.h index 2b0aa59d..850bac1e 100644 --- a/src/otclient/core/game.h +++ b/src/otclient/core/game.h @@ -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 m_containers; bool m_dead; int m_serverBeat; Otc::FightModes m_fightMode; diff --git a/src/otclient/core/mapview.cpp b/src/otclient/core/mapview.cpp index f59897bb..189b7ead 100644 --- a/src/otclient/core/mapview.cpp +++ b/src/otclient/core/mapview.cpp @@ -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(); } diff --git a/src/otclient/core/mapview.h b/src/otclient/core/mapview.h index 53e893cd..e23dc356 100644 --- a/src/otclient/core/mapview.h +++ b/src/otclient/core/mapview.h @@ -93,7 +93,6 @@ public: MapViewPtr asMapView() { return std::static_pointer_cast(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 m_mustUpdateVisibleTilesCache; Boolean m_mustDrawVisibleTilesCache; Boolean m_mustCleanFramebuffer; diff --git a/src/otclient/core/player.cpp b/src/otclient/core/player.cpp new file mode 100644 index 00000000..237e5355 --- /dev/null +++ b/src/otclient/core/player.cpp @@ -0,0 +1,23 @@ +/* + * 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 "player.h" diff --git a/src/otclient/core/player.h b/src/otclient/core/player.h index 461c4069..83c93b1a 100644 --- a/src/otclient/core/player.h +++ b/src/otclient/core/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(shared_from_this()); } }; diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index 66aa5151..a557b499 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -26,6 +26,7 @@ #include #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 diff --git a/src/otclient/core/thing.h b/src/otclient/core/thing.h index 1b270009..8b197c7d 100644 --- a/src/otclient/core/thing.h +++ b/src/otclient/core/thing.h @@ -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(shared_from_this()); } diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index 7b487d02..1d27729c 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -305,6 +305,7 @@ void OTClient::registerLuaFunctions() g_lua.registerClass(); g_lua.bindClassStaticFunction("create", []{ return UIMapPtr(new UIMap); } ); + g_lua.bindClassMemberFunction("followCreature", &UIMap::followCreature); g_lua.bindClassMemberFunction("getTile", &UIMap::getTile); g_lua.bindClassMemberFunction("zoomIn", &UIMap::zoomIn); g_lua.bindClassMemberFunction("zoomOut", &UIMap::zoomOut); diff --git a/src/otclient/ui/uigame.cpp b/src/otclient/ui/uigame.cpp deleted file mode 100644 index bf001a40..00000000 --- a/src/otclient/ui/uigame.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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 "uigame.h" -#include -#include -#include - -bool UIGame::onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks) -{ - if(UIWidget::onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks)) - return true; - - UILineEditPtr chatLineEdit = std::dynamic_pointer_cast(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(getParent()->recursiveGetChildById("consoleLineEdit")); - chatLineEdit->appendText(keyText); - return true; -} diff --git a/src/otclient/ui/uimap.cpp b/src/otclient/ui/uimap.cpp index 411ec563..b7816d05 100644 --- a/src/otclient/ui/uimap.cpp +++ b/src/otclient/ui/uimap.cpp @@ -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); diff --git a/src/otclient/ui/uimap.h b/src/otclient/ui/uimap.h index 41452cc9..074976c2 100644 --- a/src/otclient/ui/uimap.h +++ b/src/otclient/ui/uimap.h @@ -37,6 +37,7 @@ public: void zoomIn(); void zoomOut(); + void followCreature(const CreaturePtr& creature); void setCameraPosition(const Position& pos); TilePtr getTile(const Point& mousePos);