diff --git a/modules/about/about.otmod b/modules/about/about.otmod index 7c1a14c4..353895a8 100644 --- a/modules/about/about.otmod +++ b/modules/about/about.otmod @@ -3,7 +3,6 @@ Module description: Create the about window author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true dependencies: - core diff --git a/modules/background/background.otmod b/modules/background/background.otmod index 8523717d..750d33a5 100644 --- a/modules/background/background.otmod +++ b/modules/background/background.otmod @@ -3,10 +3,8 @@ Module description: Handles the background of the login screen author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true dependencies: - core - - topmenu onLoad: | require 'background' diff --git a/modules/chat/chat.otmod b/modules/chat/chat.otmod index 401582b2..6ce771d6 100644 --- a/modules/chat/chat.otmod +++ b/modules/chat/chat.otmod @@ -3,10 +3,6 @@ Module description: Manage chat window author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - game - onLoad: | require 'chat' return true diff --git a/modules/core_styles/styles/windows.otui b/modules/core_styles/styles/windows.otui index 80b6c3ba..43d6e350 100644 --- a/modules/core_styles/styles/windows.otui +++ b/modules/core_styles/styles/windows.otui @@ -6,6 +6,7 @@ Window < UIWindow head height: 20 head text align: center move policy: free + stackable: true border-image: source: /core_styles/images/window.png border: 4 diff --git a/modules/entergame/entergame.otmod b/modules/entergame/entergame.otmod index ccfcb342..7b9bfa7d 100644 --- a/modules/entergame/entergame.otmod +++ b/modules/entergame/entergame.otmod @@ -3,12 +3,6 @@ Module description: Manages enter game and character list windows author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - core - - topmenu - - background - onLoad: | require 'entergame' require 'characterlist' diff --git a/modules/game/game.lua b/modules/game/game.lua index 4303bf26..06555566 100644 --- a/modules/game/game.lua +++ b/modules/game/game.lua @@ -17,6 +17,7 @@ function Game.createInterface() Background.hide() CharacterList.destroyLoadBox() Game.gameUi = loadUI('/game/game.otui', UI.root) + UI.root:moveChildToIndex(Game.gameUi, 1) Game.gameMapPanel = Game.gameUi:getChildById('mapPanel') Game.gameRightPanel = Game.gameUi:getChildById('rightPanel') Game.gameBottomPanel = Game.gameUi:getChildById('bottomPanel') diff --git a/modules/game/game.otmod b/modules/game/game.otmod index c16c6676..4f941688 100644 --- a/modules/game/game.otmod +++ b/modules/game/game.otmod @@ -3,14 +3,6 @@ Module description: Create the game interface, where the ingame stuff starts author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - core - - tibiafiles - - topmenu - - entergame - - background - onLoad: | require 'game' return true diff --git a/modules/health_mana/health_mana.otmod b/modules/health_mana/health_mana.otmod index aa0c828b..c62bf9b3 100644 --- a/modules/health_mana/health_mana.otmod +++ b/modules/health_mana/health_mana.otmod @@ -3,10 +3,6 @@ Module description: Displays health and mana points author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - game - onLoad: | require 'health_mana' return true diff --git a/modules/inventory/inventory.otmod b/modules/inventory/inventory.otmod index f9d1ab13..1ce10ed3 100644 --- a/modules/inventory/inventory.otmod +++ b/modules/inventory/inventory.otmod @@ -1,12 +1,8 @@ Module - name: equipments + name: inventory description: View local player equipments window author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - game - onLoad: | require 'inventory' return true diff --git a/modules/options/options.otmod b/modules/options/options.otmod index 254ca702..97d72044 100644 --- a/modules/options/options.otmod +++ b/modules/options/options.otmod @@ -3,10 +3,6 @@ Module description: Create the options window author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - core - onLoad: | require 'options' return true diff --git a/modules/otclient/otclient.otmod b/modules/otclient/otclient.otmod new file mode 100644 index 00000000..1ffe3485 --- /dev/null +++ b/modules/otclient/otclient.otmod @@ -0,0 +1,17 @@ +Module + name: otclient + description: Load all other otclient modules + author: OTClient team + website: https://github.com/edubart/otclient + dependencies: + - core + - background + - topmenu + - game + - health_mana + - inventory + - skills + - viplist + - textmessage + - chat + diff --git a/modules/skills/skills.otmod b/modules/skills/skills.otmod index 12340ea5..b895f8a2 100644 --- a/modules/skills/skills.otmod +++ b/modules/skills/skills.otmod @@ -3,10 +3,6 @@ Module description: Manage skills window author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - game - onLoad: | require 'skills' return true diff --git a/modules/textmessage/textmessage.otmod b/modules/textmessage/textmessage.otmod index 2edfca4d..534a2fe0 100644 --- a/modules/textmessage/textmessage.otmod +++ b/modules/textmessage/textmessage.otmod @@ -3,10 +3,6 @@ Module description: Manage game text messages author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - game - onLoad: | require 'textmessage' return true diff --git a/modules/topmenu/topmenu.otmod b/modules/topmenu/topmenu.otmod index 325c6ac3..84bcca62 100644 --- a/modules/topmenu/topmenu.otmod +++ b/modules/topmenu/topmenu.otmod @@ -3,9 +3,11 @@ Module description: Create the top menu author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true dependencies: - core + - entergame + - options + - about onLoad: | require 'topmenu' diff --git a/modules/viplist/viplist.otmod b/modules/viplist/viplist.otmod index 7f995c5d..40b14260 100644 --- a/modules/viplist/viplist.otmod +++ b/modules/viplist/viplist.otmod @@ -3,10 +3,6 @@ Module description: Manage vip list window author: OTClient team website: https://github.com/edubart/otclient - autoLoad: true - dependencies: - - game - onLoad: | require 'viplist' return true diff --git a/modules/viplist/viplist.otui b/modules/viplist/viplist.otui index 8829fe92..f8ebda5d 100644 --- a/modules/viplist/viplist.otui +++ b/modules/viplist/viplist.otui @@ -8,6 +8,7 @@ MiniWindow TextList id: vipList + border-image: ~ anchors.fill: parent margin.top: 26 margin.bottom: 6 diff --git a/src/framework/core/resourcemanager.cpp b/src/framework/core/resourcemanager.cpp index 2071febc..3544dbe2 100644 --- a/src/framework/core/resourcemanager.cpp +++ b/src/framework/core/resourcemanager.cpp @@ -29,7 +29,7 @@ ResourceManager g_resources; -void ResourceManager::init(const char* argv0) +void ResourceManager::init(const char* argv0, const char *appName) { PHYSFS_init(argv0); @@ -39,11 +39,12 @@ void ResourceManager::init(const char* argv0) std::string possibleDirs[] = { "modules", baseDir + "modules", baseDir + "../modules", - baseDir + "../share/otclient/modules", + baseDir + "../share/" + appName + "/otclient/modules", "" }; bool found = false; for(const std::string& dir : possibleDirs) { + dump << dir; if(g_resources.addToSearchPath(dir)) { logInfo("Using modules directory '", dir.c_str(), "'"); found = true; diff --git a/src/framework/core/resourcemanager.h b/src/framework/core/resourcemanager.h index 844591a1..09d785b5 100644 --- a/src/framework/core/resourcemanager.h +++ b/src/framework/core/resourcemanager.h @@ -28,7 +28,7 @@ class ResourceManager { public: - void init(const char* argv0); + void init(const char* argv0, const char *appName); void terminate(); /// Set output files directory diff --git a/src/framework/luascript/luafunctions.cpp b/src/framework/luascript/luafunctions.cpp index 7605b89b..b834324c 100644 --- a/src/framework/luascript/luafunctions.cpp +++ b/src/framework/luascript/luafunctions.cpp @@ -49,6 +49,7 @@ void LuaInterface::registerFunctions() g_lua.bindClassMemberFunction("setSize", &UIWidget::resize); g_lua.bindClassMemberFunction("getPosition", &UIWidget::getPosition); g_lua.bindClassMemberFunction("moveTo", &UIWidget::moveTo); + g_lua.bindClassMemberFunction("moveChildToIndex", &UIWidget::moveChildToIndex); g_lua.bindClassMemberFunction("getParent", &UIWidget::getParent); g_lua.bindClassMemberFunction("setParent", &UIWidget::setParent); g_lua.bindClassMemberFunction("getBackgroundColor", &UIWidget::getBackgroundColor); diff --git a/src/framework/ui/uiverticallayout.cpp b/src/framework/ui/uiverticallayout.cpp index b72e64e0..d9c40641 100644 --- a/src/framework/ui/uiverticallayout.cpp +++ b/src/framework/ui/uiverticallayout.cpp @@ -28,6 +28,7 @@ UIVerticalLayout::UIVerticalLayout(UIWidgetPtr parentWidget) : UILayout(parentWidget) { m_alignBottom = false; + m_padding = 0; } void UIVerticalLayout::applyStyle(const OTMLNodePtr& styleNode) @@ -37,6 +38,8 @@ void UIVerticalLayout::applyStyle(const OTMLNodePtr& styleNode) for(const OTMLNodePtr& node : styleNode->children()) { if(node->tag() == "align bottom") m_alignBottom = node->value(); + else if(node->tag() == "padding") + m_padding = node->value(); } } @@ -45,12 +48,6 @@ void UIVerticalLayout::update() UIWidgetPtr parentWidget = getParentWidget(); UIWidgetList widgets = parentWidget->getChildren(); - // sort by Y pos - std::sort(widgets.begin(), widgets.end(), - [](const UIWidgetPtr& first, const UIWidgetPtr& second) -> bool { - return first->getY() < second->getY(); - }); - if(m_alignBottom) std::reverse(widgets.begin(), widgets.end()); @@ -68,13 +65,12 @@ void UIVerticalLayout::update() } widget->setRect(Rect(pos, size)); pos.y += (m_alignBottom) ? -widget->getMarginTop() : (widget->getHeight() + widget->getMarginBottom()); + pos.y += m_padding; } } void UIVerticalLayout::addWidget(const UIWidgetPtr& widget) { - // needed to be correctly sorted on the following update - widget->setY(9999); update(); } diff --git a/src/framework/ui/uiverticallayout.h b/src/framework/ui/uiverticallayout.h index 56a8fcef..79ea9b37 100644 --- a/src/framework/ui/uiverticallayout.h +++ b/src/framework/ui/uiverticallayout.h @@ -37,6 +37,7 @@ public: private: bool m_alignBottom; + int m_padding; }; #endif diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 780ae67d..d167ea56 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -497,6 +497,18 @@ void UIWidget::moveChildToTop(const UIWidgetPtr& child) m_children.push_back(child); } +void UIWidget::moveChildToIndex(const UIWidgetPtr& child, int index) +{ + if(!child) + return; + + // remove and push child again + auto it = std::find(m_children.begin(), m_children.end(), child); + assert(it != m_children.end()); + m_children.erase(it); + m_children.insert(m_children.begin() + index - 1, child); +} + void UIWidget::lockChild(const UIWidgetPtr& child) { if(!child) @@ -572,6 +584,17 @@ bool UIWidget::isChildLocked(const UIWidgetPtr& child) return it != m_lockedChildren.end(); } +int UIWidget::getChildIndex(const UIWidgetPtr& child) +{ + int index = 1; + for(auto it = m_children.begin(); it != m_children.end(); ++it) { + if(*it == child) + return index; + ++index; + } + return -1; +} + void UIWidget::updateParentLayout() { if(UIWidgetPtr parent = getParent()) diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 409374b8..cc3d8e38 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -139,9 +139,11 @@ public: void focusNextChild(Fw::FocusReason reason); void focusPreviousChild(Fw::FocusReason reason); void moveChildToTop(const UIWidgetPtr& child); + void moveChildToIndex(const UIWidgetPtr& child, int index); void lockChild(const UIWidgetPtr& child); void unlockChild(const UIWidgetPtr& child); bool isChildLocked(const UIWidgetPtr& child); + int getChildIndex(const UIWidgetPtr& child); void updateParentLayout(); void updateLayout(); diff --git a/src/framework/ui/uiwindow.cpp b/src/framework/ui/uiwindow.cpp index eb9c6fc0..910af09f 100644 --- a/src/framework/ui/uiwindow.cpp +++ b/src/framework/ui/uiwindow.cpp @@ -32,6 +32,7 @@ void UIWindow::setup() m_moving = false; m_movePolicy = DONT_MOVE; m_headHeight = 0; + m_oldIndex = -1; m_titleAlign = Fw::AlignCenter; } @@ -103,15 +104,6 @@ void UIWindow::onGeometryUpdate(const Rect& oldRect, const Rect& newRect) setRect(boundRect); } -void UIWindow::onFocusChange(bool focused, Fw::FocusReason reason) -{ - // when a window is focused it goes to the top - if(focused) { - if(UIWidgetPtr parent = getParent()) - parent->moveChildToTop(asUIWidget()); - } -} - bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button) { if(m_movePolicy != DONT_MOVE) { @@ -120,6 +112,9 @@ bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button) if(!clickedChild || clickedChild->isPhantom()) { m_moving = true; m_movingReference = mousePos - getRect().topLeft(); + m_oldIndex = getParent()->getChildIndex(asUIWidget()); + m_oldPos = getPosition(); + getParent()->moveChildToTop(asUIWidget()); } } return UIWidget::onMousePress(mousePos, button); @@ -128,6 +123,25 @@ bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button) bool UIWindow::onMouseRelease(const Point& mousePos, Fw::MouseButton button) { if(m_moving) { + if(m_movePolicy == FREE_UPDATED_MOVE) { + UIWidgetPtr parent = getParent(); + + // restore position before move + parent->moveChildToIndex(asUIWidget(), m_oldIndex); + moveTo(m_oldPos); + + // calculate new index + int newIndex; + for(newIndex=parent->getChildCount();newIndex>1;--newIndex) { + UIWidgetPtr child = parent->getChildByIndex(newIndex); + if(mousePos.y >= child->getRect().top()) + break; + } + + // set the new index + parent->moveChildToIndex(asUIWidget(), newIndex); + updateParentLayout(); + } m_moving = false; return true; } @@ -138,8 +152,6 @@ bool UIWindow::onMouseMove(const Point& mousePos, const Point& mouseMoved) { if(m_moving) { moveTo(mousePos - m_movingReference); - if(m_movePolicy == FREE_UPDATED_MOVE) - updateParentLayout(); return true; } return UIWidget::onMouseMove(mousePos, mouseMoved); diff --git a/src/framework/ui/uiwindow.h b/src/framework/ui/uiwindow.h index b8946dae..95cc5a4d 100644 --- a/src/framework/ui/uiwindow.h +++ b/src/framework/ui/uiwindow.h @@ -43,7 +43,6 @@ public: protected: virtual void onStyleApply(const OTMLNodePtr& styleNode); virtual void onGeometryUpdate(const Rect& oldRect, const Rect& newRect); - virtual void onFocusChange(bool focused, Fw::FocusReason reason); virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button); virtual bool onMouseRelease(const Point& mousePos, Fw::MouseButton button); virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved); @@ -54,6 +53,8 @@ private: bool m_moving; MovePolicy m_movePolicy; Point m_movingReference; + Point m_oldPos; + int m_oldIndex; // styling BorderImagePtr m_headImage; diff --git a/src/otclient/const.h b/src/otclient/const.h index 7f2f0d27..1ad7a220 100644 --- a/src/otclient/const.h +++ b/src/otclient/const.h @@ -28,6 +28,7 @@ namespace Otc { static const char* AppName = "OTClient"; + static const char* AppPathName = "otclient"; static const char* AppVersion = "0.4.0"; static const char* CipsoftPublicRSA = "1321277432058722840622950990822933849527763264961655079678763618" diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index 47a7327b..dbcd8559 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -105,9 +105,7 @@ void Game::processTextMessage(int type, const std::string& message) void Game::processInventoryChange(int slot, const ItemPtr& item) { - g_dispatcher.addEvent([slot, item] { - g_lua.callGlobalField("Game","onInventoryChange", slot, item); - }); + g_lua.callGlobalField("Game","onInventoryChange", slot, item); } void Game::walk(Otc::Direction direction) diff --git a/src/otclient/net/protocolgame.h b/src/otclient/net/protocolgame.h index 55d5c1e3..6083d2b8 100644 --- a/src/otclient/net/protocolgame.h +++ b/src/otclient/net/protocolgame.h @@ -67,7 +67,7 @@ private: void parsePlayerLogin(InputMessage& msg); void parseGMActions(InputMessage& msg); - void parseErrorMessage(InputMessage& msg); + void parseLoginError(InputMessage& msg); void parseFYIMessage(InputMessage& msg); void parseWaitList(InputMessage& msg); void parsePing(InputMessage&); diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index ce626f0b..5b77b8c4 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -46,7 +46,7 @@ void ProtocolGame::parseMessage(InputMessage& msg) parseGMActions(msg); break; case Otc::GameServerLoginError: - parseErrorMessage(msg); + parseLoginError(msg); break; case Otc::GameServerLoginAdvice: parseFYIMessage(msg); @@ -274,10 +274,10 @@ void ProtocolGame::parseGMActions(InputMessage& msg) msg.getU8(); } -void ProtocolGame::parseErrorMessage(InputMessage& msg) +void ProtocolGame::parseLoginError(InputMessage& msg) { std::string error = msg.getString(); - g_game.processLoginError(error); + g_dispatcher.addEvent(std::bind(&Game::processLoginError, &g_game, error)); } void ProtocolGame::parseFYIMessage(InputMessage& msg) @@ -454,13 +454,13 @@ void ProtocolGame::parseAddInventoryItem(InputMessage& msg) { uint8 slot = msg.getU8(); ItemPtr item = internalGetItem(msg, 0xFFFF); - g_game.processInventoryChange(slot, item); + g_dispatcher.addEvent(std::bind(&Game::processInventoryChange, &g_game, slot, item)); } void ProtocolGame::parseRemoveInventoryItem(InputMessage& msg) { uint8 slot = msg.getU8(); - g_game.processInventoryChange(slot, ItemPtr(nullptr)); + g_dispatcher.addEvent(std::bind(&Game::processInventoryChange, &g_game, slot, ItemPtr())); } void ProtocolGame::parseOpenShopWindow(InputMessage& msg) @@ -771,7 +771,6 @@ void ProtocolGame::parseTextMessage(InputMessage& msg) uint8 type = msg.getU8(); std::string message = msg.getString(); - // must be scheduled because the map may not exist yet g_dispatcher.addEvent(std::bind(&Game::processTextMessage, &g_game, type, message)); } diff --git a/src/otclient/otclient.cpp b/src/otclient/otclient.cpp index ede805b2..3e87be27 100644 --- a/src/otclient/otclient.cpp +++ b/src/otclient/otclient.cpp @@ -58,7 +58,7 @@ void OTClient::init(std::vector args) registerLuaFunctions(); // initialize resources - g_resources.init(args[0].c_str()); + g_resources.init(args[0].c_str(), Otc::AppPathName); // load configurations loadConfigurations(); @@ -90,6 +90,7 @@ void OTClient::init(std::vector args) // discover and load modules g_modules.discoverAndLoadModules(); + g_modules.getModule("otclient")->load(); // now that everything is initialized, setup configurations setupConfigurations(); diff --git a/src/otclient/otclient.h b/src/otclient/otclient.h index 8a711d2c..85726aeb 100644 --- a/src/otclient/otclient.h +++ b/src/otclient/otclient.h @@ -59,6 +59,8 @@ public: void setOnClose(const SimpleCallback& onCloseCallback) { m_onCloseCallback = onCloseCallback; } SimpleCallback getOnClose() const { return m_onCloseCallback; } + static void registerLuaFunctions(); + private: /// Set default configurations and load the user configurations void loadConfigurations(); @@ -66,8 +68,6 @@ private: void setupConfigurations(); void saveConfigurations(); - void registerLuaFunctions(); - bool m_running; bool m_stopping;