From 8b2cb410c282db1516624e2b109e97fbd802b306 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Mon, 29 Aug 2011 11:14:21 -0300 Subject: [PATCH] ctrl+g kinda working, but login/logout events still need a remake --- modules/game/game.lua | 32 +++++- modules/game/ui/gameinterface.otui | 4 +- modules/mainmenu/characterlist.lua | 93 ++++++++++++++++++ modules/mainmenu/entergame.lua | 119 +++++++---------------- modules/mainmenu/mainmenu.lua | 22 +++++ modules/mainmenu/mainmenu.otmod | 10 +- modules/mainmenu/ui/charlist.otui | 18 ++-- modules/mainmenu/ui/entergamewindow.otui | 4 +- modules/mainmenu/ui/mainmenu.otui | 2 +- src/framework/luascript/luafunctions.cpp | 11 +++ src/framework/luascript/luainterface.cpp | 10 ++ src/framework/luascript/luainterface.h | 30 ++++++ src/framework/ui/uimanager.cpp | 8 +- src/framework/ui/uiwidget.cpp | 20 +++- src/framework/ui/uiwidget.h | 6 +- src/otclient/core/creature.h | 1 + src/otclient/core/datmanager.cpp | 1 + src/otclient/core/datmanager.h | 2 +- src/otclient/core/game.cpp | 12 ++- src/otclient/core/game.h | 5 +- src/otclient/core/map.cpp | 3 +- src/otclient/core/map.h | 1 - src/otclient/core/tile.cpp | 6 -- src/otclient/net/protocolgame.cpp | 4 +- src/otclient/net/protocolgame.h | 5 +- src/otclient/net/protocolgameparse.cpp | 16 +-- src/otclient/otclientluafunctions.cpp | 14 +++ 27 files changed, 317 insertions(+), 142 deletions(-) create mode 100644 modules/mainmenu/characterlist.lua create mode 100644 modules/mainmenu/mainmenu.lua diff --git a/modules/game/game.lua b/modules/game/game.lua index 55983ed4..d9aecd0d 100644 --- a/modules/game/game.lua +++ b/modules/game/game.lua @@ -1,13 +1,35 @@ -function Game.createMainInterface() +-- private functions +local function onGameKeyPress(self, keyCode, keyChar, keyboardModifiers) + if keyboardModifiers == KeyboardCtrlModifier then + if keyCode == KeyG then + CharacterList.show() + return true + end + end + return false +end + +local function createMainInterface() gameUi = loadUI('/game/ui/gameinterface.otui', UI.root) + gameUi.onKeyPress = onGameKeyPress end -function Game.onLogin() +local function destroyMainInterface() + if gameUi then + gameUi:destroy() + gameUi = nil + end +end + +function Game.onLogin() + MainMenu.hide() + CharacterList.destroyLoadBox() + createMainInterface() end function Game.onLogout() - gameUi:destroy() - gameUi = nil - mainMenu:show() + MainMenu.show() + CharacterList.show() + destroyMainInterface() end diff --git a/modules/game/ui/gameinterface.otui b/modules/game/ui/gameinterface.otui index a5c0524f..476c95ad 100644 --- a/modules/game/ui/gameinterface.otui +++ b/modules/game/ui/gameinterface.otui @@ -10,6 +10,4 @@ UIWidget anchors.left: gameMap.right anchors.top: parent.top text: Logout - onClick: | - Game.logout() - Game.onLogout() \ No newline at end of file + onClick: Game.logout() \ No newline at end of file diff --git a/modules/mainmenu/characterlist.lua b/modules/mainmenu/characterlist.lua new file mode 100644 index 00000000..6547739a --- /dev/null +++ b/modules/mainmenu/characterlist.lua @@ -0,0 +1,93 @@ +CharacterList = { } + +-- private variables +local charactersWindow +local loadBox +local characterList + +-- private functions +local function onCharactersWindowKeyPress(self, keyCode, keyChar, keyboardModifiers) + if keyboardModifiers == KeyboardNoModifier then + if keyCode == KeyUp or keyCode == KeyTab then + characterList:focusPreviousChild(ActiveFocusReason) + elseif keyCode == KeyDown then + characterList:focusNextChild(ActiveFocusReason) + end + end + return false +end + +-- public functions +function CharacterList.create(characters, premDays) + if charactersWindow then + charactersWindow:destroy() + end + + charactersWindow = UI.loadAndDisplayLocked('/mainmenu/ui/charlist.otui') + characterList = charactersWindow:getChildById('characterList') + local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel') + charactersWindow.onKeyPress = onCharactersWindowKeyPress + + for i,characterInfo in ipairs(characters) do + local characterName = characterInfo[1] + local worldName = characterInfo[2] + local worldHost = characterInfo[3] + local worldIp = characterInfo[4] + + local label = UILabel.create() + characterList:addChild(label) + label:setText(characterName .. ' (' .. worldName .. ')') + label:setStyle('CharacterListLabel') + label.characterName = characterName + label.worldHost = worldHost + label.worldPort = worldIp + + if i == 0 or Configs.get('lastUsedCharacter') == characterName then + characterList:focusChild(label, ActiveFocusReason) + end + end + + if premDays > 0 then + accountStatusLabel:setText("Account Status:\nPremium Account (" .. premDays .. ' days left)') + end +end + +function CharacterList.hide() + charactersWindow:unlock() + charactersWindow:hide() +end + +function CharacterList.show() + charactersWindow:show() + charactersWindow:lock() +end + +function CharacterList.doLogin() + local selected = charactersWindow:getChildById('characterList'):getFocusedChild() + if selected then + --if Game.isOnline() then + -- Game.logout() + --end + + Game.loginWorld(EnterGame.account, EnterGame.password, selected.worldHost, selected.worldPort, selected.characterName) + CharacterList.hide() + + loadBox = displayCancelBox('Please wait', 'Connecting to game server...') + function loadBox.onCancel() + Game.logout() + CharacterList.show() + end + + -- save last used character + Configs.set('lastUsedCharacter', selected.characterName) + else + displayErrorBox('Error', 'You must select a character to login!') + end +end + +function CharacterList.destroyLoadBox() + if loadBox then + loadBox:destroy() + loadBox = nil + end +end diff --git a/modules/mainmenu/entergame.lua b/modules/mainmenu/entergame.lua index 6a4099f9..470443c4 100644 --- a/modules/mainmenu/entergame.lua +++ b/modules/mainmenu/entergame.lua @@ -1,103 +1,56 @@ -local account -local password +EnterGame = { } -function EnterGame_characterWindow_okClicked() - local charactersWindow = UI.root:getChildById('charactersWindow') - local selected = charactersWindow:getChildById('charactersList'):getFocusedChild() - if selected then - Game.loginWorld(account, password, selected.worldHost, selected.worldPort, selected.characterName) - Configs.set('lastUsedCharacter', selected.characterName) - charactersWindow:destroy() - mainMenu:hide() - Game.createMainInterface() - else - displayErrorBox('Error', 'You must select a character to login!') - end +-- private variables +local password +local loadBox +local enterGameWindow + +-- private functions +local function onError(protocol, error) + loadBox:destroy() + local errorBox = displayErrorBox('Login Error', error) + errorBox.onOk = EnterGame.create() end -local function showMotd(motdNumber, motdMessage) +local function onMotd(protocol, motd) + loadBox:destroy() + local motdNumber = string.sub(motd, 0, string.find(motd, "\n")) + local motdMessage = string.sub(motd, string.find(motd, "\n") + 1, string.len(motd)) if motdNumber ~= Configs.get("motd") then displayInfoBox("Message of the day", motdMessage) Configs.set("motd", motdNumber) end end -local function createCharactersWindow(characters, premDays) - local charactersWindow = UI.loadAndDisplayLocked('/mainmenu/ui/charlist.otui') - local charactersList = charactersWindow:getChildById('charactersList') - local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel') - - function charactersWindow:onKeyPress(keyCode, keyChar, keyboardModifiers) - if keyboardModifiers == KeyboardNoModifier then - if keyCode == KeyUp or keyCode == KeyTab then - charactersList:focusPreviousChild(ActiveFocusReason) - elseif keyCode == KeyDown then - charactersList:focusNextChild(ActiveFocusReason) - end - end - return false - end - - for i,characterInfo in ipairs(characters) do - local characterName = characterInfo[1] - local worldName = characterInfo[2] - local worldHost = characterInfo[3] - local worldIp = characterInfo[4] - - local label = UILabel.create() - charactersList:addChild(label) - label:setText(characterName .. ' (' .. worldName .. ')') - label:setStyle('CharactersListLabel') - label.characterName = characterName - label.worldHost = worldHost - label.worldPort = worldIp +local function onCharacterList(protocol, characters, premDays) + CharacterList.create(characters, premDays) +end - if i == 0 or Configs.get('lastUsedCharacter') == characterName then - charactersList:focusChild(label, ActiveFocusReason) - end - end - if premDays > 0 then - accountStatusLabel:setText("Account Status:\nPremium Account (" .. premDays .. ' days left)') - end +-- public functions +function EnterGame.create() + enterGameWindow = UI.loadAndDisplayLocked('/mainmenu/ui/entergamewindow.otui') end -function EnterGame_connectToLoginServer() - local protocolLogin = ProtocolLogin.create() +function EnterGame.destroy() + enterGameWindow:destroy() + enterGameWindow = nil +end - local recreateEnterGame = function() - UI.loadAndDisplayLocked('/mainmenu/ui/entergamewindow.otui') - end +function EnterGame.doLogin() + EnterGame.account = enterGameWindow:getChildById('accountNameLineEdit'):getText() + EnterGame.password = enterGameWindow:getChildById('accountPasswordLineEdit'):getText() + EnterGame.destroy() - local loadBox = displayCancelBox('Please wait', 'Connecting to login server...') + local protocolLogin = ProtocolLogin.create() + protocolLogin.onError = onError + protocolLogin.onMotd = onMotd + protocolLogin.onCharacterList = onCharacterList + loadBox = displayCancelBox('Please wait', 'Connecting to login server...') loadBox.onCancel = function(msgbox) - -- cancel protocol and reacreate enter game window protocolLogin:cancelLogin() - recreateEnterGame() + EnterGame.create() end - protocolLogin.onError = function(protocol, error) - loadBox:destroy() - local errorBox = displayErrorBox('Login Error', error) - errorBox.onOk = recreateEnterGame - end - - protocolLogin.onMotd = function(protocol, motd) - loadBox:destroy() - local motdNumber = string.sub(motd, 0, string.find(motd, "\n")) - local motdMessage = string.sub(motd, string.find(motd, "\n") + 1, string.len(motd)) - showMotd(motdNumber, motdMessage) - end - - protocolLogin.onCharacterList = function(protocol, characters, premDays) - loadBox:destroy() - createCharactersWindow(characters, premDays) - end - - local enterGameWindow = UI.root:getChildById('enterGameWindow') - account = enterGameWindow:getChildById('accountNameLineEdit'):getText() - password = enterGameWindow:getChildById('accountPasswordLineEdit'):getText() - protocolLogin:login(account, password) - - enterGameWindow:destroy() + protocolLogin:login(EnterGame.account, EnterGame.password) end diff --git a/modules/mainmenu/mainmenu.lua b/modules/mainmenu/mainmenu.lua new file mode 100644 index 00000000..390eb0e8 --- /dev/null +++ b/modules/mainmenu/mainmenu.lua @@ -0,0 +1,22 @@ +MainMenu = { } + +-- private variables +local mainMenu + +-- public functions +function MainMenu.create() + mainMenu = UI.loadAndDisplay("/mainmenu/ui/mainmenu.otui") +end + +function MainMenu.destroy() + mainMenu:destroy() + mainMenu = nil +end + +function MainMenu.hide() + mainMenu:hide() +end + +function MainMenu.show() + mainMenu:show() +end diff --git a/modules/mainmenu/mainmenu.otmod b/modules/mainmenu/mainmenu.otmod index ebaf94d2..7c5d0b82 100644 --- a/modules/mainmenu/mainmenu.otmod +++ b/modules/mainmenu/mainmenu.otmod @@ -9,17 +9,17 @@ Module - core onLoad: | - require('entergame') + require 'mainmenu' + require 'entergame' + require 'characterlist' if not initialized then - mainMenu = UI.loadAndDisplay("/mainmenu/ui/mainmenu.otui") + MainMenu.create() initialized = true end - return true onUnload: | - mainMenu:destroy() - mainMenu = nil + MainMenu.destroy() initialized = false diff --git a/modules/mainmenu/ui/charlist.otui b/modules/mainmenu/ui/charlist.otui index b7776b17..9fbf5e49 100644 --- a/modules/mainmenu/ui/charlist.otui +++ b/modules/mainmenu/ui/charlist.otui @@ -1,4 +1,4 @@ -CharactersListLabel < Label +CharacterListLabel < Label image: /core_ui/images/empty_rect.png font: tibia-10px-monochrome background-color: #00000000 @@ -16,11 +16,11 @@ MainWindow id: charactersWindow title: Charlist size: 250 250 - onEnter: EnterGame_characterWindow_okClicked() + onEnter: CharacterList.doLogin() onEscape: function(self) self:destroy() end TextList - id: charactersList + id: characterList anchors.fill: parent anchors.bottom: next.top margin.top: 30 @@ -29,10 +29,12 @@ MainWindow margin.right: 16 Label + id: accountStatusLabel text: |- Account Status: Free Account - id: accountStatusLabel + font: helvetica-11px-bold + color: #33cc66 anchors.left: parent.left anchors.right: parent.right anchors.bottom: next.top @@ -55,7 +57,7 @@ MainWindow anchors.bottom: parent.bottom margin.bottom: 16 margin.right: 16 - onClick: EnterGame_characterWindow_okClicked() + onClick: CharacterList.doLogin() Button id: buttonCancel @@ -65,4 +67,8 @@ MainWindow anchors.bottom: parent.bottom margin.bottom: 16 margin.right: 16 - onClick: function(self) self:getParent():destroy() end \ No newline at end of file + onClick: | + function(self) + self:getParent():unlock() + self:getParent():hide() + end \ No newline at end of file diff --git a/modules/mainmenu/ui/entergamewindow.otui b/modules/mainmenu/ui/entergamewindow.otui index ee2956d8..89d45748 100644 --- a/modules/mainmenu/ui/entergamewindow.otui +++ b/modules/mainmenu/ui/entergamewindow.otui @@ -2,7 +2,7 @@ MainWindow id: enterGameWindow title: Enter Game size: 236 160 - onEnter: EnterGame_connectToLoginServer() + onEnter: EnterGame.doLogin() onEscape: function(self) self:destroy() end LargerLabel @@ -43,7 +43,7 @@ MainWindow anchors.bottom: parent.bottom margin.bottom: 16 margin.right: 16 - onClick: EnterGame_connectToLoginServer() + onClick: EnterGame.doLogin() Button text: Cancel diff --git a/modules/mainmenu/ui/mainmenu.otui b/modules/mainmenu/ui/mainmenu.otui index 516e6799..579e868e 100644 --- a/modules/mainmenu/ui/mainmenu.otui +++ b/modules/mainmenu/ui/mainmenu.otui @@ -24,7 +24,7 @@ Panel MenuButton text: Enter Game margin.top: 18 - onClick: UI.loadAndDisplayLocked("/mainmenu/ui/entergamewindow.otui") + onClick: EnterGame.create() MenuButton text: Options diff --git a/src/framework/luascript/luafunctions.cpp b/src/framework/luascript/luafunctions.cpp index f7780691..1fee4c85 100644 --- a/src/framework/luascript/luafunctions.cpp +++ b/src/framework/luascript/luafunctions.cpp @@ -59,8 +59,18 @@ void LuaInterface::registerFunctions() g_lua.bindClassMemberFunction("setMarginLeft", &UIWidget::setMarginLeft); g_lua.bindClassMemberFunction("getMarginRight", &UIWidget::getMarginRight); g_lua.bindClassMemberFunction("setMarginRight", &UIWidget::setMarginRight); + g_lua.bindClassMemberFunction("isVisible", &UIWidget::isVisible); + g_lua.bindClassMemberFunction("isHidden", &UIWidget::isHidden); + g_lua.bindClassMemberFunction("isHovered", &UIWidget::isHovered); + g_lua.bindClassMemberFunction("isFocused", &UIWidget::isFocused); + g_lua.bindClassMemberFunction("isPressed", &UIWidget::isPressed); + g_lua.bindClassMemberFunction("isEnabled", &UIWidget::isEnabled); + g_lua.bindClassMemberFunction("isDisabled", &UIWidget::isDisabled); + g_lua.bindClassMemberFunction("isActive", &UIWidget::isActive); g_lua.bindClassMemberFunction("hide", &UIWidget::hide); g_lua.bindClassMemberFunction("show", &UIWidget::show); + g_lua.bindClassMemberFunction("lock", &UIWidget::lock); + g_lua.bindClassMemberFunction("unlock", &UIWidget::unlock); g_lua.bindClassMemberFunction("getChildById", &UIWidget::getChildById); g_lua.bindClassMemberFunction("getChildByIndex", &UIWidget::getChildByIndex); g_lua.bindClassMemberFunction("getChildCount", &UIWidget::getChildCount); @@ -72,6 +82,7 @@ void LuaInterface::registerFunctions() g_lua.bindClassMemberFunction("focusNextChild", &UIWidget::focusNextChild); g_lua.bindClassMemberFunction("focusPreviousChild", &UIWidget::focusPreviousChild); g_lua.bindClassMemberFunction("lockChild", &UIWidget::lockChild); + g_lua.bindClassMemberFunction("unlockChild", &UIWidget::unlockChild); g_lua.bindClassMemberFunction("updateLayout", &UIWidget::updateLayout); g_lua.bindClassMemberFunction("updateParentLayout", &UIWidget::updateParentLayout); g_lua.bindClassMemberFunction("destroy", &UIWidget::destroy); diff --git a/src/framework/luascript/luainterface.cpp b/src/framework/luascript/luainterface.cpp index 6226cf31..00c4eba8 100644 --- a/src/framework/luascript/luainterface.cpp +++ b/src/framework/luascript/luainterface.cpp @@ -775,6 +775,16 @@ void LuaInterface::getGlobal(const std::string& key) lua_getglobal(L, key.c_str()); } +void LuaInterface::getGlobalField(const std::string& globalKey, const std::string& fieldKey) +{ + getGlobal(globalKey); + if(!isNil()) { + assert(isTable() || isUserdata()); + getField(fieldKey); + remove(-2); + } +} + void LuaInterface::setGlobal(const std::string& key) { assert(hasIndex(-1)); diff --git a/src/framework/luascript/luainterface.h b/src/framework/luascript/luainterface.h index 5e47bf08..d081acfa 100644 --- a/src/framework/luascript/luainterface.h +++ b/src/framework/luascript/luainterface.h @@ -164,6 +164,12 @@ public: /// prevents new variables in this new environment to be set on the global environment void newEnvironment(); + template + int callGlobalField(const std::string& global, const std::string& field, const T&... args); + + template + R callGlobalField(const std::string& global, const std::string& field, const T&... args); + private: /// Load scripts requested by lua 'require' static int luaScriptLoader(lua_State* L); @@ -221,6 +227,7 @@ public: void setEnv(int index = -2); void getGlobal(const std::string& key); + void getGlobalField(const std::string& globalKey, const std::string& fieldKey); void setGlobal(const std::string& key); void rawGet(int index = -1); @@ -347,4 +354,27 @@ T LuaInterface::castValue(int index) { return o; } +template +int LuaInterface::callGlobalField(const std::string& global, const std::string& field, const T&... args) { + g_lua.getGlobalField(global, field); + if(!g_lua.isNil()) { + g_lua.polymorphicPush(args...); + return g_lua.protectedCall(sizeof...(args)); + } else + g_lua.pop(1); + return 0; +} + +template +R LuaInterface::callGlobalField(const std::string& global, const std::string& field, const T&... args) { + R result; + int rets = callGlobalField(global, field, args...); + if(rets > 0) { + assert(rets == 1); + result = g_lua.polymorphicPop(); + } else + result = R(); + return result; +} + #endif diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index bc3725fa..e55ab39c 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -188,13 +188,7 @@ UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const U std::string widgetType = styleNode->valueAt("__widgetType"); // call widget creation from lua - //g_lua.getGlobalField(widgetType, "create"); - g_lua.getGlobal(widgetType); - g_lua.getField("create"); - g_lua.remove(-2); - g_lua.protectedCall(0, 1); - - UIWidgetPtr widget = g_lua.polymorphicPop(); + UIWidgetPtr widget = g_lua.callGlobalField(widgetType, "create"); if(parent) parent->addChild(widget); diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index ed76b039..3325d00e 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -167,6 +167,18 @@ void UIWidget::setRect(const Rect& rect) m_updateEventScheduled = true; } +void UIWidget::lock() +{ + if(UIWidgetPtr parent = getParent()) + parent->lockChild(asUIWidget()); +} + +void UIWidget::unlock() +{ + if(UIWidgetPtr parent = getParent()) + parent->unlockChild(asUIWidget()); +} + bool UIWidget::isVisible() { if(!m_visible) @@ -365,8 +377,11 @@ void UIWidget::removeChild(const UIWidgetPtr& child) auto it = std::find(m_children.begin(), m_children.end(), child); if(it != m_children.end()) { // defocus if needed - if(m_focusedChild == child) + bool focusAnother = false; + if(m_focusedChild == child) { focusChild(nullptr, Fw::ActiveFocusReason); + focusAnother = true; + } // unlock child if it was locked unlockChild(child); @@ -381,6 +396,9 @@ void UIWidget::removeChild(const UIWidgetPtr& child) // update child states child->updateStates(); + + if(focusAnother) + focusPreviousChild(Fw::ActiveFocusReason); } else logError("attempt to remove an unknown child from a UIWidget"); } diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 6a26eadc..b5256bfd 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -73,6 +73,8 @@ public: void show() { setVisible(true); } void disable() { setEnabled(false); } void enable() { setEnabled(true); } + void lock(); + void unlock(); bool isActive() const { return hasState(Fw::ActiveState); } bool isEnabled() const { return !hasState(Fw::DisabledState); } @@ -81,6 +83,7 @@ public: bool isHovered() const { return hasState(Fw::HoverState); } bool isPressed() const { return hasState(Fw::PressedState); } bool isVisible(); + bool isHidden() { return !isVisible(); } bool isExplicitlyEnabled() const { return m_enabled; } bool isExplicitlyVisible() const { return m_visible; } bool isFocusable() const { return m_focusable; } @@ -143,9 +146,6 @@ public: UIWidgetPtr asUIWidget() { return std::static_pointer_cast(shared_from_this()); } private: - void internalDestroy(); - void internalDestroyCheck(); - bool m_updateEventScheduled; protected: diff --git a/src/otclient/core/creature.h b/src/otclient/core/creature.h index 1f000b1b..272c0214 100644 --- a/src/otclient/core/creature.h +++ b/src/otclient/core/creature.h @@ -26,6 +26,7 @@ #include "thing.h" #include +//TODO: create Outfit class and move to a separate file struct Outfit { uint16 type; uint8 head; diff --git a/src/otclient/core/datmanager.cpp b/src/otclient/core/datmanager.cpp index 99d3f320..381e4ad5 100644 --- a/src/otclient/core/datmanager.cpp +++ b/src/otclient/core/datmanager.cpp @@ -22,6 +22,7 @@ #include "datmanager.h" #include "spritemanager.h" +#include "thing.h" #include DatManager g_dat; diff --git a/src/otclient/core/datmanager.h b/src/otclient/core/datmanager.h index b376049f..eac45899 100644 --- a/src/otclient/core/datmanager.h +++ b/src/otclient/core/datmanager.h @@ -24,7 +24,7 @@ #define DATMANAGER_H #include -#include "thing.h" +#include "thingattributes.h" class DatManager { diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index 7e4a0562..ea181225 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -46,17 +46,19 @@ void Game::loginWorld(const std::string& account, const std::string& password, c void Game::logout() { m_protocolGame->sendLogout(); - onLogout(); + processLogout(); } -void Game::onLogin() +void Game::processLogin(const LocalPlayerPtr& localPlayer) { - m_localPlayer = LocalPlayerPtr(new LocalPlayer); + m_localPlayer = localPlayer; m_online = true; + g_lua.callGlobalField("Game", "onLogin", m_localPlayer); } -void Game::onLogout() +void Game::processLogout() { + g_lua.callGlobalField("Game", "onLogout", m_localPlayer); if(m_protocolGame) { m_protocolGame->disconnect(); m_protocolGame.reset(); @@ -72,7 +74,7 @@ void Game::walk(Otc::Direction direction) // TODO: check if we can walk. - m_localPlayer->setDirection(direction); + //m_localPlayer->setDirection(direction); switch(direction) { case Otc::North: diff --git a/src/otclient/core/game.h b/src/otclient/core/game.h index 806193c0..810e7030 100644 --- a/src/otclient/core/game.h +++ b/src/otclient/core/game.h @@ -36,10 +36,11 @@ public: const std::string& password, const std::string& worldHost, int worldPort, const std::string& characterName); + void cancelLogin(); void logout(); - void onLogin(); - void onLogout(); + void processLogin(const LocalPlayerPtr& localPlayer); + void processLogout(); void walk(Otc::Direction direction); void turn(Otc::Direction direction); diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index b438608f..235cd150 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -23,6 +23,7 @@ #include "map.h" #include "game.h" #include "localplayer.h" +#include "tile.h" #include #include @@ -187,7 +188,7 @@ void Map::cleanTile(const Position& pos) CreaturePtr Map::getCreatureById(uint32 id) { - if(g_game.getLocalPlayer()->getId() == id) + if(g_game.getLocalPlayer() && g_game.getLocalPlayer()->getId() == id) return g_game.getLocalPlayer(); return m_creatures[id]; } diff --git a/src/otclient/core/map.h b/src/otclient/core/map.h index 7a2f75dc..517e1e49 100644 --- a/src/otclient/core/map.h +++ b/src/otclient/core/map.h @@ -23,7 +23,6 @@ #ifndef MAP_H #define MAP_H -#include "tile.h" #include "creature.h" #include diff --git a/src/otclient/core/tile.cpp b/src/otclient/core/tile.cpp index 3828ef7a..2f807e40 100644 --- a/src/otclient/core/tile.cpp +++ b/src/otclient/core/tile.cpp @@ -99,12 +99,6 @@ void Tile::addThing(ThingPtr thing, int stackpos) const ThingAttributes& thingAttributes = thing->getAttributes(); - if(thing->getPosition() == g_game.getLocalPlayer()->getPosition() + Position(-1, 0, 0) && thingAttributes.group == Otc::ThingGroundGroup) { - logDebug((int)thing->getId()); - } - - - if(thing->asItem()) { if(thingAttributes.group == Otc::ThingGroundGroup) m_ground = thing; diff --git a/src/otclient/net/protocolgame.cpp b/src/otclient/net/protocolgame.cpp index 09bd9367..b3339c57 100644 --- a/src/otclient/net/protocolgame.cpp +++ b/src/otclient/net/protocolgame.cpp @@ -22,6 +22,8 @@ #include #include +#include +#include ProtocolGame::ProtocolGame() { @@ -69,6 +71,6 @@ void ProtocolGame::onRecv(InputMessage& inputMessage) void ProtocolGame::onError(const boost::system::error_code& error) { // already disconnected, just fire onLogout - g_game.onLogout(); + g_game.processLogout(); } diff --git a/src/otclient/net/protocolgame.h b/src/otclient/net/protocolgame.h index 40cc82d7..ab358a20 100644 --- a/src/otclient/net/protocolgame.h +++ b/src/otclient/net/protocolgame.h @@ -24,10 +24,9 @@ #define PROTOCOLGAME_H #include "declarations.h" +#include #include - -#include -#include +#include class ProtocolGame : public Protocol { diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 77dff5cc..c43a97e1 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -26,7 +26,9 @@ #include #include #include +#include #include +#include void ProtocolGame::parseMessage(InputMessage& msg) { @@ -258,9 +260,7 @@ void ProtocolGame::parsePlayerLogin(InputMessage& msg) int playerDrawSpeed = msg.getU16(); int playerCanReportBugs = msg.getU8(); - g_game.onLogin(); - - m_localPlayer = g_game.getLocalPlayer(); + m_localPlayer = LocalPlayerPtr(new LocalPlayer); m_localPlayer->setId(playerId); m_localPlayer->setDrawSpeed(playerDrawSpeed); m_localPlayer->setCanReportBugs(playerCanReportBugs); @@ -975,9 +975,8 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) g_map.removeCreatureById(removeId); - LocalPlayerPtr localPlayer = g_game.getLocalPlayer(); - if(localPlayer->getId() == id) - creature = localPlayer->asCreature(); + if(m_localPlayer->getId() == id) + creature = m_localPlayer->asCreature(); creature->setId(id); creature->setName(name); @@ -1013,6 +1012,11 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) thing = creature; + // login event is generated the first time that local player gets known + if(!g_game.isOnline() && creature == m_localPlayer) { + // this event must be scheduled because the entire map description is not known yet + g_dispatcher.addEvent(std::bind(&Game::processLogin, &g_game, m_localPlayer)); + } } else if(thingId == 0x0063) { // creature turn parseCreatureTurn(msg); diff --git a/src/otclient/otclientluafunctions.cpp b/src/otclient/otclientluafunctions.cpp index ea4f7ebb..0bdfce89 100644 --- a/src/otclient/otclientluafunctions.cpp +++ b/src/otclient/otclientluafunctions.cpp @@ -24,6 +24,12 @@ #include #include +#include +#include +#include +#include +#include +#include #include #include #include @@ -44,6 +50,14 @@ void OTClient::registerLuaFunctions() g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); g_lua.bindClassStaticFunction("loginWorld", std::bind(&Game::loginWorld, &g_game, _1, _2, _3, _4, _5)); g_lua.bindClassStaticFunction("logout", std::bind(&Game::logout, &g_game));