diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game.cpp | 135 | ||||
-rw-r--r-- | src/gui/gui.cpp | 130 | ||||
-rw-r--r-- | src/gui/gui.h | 25 | ||||
-rw-r--r-- | src/gui/inventorywindow.cpp | 4 | ||||
-rw-r--r-- | src/gui/popupmenu.h | 2 | ||||
-rw-r--r-- | src/net/protocol.cpp | 18 | ||||
-rw-r--r-- | src/net/protocol.h | 8 |
7 files changed, 164 insertions, 158 deletions
diff --git a/src/game.cpp b/src/game.cpp index e7f7beb7..ab0e73d9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -58,7 +58,6 @@ #include "gui/npc.h" #include "gui/npc_text.h" #include "gui/ok_dialog.h" -#include "gui/popupmenu.h" #include "gui/requesttrade.h" #include "gui/sell.h" #include "gui/setup.h" @@ -116,7 +115,6 @@ ChargeDialog *chargeDialog; TradeWindow *tradeWindow; //BuddyWindow *buddyWindow; HelpWindow *helpWindow; -PopupMenu *popupMenu; DebugWindow *debugWindow; Inventory *inventory = NULL; @@ -217,7 +215,6 @@ void createGuiWindows() tradeWindow = new TradeWindow(); //buddyWindow = new BuddyWindow(); helpWindow = new HelpWindow(); - popupMenu = new PopupMenu(); debugWindow = new DebugWindow(); // Initialize window positions @@ -252,7 +249,6 @@ void createGuiWindows() tradeWindow->setVisible(false); //buddyWindow->setVisible(false); helpWindow->setVisible(false); - popupMenu->setVisible(false); debugWindow->setVisible(false); // Do not focus any text field @@ -283,7 +279,6 @@ void destroyGuiWindows() delete tradeWindow; //delete buddyWindow; delete helpWindow; - delete popupMenu; delete debugWindow; } @@ -671,136 +666,6 @@ void do_input() } } - // Mouse events - else if (event.type == SDL_MOUSEBUTTONDOWN) - { - int mx = event.button.x / 32 + camera_x; - int my = event.button.y / 32 + camera_y; - - // Mouse button left - if (event.button.button == SDL_BUTTON_LEFT) - { - // Don't move when shift is pressed - // XXX Is this too hackish? I'm not sure if making the Gui - // class a KeyListener is a good idea and works as expected - // at all... - if (keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) { - used = true; - } - - // Check for default actions for NPC/Monster/Players - Being *target = findNode(mx, my); - Uint32 floorItemId = find_floor_item_by_cor(mx, my); - - if (target) - { - switch (target->getType()) - { - case Being::NPC: - // NPC default: talk - if (!current_npc) - { - MessageOut outMsg; - outMsg.writeInt16(CMSG_NPC_TALK); - outMsg.writeInt32(target->getId()); - outMsg.writeInt8(0); - current_npc = target->getId(); - } - break; - - case Being::MONSTER: - case Being::PLAYER: - // Monster and player default: attack - /** - * TODO: Move player to mouse click position before - * attack the monster (maybe using follow mode). - */ - if (target->action != Being::MONSTER_DEAD && - player_node->action == Being::STAND && - target != player_node) - { - // Autotarget by default with mouse - autoTarget = target; - - attack(target); - } - break; - - default: - break; - } - } - // Check for default action to items on the floor - else if (floorItemId != 0) - { - /** - * TODO: Move player to mouse click position before - * pick up the items on the floor. - * - * Provisory: pick up only items near of player. - */ - int dx = mx - player_node->x; - int dy = my - player_node->y; - // "sqrt(dx*dx + dy*dy) < 2" is equal to "dx*dx + dy*dy < 4" - if ((dx*dx + dy*dy) < 4) - { - MessageOut outMsg; - outMsg.writeInt16(0x009f); - outMsg.writeInt32(floorItemId); - } - } - - // Just cancel the popup menu if shown, and don't make the - // character walk - if (popupMenu->isVisible() == true) - { - // If we click elsewhere than in the window, do not use - // the event - // The user wanted to close the popup. - // Still buggy : Wonder if the x, y, width, and height - // aren't reported partially with these functions. - if (event.button.x >= - (popupMenu->getX() + popupMenu->getWidth()) || - event.button.x < popupMenu->getX() || - event.button.y >= - (popupMenu->getY() + popupMenu->getHeight()) || - event.button.y < popupMenu->getY()) - { - used = true; - popupMenu->setVisible(false); - } - } - - } // End Mouse left button - - // Mouse button middle - else if (event.button.button == SDL_BUTTON_MIDDLE) - { - /* - * Some people haven't a mouse with three buttons, - * right Usiu??? ;-) - */ - } - - // Mouse button right - else if (event.button.button == SDL_BUTTON_RIGHT) - { - Being *being; - FloorItem *floorItem; - - if ((being = findNode(mx, my)) && being != player_node) { - popupMenu->showPopup(event.button.x, event.button.y, - being); - } else if ((floorItem = find_floor_item_by_id( - find_floor_item_by_cor(mx, my)))) { - popupMenu->showPopup(event.button.x, event.button.y, - floorItem); - } else { - popupMenu->setVisible(false); - } - } - } - // Quit event else if (event.type == SDL_QUIT) { diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index bf35e3ec..25b794ec 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -34,6 +34,7 @@ #include <guichan/sdl/sdlinput.hpp> #include "focushandler.h" +#include "popupmenu.h" #include "window.h" #include "windowcontainer.h" @@ -41,6 +42,7 @@ #include "../configlistener.h" #include "../configuration.h" #include "../engine.h" +#include "../floor_item.h" #include "../game.h" #include "../graphics.h" #include "../log.h" @@ -87,7 +89,8 @@ class GuiConfigListener : public ConfigListener Gui::Gui(Graphics *graphics): mHostImageLoader(NULL), mMouseCursor(NULL), - mCustomCursor(false) + mCustomCursor(false), + mPopupActive(false) { // Set graphics setGraphics(graphics); @@ -168,10 +171,14 @@ Gui::Gui(Graphics *graphics): setUseCustomCursor(config.getValue("customcursor", 1) == 1); mConfigListener = new GuiConfigListener(this); config.addListener("customcursor", mConfigListener); + + mPopup = new PopupMenu(); } Gui::~Gui() { + delete mPopup; + config.removeListener("customcursor", mConfigListener); delete mConfigListener; @@ -231,21 +238,100 @@ Gui::mousePress(int mx, int my, int button) { // Mouse pressed on window container (basically, the map) - // When conditions for walking are met, set new player destination - if (player_node && - player_node->action != Being::DEAD && - current_npc == 0 && - button == gcn::MouseInput::LEFT) + // Are we in-game yet? + if (state != GAME_STATE) + return; + + // Check if we are alive and kickin' + if (!player_node || player_node->action == Being::DEAD) + return; + + // Check if we are busy + if (current_npc) + return; + + int tilex = mx / 32 + camera_x; + int tiley = my / 32 + camera_y; + + // Right click might open a popup + if (button == gcn::MouseInput::RIGHT) { - Map *tiledMap = engine->getCurrentMap(); - int tilex = mx / 32 + camera_x; - int tiley = my / 32 + camera_y; + Being *being; + FloorItem *floorItem; - if (state == GAME_STATE && tiledMap->getWalk(tilex, tiley)) { - walk(tilex, tiley, 0); - player_node->setDestination(tilex, tiley); + if ((being = findNode(tilex, tiley)) && being != player_node) + { + showPopup(mx, my, being); + return; + } + else if(floorItem = find_floor_item_by_id( + find_floor_item_by_cor(mx, my))) + { + showPopup(mx, my, floorItem); + return; + } + } + + // If a popup is active, just remove it + if (mPopupActive) + { + mPopup->setVisible(false); + mPopupActive = false; + return; + } + + // Left click can cause different actions + if (button == gcn::MouseInput::LEFT) + { + Being *being; + Uint32 floorItemId; - autoTarget = NULL; + // Interact with some being + if (being = findNode(tilex, tiley)) + { + switch (being->getType()) + { + case Being::NPC: + talk(being); + current_npc = being->getId(); + break; + + case Being::MONSTER: + case Being::PLAYER: + if (being->action == Being::MONSTER_DEAD || + player_node->action != Being::STAND || + being == player_node) + break; + + autoTarget = being; + attack(being); + break; + + default: + break; + } + } + // Pick up some item + else if (floorItemId = find_floor_item_by_cor(tilex, tiley)) + { + int dx = tilex - player_node->x; + int dy = tiley - player_node->y; + + if ((dx * dx + dy * dy) < 4) + pickUp(floorItemId); + } + // Just walk around + else if (engine->getCurrentMap()->getWalk(tilex, tiley)) + { + // XXX XXX XXX REALLY UGLY! + Uint8 *keys = SDL_GetKeyState(NULL); + if (!(keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT])) + { + walk(tilex, tiley, 0); + player_node->setDestination(tilex, tiley); + + autoTarget = NULL; + } } } } @@ -282,3 +368,21 @@ Gui::setUseCustomCursor(bool customCursor) } } } + +void Gui::showPopup(int x, int y, Item *item) +{ + mPopup->showPopup(x, y, item); + mPopupActive = true; +} + +void Gui::showPopup(int x, int y, FloorItem *floorItem) +{ + mPopup->showPopup(x, y, floorItem); + mPopupActive = true; +} + +void Gui::showPopup(int x, int y, Being *being) +{ + mPopup->showPopup(x, y, being); + mPopupActive = true; +} diff --git a/src/gui/gui.h b/src/gui/gui.h index 238ee38e..83f731db 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -29,9 +29,13 @@ #include "../guichanfwd.h" +class Being; +class FloorItem; class GuiConfigListener; class Graphics; class Image; +class Item; +class PopupMenu; class WindowContainer; /** @@ -92,10 +96,22 @@ class Gui : public gcn::Gui, public gcn::MouseListener setUseCustomCursor(bool customCursor); /** - * ConfigListener method. + * Shows a popup for an item + * TODO Find some way to get rid of Item here */ - void - optionChanged(const std::string &name); + void showPopup(int x, int y, Item *item); + + /** + * Shows a popup for a floor item + * TODO Find some way to get rid of FloorItem here + */ + void showPopup(int x, int y, FloorItem *floorItem); + + /** + * Shows a popup for a being + * TODO Find some way to get rid of Being here + */ + void showPopup(int x, int y, Being *being); private: GuiConfigListener *mConfigListener; @@ -104,6 +120,9 @@ class Gui : public gcn::Gui, public gcn::MouseListener gcn::Font *mGuiFont; /**< The global GUI font */ Image *mMouseCursor; /**< Mouse cursor image */ bool mCustomCursor; /**< Show custom cursor */ + + PopupMenu *mPopup; /**< Popup window */ + bool mPopupActive; }; extern Gui *gui; /**< The GUI system */ diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 35809bdd..0b8a37a7 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -31,9 +31,9 @@ #include <guichan/widgets/label.hpp> #include "button.h" +#include "gui.h" #include "item_amount.h" #include "itemcontainer.h" -#include "popupmenu.h" #include "scrollarea.h" #include "../inventory.h" @@ -162,7 +162,7 @@ void InventoryWindow::mouseClick(int x, int y, int button, int count) */ int mx = x + getX(); int my = y + getY(); - popupMenu->showPopup(mx, my, item); + gui->showPopup(mx, my, item); } } diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h index 97cadf38..dfbb2e92 100644 --- a/src/gui/popupmenu.h +++ b/src/gui/popupmenu.h @@ -79,6 +79,4 @@ class PopupMenu : public Window, public LinkHandler void showPopup(int x, int y); }; -extern PopupMenu *popupMenu; - #endif diff --git a/src/net/protocol.cpp b/src/net/protocol.cpp index e57be110..7a98ffb6 100644 --- a/src/net/protocol.cpp +++ b/src/net/protocol.cpp @@ -23,13 +23,10 @@ #include "protocol.h" -#include "messagein.h" #include "messageout.h" -#include "network.h" #include "../being.h" #include "../game.h" -#include "../log.h" #include "../main.h" #include "../playerinfo.h" #include "../sound.h" @@ -85,6 +82,21 @@ void action(char type, int id) outMsg.writeInt8(type); } +void talk(Being *being) +{ + MessageOut outMsg; + outMsg.writeInt16(CMSG_NPC_TALK); + outMsg.writeInt32(being->getId()); + outMsg.writeInt8(0); +} + +void pickUp(Uint32 floorItemId) +{ + MessageOut outMsg; + outMsg.writeInt16(0x009f); + outMsg.writeInt32(floorItemId); +} + Being* attack(unsigned short x, unsigned short y, unsigned char direction) { Being *target = NULL; diff --git a/src/net/protocol.h b/src/net/protocol.h index c6e118d4..8ac0f16d 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -24,6 +24,8 @@ #ifndef _TMW_PROTOCOL_ #define _TMW_PROTOCOL_ +#include <SDL_types.h> + class Being; // Packets from server to client @@ -127,4 +129,10 @@ void attack(Being *target); /** Request action */ void action(char type, int id); +/** Talk to a being */ +void talk(Being *being); + +/** Pick up an item */ +void pickUp(Uint32 floorItemId); + #endif |