From aff167beefadc32add4b44626cc2f1cbef800c7b Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Sun, 30 Jul 2006 14:33:28 +0000 Subject: Updated TMW to be compatible with Guichan 0.5.0 (merged from guichan-0.5.0 branch). --- src/gui/sell.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gui/sell.h') diff --git a/src/gui/sell.h b/src/gui/sell.h index 59bc58c2..423fea26 100644 --- a/src/gui/sell.h +++ b/src/gui/sell.h @@ -68,7 +68,7 @@ class SellDialog : public Window, public gcn::ActionListener /** * Called when receiving actions from the widgets. */ - void action(const std::string& eventId); + void action(const std::string& eventId, gcn::Widget* widget); /** * Mouse callback -- cgit v1.2.3-70-g09d2 From 07b6070c25faedd78c2e26825bd700dc294f00cf Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Sat, 26 Aug 2006 17:24:43 +0000 Subject: Made the Network class a purely static interface, as there is only one instance. --- ChangeLog | 9 +++++ src/beingmanager.cpp | 7 +--- src/beingmanager.h | 4 --- src/engine.cpp | 5 ++- src/engine.h | 4 +-- src/game.cpp | 42 +++++++++++------------ src/game.h | 5 +-- src/gui/buy.cpp | 4 +-- src/gui/buy.h | 4 +-- src/gui/char_select.cpp | 17 +++++----- src/gui/char_select.h | 8 ++--- src/gui/chat.cpp | 5 ++- src/gui/chat.h | 4 +-- src/gui/sell.cpp | 3 +- src/gui/sell.h | 4 +-- src/gui/trade.cpp | 3 +- src/gui/trade.h | 5 +-- src/localplayer.h | 4 --- src/main.cpp | 48 +++++++++++++------------- src/net/charserverhandler.cpp | 4 +-- src/net/messagehandler.cpp | 14 +------- src/net/messagehandler.h | 7 ---- src/net/network.cpp | 47 ++++++++++++++----------- src/net/network.h | 79 ++++++++++++++----------------------------- src/net/tradehandler.h | 2 -- src/npc.cpp | 4 +-- src/npc.h | 7 +--- 27 files changed, 136 insertions(+), 213 deletions(-) (limited to 'src/gui/sell.h') diff --git a/ChangeLog b/ChangeLog index 8e10286f..97782a6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,15 @@ support for "say around" messages. * src/net/beinghandler.cpp: Partly implemented being creation, so that chat works. + * src/game.cpp, src/engine.h, src/beingmanager.h, src/gui/trade.cpp, + src/gui/sell.cpp, src/gui/char_select.cpp, src/gui/chat.h, + src/gui/buy.h, src/gui/chat.cpp, src/gui/char_select.h, + src/gui/buy.cpp, src/gui/sell.h, src/gui/trade.h, src/engine.cpp, + src/beingmanager.cpp, src/npc.cpp, src/main.cpp, src/npc.h, + src/net/tradehandler.h, src/net/messagehandler.h, src/net/network.h, + src/net/charserverhandler.cpp, src/net/messagehandler.cpp, + src/net/network.cpp, src/localplayer.h, src/game.h: Made the Network + class a purely static interface, as there is only one instance. 2006-08-21 Eugenio Favalli diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp index 7a94859a..caecd88e 100644 --- a/src/beingmanager.cpp +++ b/src/beingmanager.cpp @@ -49,11 +49,6 @@ class FindBeingFunctor Being::Type type; } beingFinder; -BeingManager::BeingManager(Network *network): - mNetwork(network) -{ -} - void BeingManager::setMap(Map *map) { mMap = map; @@ -79,7 +74,7 @@ Being* BeingManager::createBeing(Uint32 id, Uint16 job) outMsg.writeLong(id); } else if (job >= 100 & job < 200) - being = new NPC(id, job, mMap, mNetwork); + being = new NPC(id, job, mMap); else if (job >= 1000 && job < 1200) being = new Monster(id, job, mMap); else diff --git a/src/beingmanager.h b/src/beingmanager.h index bb6fc99b..0dbafcc6 100644 --- a/src/beingmanager.h +++ b/src/beingmanager.h @@ -28,7 +28,6 @@ class LocalPlayer; class Map; -class Network; typedef std::list Beings; typedef Beings::iterator BeingIterator; @@ -36,8 +35,6 @@ typedef Beings::iterator BeingIterator; class BeingManager { public: - BeingManager(Network *network); - /** * Sets the map on which beings are created */ @@ -86,7 +83,6 @@ class BeingManager protected: Beings mBeings; Map *mMap; - Network *mNetwork; }; extern BeingManager *beingManager; diff --git a/src/engine.cpp b/src/engine.cpp index a6ce9533..3e6b091a 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -62,10 +62,9 @@ Spriteset *emotionset; Spriteset *npcset; std::vector weaponset; -Engine::Engine(Network *network): +Engine::Engine(): mShowDebugPath(false), - mCurrentMap(NULL), - mNetwork(network) + mCurrentMap(NULL) { // Load the sprite sets ResourceManager *resman = ResourceManager::getInstance(); diff --git a/src/engine.h b/src/engine.h index ff39cfba..bdf8419a 100644 --- a/src/engine.h +++ b/src/engine.h @@ -30,7 +30,6 @@ extern int camera_x, camera_y; class Graphics; class Map; -class Network; /** * Game engine that does the main drawing. @@ -41,7 +40,7 @@ class Engine /** * Constructor. */ - Engine(Network *network); + Engine(); /** * Destructor. @@ -77,7 +76,6 @@ class Engine bool mShowDebugPath; Map *mCurrentMap; - Network *mNetwork; }; extern Engine *engine; diff --git a/src/game.cpp b/src/game.cpp index b6428103..f83e9c1f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -164,15 +164,15 @@ int get_elapsed_time(int start_time) /** * Create all the various globally accessible gui windows */ -void createGuiWindows(Network *network) +void createGuiWindows() { // Create dialogs - chatWindow = new ChatWindow(network); + chatWindow = new ChatWindow; menuWindow = new MenuWindow(); statusWindow = new StatusWindow(player_node); miniStatusWindow = new MiniStatusWindow(); - buyDialog = new BuyDialog(network); - sellDialog = new SellDialog(network); + buyDialog = new BuyDialog; + sellDialog = new SellDialog; buySellDialog = new BuySellDialog(); inventoryWindow = new InventoryWindow(); npcTextDialog = new NpcTextDialog(); @@ -183,7 +183,7 @@ void createGuiWindows(Network *network) minimap = new Minimap(); equipmentWindow = new EquipmentWindow(player_node->mEquipment.get()); chargeDialog = new ChargeDialog(); - tradeWindow = new TradeWindow(network); + tradeWindow = new TradeWindow; //buddyWindow = new BuddyWindow(); helpWindow = new HelpWindow(); debugWindow = new DebugWindow(); @@ -250,8 +250,7 @@ void destroyGuiWindows() delete debugWindow; } -Game::Game(Network *network): - mNetwork(network), +Game::Game(): mBeingHandler(new BeingHandler()), mBuySellHandler(new BuySellHandler()), mChatHandler(new ChatHandler()), @@ -263,10 +262,10 @@ Game::Game(Network *network): mSkillHandler(new SkillHandler()), mTradeHandler(new TradeHandler()) { - createGuiWindows(network); - engine = new Engine(network); + createGuiWindows(); + engine = new Engine; - beingManager = new BeingManager(network); + beingManager = new BeingManager; floorItemManager = new FloorItemManager(); // Initialize timers @@ -276,7 +275,6 @@ Game::Game(Network *network): // Initialize beings beingManager->setPlayer(player_node); - player_node->setNetwork(network); Joystick::init(); // TODO: The user should be able to choose which one to use @@ -286,16 +284,16 @@ Game::Game(Network *network): joystick = new Joystick(0); } - network->registerHandler(mBeingHandler.get()); - network->registerHandler(mBuySellHandler.get()); - network->registerHandler(mChatHandler.get()); - network->registerHandler(mEquipmentHandler.get()); - network->registerHandler(mInventoryHandler.get()); - network->registerHandler(mItemHandler.get()); - network->registerHandler(mNpcHandler.get()); - network->registerHandler(mPlayerHandler.get()); - network->registerHandler(mSkillHandler.get()); - network->registerHandler(mTradeHandler.get()); + Network::registerHandler(mBeingHandler.get()); + Network::registerHandler(mBuySellHandler.get()); + Network::registerHandler(mChatHandler.get()); + Network::registerHandler(mEquipmentHandler.get()); + Network::registerHandler(mInventoryHandler.get()); + Network::registerHandler(mItemHandler.get()); + Network::registerHandler(mNpcHandler.get()); + Network::registerHandler(mPlayerHandler.get()); + Network::registerHandler(mSkillHandler.get()); + Network::registerHandler(mTradeHandler.get()); } Game::~Game() @@ -374,7 +372,7 @@ void Game::logic() } // Handle network stuff - mNetwork->flush(); + Network::flush(); } } diff --git a/src/game.h b/src/game.h index a44c8970..7330052a 100644 --- a/src/game.h +++ b/src/game.h @@ -31,7 +31,6 @@ #define SPEECH_MAX_TIME 100 class MessageHandler; -class Network; extern std::string map_path; extern volatile int fps; @@ -40,7 +39,7 @@ extern volatile int tick_time; class Game { public: - Game(Network *network); + Game(); ~Game(); void logic(); @@ -48,8 +47,6 @@ class Game void handleInput(); protected: - Network *mNetwork; - typedef std::auto_ptr MessageHandlerPtr; MessageHandlerPtr mBeingHandler; MessageHandlerPtr mBuySellHandler; diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index e7bfef58..63a6e20e 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -42,8 +42,8 @@ #include "../utils/tostring.h" -BuyDialog::BuyDialog(Network *network): - Window("Buy"), mNetwork(network), +BuyDialog::BuyDialog(): + Window("Buy"), mMoney(0), mAmountItems(0), mMaxItems(0) { mShopItems = new ShopItems; diff --git a/src/gui/buy.h b/src/gui/buy.h index b09b648b..0ddea4c4 100644 --- a/src/gui/buy.h +++ b/src/gui/buy.h @@ -30,7 +30,6 @@ #include "../guichanfwd.h" -class Network; class ShopItems; /** @@ -46,7 +45,7 @@ class BuyDialog : public Window, public gcn::ActionListener * * @see Window::Window */ - BuyDialog(Network *network); + BuyDialog(); /** * Destructor @@ -89,7 +88,6 @@ class BuyDialog : public Window, public gcn::ActionListener std::string getElementAt(int i); private: - Network *mNetwork; gcn::Button *mBuyButton; gcn::Button *mQuitButton; gcn::Button *mIncreaseButton; diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index 3db82287..7e0a1a29 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -71,9 +71,8 @@ void CharDeleteConfirm::action(const std::string &eventId, gcn::Widget *widget) ConfirmDialog::action(eventId, widget); } -CharSelectDialog::CharSelectDialog(Network *network, - LockedArray *charInfo): - Window("Select Character"), mNetwork(network), +CharSelectDialog::CharSelectDialog(LockedArray *charInfo): + Window("Select Character"), mCharInfo(charInfo), mCharSelected(false) { mSelectButton = new Button("Ok", "ok", this); @@ -147,7 +146,7 @@ void CharSelectDialog::action(const std::string &eventId, gcn::Widget *widget) { // Start new character dialog mCharInfo->lock(); - new CharCreateDialog(this, mCharInfo->getPos(), mNetwork); + new CharCreateDialog(this, mCharInfo->getPos()); mCharInfo->unlock(); } } @@ -208,7 +207,7 @@ void CharSelectDialog::attemptCharDelete() msg.writeShort(PAMSG_CHAR_DELETE); // TODO: Send the selected slot msg.writeByte(0); - network->send(Network::ACCOUNT, msg); + Network::send(Network::ACCOUNT, msg); mCharInfo->lock(); } @@ -218,7 +217,7 @@ void CharSelectDialog::attemptCharSelect() MessageOut msg; msg.writeShort(PAMSG_CHAR_SELECT); msg.writeByte(mCharInfo->getPos()); - network->send(Network::ACCOUNT, msg); + Network::send(Network::ACCOUNT, msg); mCharInfo->lock(); } @@ -227,8 +226,8 @@ void CharSelectDialog::logic() updatePlayerInfo(); } -CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network): - Window("Create Character", true, parent), mNetwork(network), mSlot(slot) +CharCreateDialog::CharCreateDialog(Window *parent, int slot): + Window("Create Character", true, parent), mSlot(slot) { mNameField = new TextField(""); mNameLabel = new gcn::Label("Name:"); @@ -336,5 +335,5 @@ void CharCreateDialog::attemptCharCreate() outMsg.writeShort(10); // INT outMsg.writeShort(10); // DEX outMsg.writeShort(10); // LUK - network->send(Network::ACCOUNT, outMsg); + Network::send(Network::ACCOUNT, outMsg); } diff --git a/src/gui/char_select.h b/src/gui/char_select.h index e65f400d..73fc8b2d 100644 --- a/src/gui/char_select.h +++ b/src/gui/char_select.h @@ -32,7 +32,6 @@ #include class LocalPlayer; -class Network; class PlayerBox; /** @@ -47,8 +46,7 @@ class CharSelectDialog : public Window, public gcn::ActionListener /** * Constructor. */ - CharSelectDialog(Network *network, - LockedArray *charInfo); + CharSelectDialog(LockedArray *charInfo); void action(const std::string& eventId, gcn::Widget* widget); @@ -57,7 +55,6 @@ class CharSelectDialog : public Window, public gcn::ActionListener void logic(); private: - Network *mNetwork; LockedArray *mCharInfo; gcn::Button *mSelectButton; @@ -97,14 +94,13 @@ class CharCreateDialog : public Window, public gcn::ActionListener /** * Constructor. */ - CharCreateDialog(Window *parent, int slot, Network *network); + CharCreateDialog(Window *parent, int slot); void action(const std::string& eventId, gcn::Widget* widget); std::string getName(); private: - Network *mNetwork; gcn::TextField *mNameField; gcn::Label *mNameLabel; gcn::Button *mNextHairColorButton; diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index e8bb1cc6..04ac3996 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -40,9 +40,8 @@ #include "../net/network.h" #include "../net/protocol.h" -ChatWindow::ChatWindow(Network *network): +ChatWindow::ChatWindow(): Window(""), - mNetwork(network), mTmpVisible(false) { setWindowName("Chat"); @@ -253,7 +252,7 @@ ChatWindow::chatSend(const std::string &nick, std::string msg) MessageOut outMsg; outMsg.writeShort(PGMSG_SAY); outMsg.writeString(msg); - network->send(Network::GAME, outMsg); + Network::send(Network::GAME, outMsg); } else if (msg.substr(0, IS_ANNOUNCE_LENGTH) == IS_ANNOUNCE) { diff --git a/src/gui/chat.h b/src/gui/chat.h index 20841873..a0a3d1ec 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -35,7 +35,6 @@ #include "../guichanfwd.h" class BrowserBox; -class Network; class ScrollArea; #define BY_GM 0 // those should be self-explanatory =) @@ -116,7 +115,7 @@ class ChatWindow : public Window, public gcn::ActionListener, /** * Constructor. */ - ChatWindow(Network *network); + ChatWindow(); /** * Logic (updates components' size) @@ -188,7 +187,6 @@ class ChatWindow : public Window, public gcn::ActionListener, void setVisible(bool visible); private: - Network *mNetwork; bool mTmpVisible; /** One item in the chat log */ diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index e820d42f..3aa7c889 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -44,9 +44,8 @@ #include "../utils/tostring.h" -SellDialog::SellDialog(Network *network): +SellDialog::SellDialog(): Window("Sell"), - mNetwork(network), mMaxItems(0), mAmountItems(0) { mShopItems = new ShopItems(); diff --git a/src/gui/sell.h b/src/gui/sell.h index 423fea26..be5185bd 100644 --- a/src/gui/sell.h +++ b/src/gui/sell.h @@ -31,7 +31,6 @@ #include "../guichanfwd.h" class Item; -class Network; class ShopItems; @@ -48,7 +47,7 @@ class SellDialog : public Window, public gcn::ActionListener * * @see Window::Window */ - SellDialog(Network *network); + SellDialog(); /** * Destructor @@ -76,7 +75,6 @@ class SellDialog : public Window, public gcn::ActionListener void mouseClick(int x, int y, int buton, int count); private: - Network *mNetwork; gcn::Button *mSellButton; gcn::Button *mIncreaseButton; gcn::Button *mDecreaseButton; diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index 73193c88..6b247901 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -45,9 +45,8 @@ #include "../utils/tostring.h" -TradeWindow::TradeWindow(Network *network): +TradeWindow::TradeWindow(): Window("Trade: You"), - mNetwork(network), mMyInventory(new Inventory()), mPartnerInventory(new Inventory()) { diff --git a/src/gui/trade.h b/src/gui/trade.h index eb3c0f97..fe60aac5 100644 --- a/src/gui/trade.h +++ b/src/gui/trade.h @@ -35,7 +35,6 @@ class Inventory; class Item; class ItemContainer; -class Network; class ScrollArea; /** @@ -49,7 +48,7 @@ class TradeWindow : public Window, gcn::ActionListener /** * Constructor. */ - TradeWindow(Network *network); + TradeWindow(); /** * Destructor. @@ -113,8 +112,6 @@ class TradeWindow : public Window, gcn::ActionListener void action(const std::string& eventId, gcn::Widget* widget); private: - Network *mNetwork; - typedef std::auto_ptr InventoryPtr; InventoryPtr mMyInventory; InventoryPtr mPartnerInventory; diff --git a/src/localplayer.h b/src/localplayer.h index fdef6ba1..613f196a 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -34,7 +34,6 @@ class FloorItem; class Inventory; class Item; -class Network; class LocalPlayer : public Player { @@ -47,8 +46,6 @@ class LocalPlayer : public Player virtual ~LocalPlayer(); - void setNetwork(Network *network) { mNetwork = network; } - virtual void logic(); virtual void nextStep(); @@ -145,7 +142,6 @@ class LocalPlayer : public Player std::auto_ptr mInventory; protected: - Network *mNetwork; Being *mTarget; FloorItem *mPickUpTarget; diff --git a/src/main.cpp b/src/main.cpp index 4e65e4fc..573b1a79 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -413,8 +413,8 @@ MapLoginHandler mapLoginHandler; void accountLogin(LoginData *loginData) { logger->log("Username is %s", loginData->username.c_str()); - network->registerHandler(&loginHandler); - network->registerHandler(&charServerHandler); + Network::registerHandler(&loginHandler); + Network::registerHandler(&charServerHandler); loginHandler.setLoginData(loginData); charServerHandler.setLoginData(loginData); charServerHandler.setCharInfo(&charInfo); @@ -424,7 +424,7 @@ void accountLogin(LoginData *loginData) msg.writeLong(0); // client version msg.writeString(loginData->username); msg.writeString(loginData->password); - network->send(Network::ACCOUNT, msg); + Network::send(Network::ACCOUNT, msg); // Clear the password, avoids auto login when returning to login loginData->password = ""; @@ -441,7 +441,7 @@ void accountLogin(LoginData *loginData) void accountRegister(LoginData *loginData) { logger->log("Username is %s", loginData->username.c_str()); - network->registerHandler(&loginHandler); + Network::registerHandler(&loginHandler); loginHandler.setLoginData(loginData); charServerHandler.setLoginData(loginData); charServerHandler.setCharInfo(&charInfo); @@ -452,21 +452,21 @@ void accountRegister(LoginData *loginData) msg.writeString(loginData->username); msg.writeString(loginData->password); msg.writeString(loginData->email); - network->send(Network::ACCOUNT, msg); + Network::send(Network::ACCOUNT, msg); } -void mapLogin(Network *network, LoginData *loginData) +void mapLogin(LoginData *loginData) { - network->registerHandler(&mapLoginHandler); + Network::registerHandler(&mapLoginHandler); // Send connect messages with the magic token to game and chat servers MessageOut gameServerConnect(PGMSG_CONNECT); gameServerConnect.writeString(token, 32); - network->send(Network::GAME, gameServerConnect); + Network::send(Network::GAME, gameServerConnect); MessageOut chatServerConnect(PCMSG_CONNECT); chatServerConnect.writeString(token, 32); - network->send(Network::CHAT, chatServerConnect); + Network::send(Network::CHAT, chatServerConnect); } /** Main */ @@ -533,7 +533,7 @@ int main(int argc, char *argv[]) { logger->error("An error occurred while initializing ENet."); } - network = new Network(); + Network::initialize(); SDL_Event event; @@ -557,9 +557,9 @@ int main(int argc, char *argv[]) } gui->logic(); - network->flush(); + Network::flush(); - if (network->getState() == Network::NET_ERROR) + if (Network::getState() == Network::NET_ERROR) { state = STATE_ERROR; errorMessage = "Got disconnected from server!"; @@ -585,7 +585,7 @@ int main(int argc, char *argv[]) // TODO: Add connect timeout to go back to choose server if (state == STATE_CONNECT_ACCOUNT && - network->isConnected(Network::ACCOUNT)) + Network::isConnected(Network::ACCOUNT)) { if (options.skipUpdate) { state = STATE_LOGIN; @@ -594,8 +594,8 @@ int main(int argc, char *argv[]) } } else if (state == STATE_CONNECT_GAME && - network->isConnected(Network::GAME) && - network->isConnected(Network::CHAT)) + Network::isConnected(Network::GAME) && + Network::isConnected(Network::CHAT)) { // TODO: Somehow send the token state = STATE_GAME; @@ -611,7 +611,7 @@ int main(int argc, char *argv[]) // Disconnect from account server once connected to game server if (oldstate == STATE_CONNECT_GAME && state == STATE_GAME) { - network->disconnect(Network::ACCOUNT); + Network::disconnect(Network::ACCOUNT); } oldstate = state; @@ -627,7 +627,7 @@ int main(int argc, char *argv[]) logger->log("State: CHOOSE_SERVER"); // TODO: Allow changing this using a server choice dialog logger->log("Trying to connect to account server..."); - network->connect(Network::ACCOUNT, + Network::connect(Network::ACCOUNT, loginData.hostname, loginData.port); state = STATE_CONNECT_ACCOUNT; break; @@ -667,7 +667,7 @@ int main(int argc, char *argv[]) case STATE_CHAR_SELECT: logger->log("State: CHAR_SELECT"); - currentDialog = new CharSelectDialog(network, &charInfo); + currentDialog = new CharSelectDialog(&charInfo); if (options.chooseDefault) { ((CharSelectDialog*)currentDialog)->action("ok", NULL); @@ -679,9 +679,9 @@ int main(int argc, char *argv[]) currentDialog = new OkDialog("Error", errorMessage); currentDialog->addActionListener(&errorListener); currentDialog = NULL; // OkDialog deletes itself - network->disconnect(Network::GAME); - network->disconnect(Network::CHAT); - network->clearHandlers(); + Network::disconnect(Network::GAME); + Network::disconnect(Network::CHAT); + Network::clearHandlers(); break; case STATE_CONNECT_GAME: @@ -690,7 +690,7 @@ int main(int argc, char *argv[]) break; case STATE_GAME: - mapLogin(network, &loginData); + mapLogin(&loginData); sound.fadeOutMusic(1000); currentDialog = NULL; @@ -698,7 +698,7 @@ int main(int argc, char *argv[]) login_wallpaper = NULL; logger->log("State: GAME"); - game = new Game(network); + game = new Game; game->logic(); delete game; state = STATE_EXIT; @@ -711,7 +711,7 @@ int main(int argc, char *argv[]) } } - delete network; + Network::finalize(); enet_deinitialize(); if (nullFile) diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp index 1eea29b8..d67949cc 100644 --- a/src/net/charserverhandler.cpp +++ b/src/net/charserverhandler.cpp @@ -174,8 +174,8 @@ CharServerHandler::handleCharSelectResponse(MessageIn &msg) logger->log("Game server: %s:%d", gameServer.c_str(), gameServerPort); logger->log("Chat server: %s:%d", chatServer.c_str(), chatServerPort); - network->connect(Network::GAME, gameServer, gameServerPort); - network->connect(Network::CHAT, chatServer, chatServerPort); + Network::connect(Network::GAME, gameServer, gameServerPort); + Network::connect(Network::CHAT, chatServer, chatServerPort); // Keep the selected character and delete the others player_node = mCharInfo->getEntry(); diff --git a/src/net/messagehandler.cpp b/src/net/messagehandler.cpp index 849b6716..0b5cd87c 100644 --- a/src/net/messagehandler.cpp +++ b/src/net/messagehandler.cpp @@ -27,19 +27,7 @@ #include "network.h" -MessageHandler::MessageHandler(): - mNetwork(0) -{ -} - MessageHandler::~MessageHandler() { - if (mNetwork) - mNetwork->unregisterHandler(this); -} - -void MessageHandler::setNetwork(Network *network) -{ - assert(!(network && mNetwork)); - mNetwork = network; + Network::unregisterHandler(this); } diff --git a/src/net/messagehandler.h b/src/net/messagehandler.h index 9f92636d..b21abd72 100644 --- a/src/net/messagehandler.h +++ b/src/net/messagehandler.h @@ -27,22 +27,15 @@ #include class MessageIn; -class Network; class MessageHandler { public: const Uint16 *handledMessages; - MessageHandler(); virtual ~MessageHandler(); virtual void handleMessage(MessageIn &msg) = 0; - - void setNetwork(Network *network); - - protected: - Network *mNetwork; }; #endif diff --git a/src/net/network.cpp b/src/net/network.cpp index 08b5fe92..e56f6df0 100644 --- a/src/net/network.cpp +++ b/src/net/network.cpp @@ -29,10 +29,25 @@ #include "../log.h" -Network *network; +static Network::State mState; -Network::Network(): - mState(NET_OK) +/** + * The local host. + */ +static ENetHost *mClient; + +/** + * An array holding the peers of the account, game and chat servers. + */ +static ENetPeer *mServers[3]; + +typedef std::map MessageHandlers; +typedef MessageHandlers::iterator MessageHandlerIterator; +static MessageHandlers mMessageHandlers; + +Network::State Network::getState() { return mState; } + +void Network::initialize() { // Initialize server peers for (int i = 0; i < 3; ++i) @@ -48,7 +63,7 @@ Network::Network(): } } -Network::~Network() +void Network::finalize() { clearHandlers(); @@ -110,15 +125,10 @@ Network::disconnect(Server server) void Network::registerHandler(MessageHandler *handler) { - const Uint16 *i = handler->handledMessages; - - while(*i) + for (const Uint16 *i = handler->handledMessages; *i; i++) { mMessageHandlers[*i] = handler; - i++; } - - handler->setNetwork(this); } void @@ -128,30 +138,27 @@ Network::unregisterHandler(MessageHandler *handler) { mMessageHandlers.erase(*i); } - - handler->setNetwork(0); } void Network::clearHandlers() { - MessageHandlerIterator i; - for (i = mMessageHandlers.begin(); i != mMessageHandlers.end(); i++) - { - i->second->setNetwork(0); - } mMessageHandlers.clear(); } bool -Network::isConnected(Server server) const +Network::isConnected(Server server) { return mServers[server] != NULL && mServers[server]->state == ENET_PEER_STATE_CONNECTED; } -void -Network::dispatchMessage(ENetPacket *packet) +/** + * Dispatches a message to the appropriate message handler and + * destroys it afterwards. + */ +static void +dispatchMessage(ENetPacket *packet) { MessageIn msg((const char *)packet->data, packet->dataLength); diff --git a/src/net/network.h b/src/net/network.h index 40255e44..861fa2b3 100644 --- a/src/net/network.h +++ b/src/net/network.h @@ -42,108 +42,79 @@ class MessageOut; class Network { public: - friend class MessageOut; - /** - * Constructor. Sets up the local host. + * Sets up the local host. */ - Network(); + static void + initialize(); /** - * Destructor. + * Closes the connections. */ - ~Network(); + static void + finalize(); - typedef enum { + enum Server { ACCOUNT, GAME, CHAT - } Server; + }; + + enum State { + NET_OK, + NET_ERROR + }; /** * Connects to the given server with the specified address and port. * This method is non-blocking, use isConnected to check whether the * server is connected. */ - bool + static bool connect(Server server, const std::string &address, short port); /** * Disconnects from the given server. */ - void + static void disconnect(Server server); /** * Registers a message handler. A message handler handles a certain * subset of incoming messages. */ - void + static void registerHandler(MessageHandler *handler); /** * Unregisters a message handler. */ - void + static void unregisterHandler(MessageHandler *handler); - void + static void clearHandlers(); - int - getState() const { return mState; } + static State + getState(); /** * Returns whether the given server is connected. */ - bool - isConnected(Server server) const; + static bool + isConnected(Server server); - void + static void flush(); /** - * Send a message to a given server. The server should be connected. + * Sends a message to a given server. The server should be connected. */ - void + static void send(Server server, const MessageOut &msg); - - enum State { - NET_OK, - NET_ERROR - }; - - private: - /** - * The local host. - */ - ENetHost *mClient; - - /** - * An array holding the peers of the account, game and chat servers. - */ - ENetPeer *mServers[3]; - - /** - * Dispatches a message to the appropriate message handler and - * destroys it afterwards. - */ - void - dispatchMessage(ENetPacket *packet); - - unsigned int mToSkip; - - int mState; - - typedef std::map MessageHandlers; - typedef MessageHandlers::iterator MessageHandlerIterator; - MessageHandlers mMessageHandlers; }; /** Convert an address from int format to string */ char *iptostring(int address); -// TODO: remove this global, just a temp solution. -extern Network *network; - #endif diff --git a/src/net/tradehandler.h b/src/net/tradehandler.h index 0b73c871..1ab3c2e4 100644 --- a/src/net/tradehandler.h +++ b/src/net/tradehandler.h @@ -26,8 +26,6 @@ #include "messagehandler.h" -class Network; - class TradeHandler : public MessageHandler { public: diff --git a/src/npc.cpp b/src/npc.cpp index a82490ae..a14b6d24 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -33,8 +33,8 @@ extern Spriteset *npcset; NPC *current_npc = 0; -NPC::NPC(Uint32 id, Uint16 job, Map *map, Network *network): - Being(id, job, map), mNetwork(network) +NPC::NPC(Uint32 id, Uint16 job, Map *map): + Being(id, job, map) { mSprites[BASE_SPRITE] = new AnimatedSprite("graphics/sprites/npc.xml", job-100); } diff --git a/src/npc.h b/src/npc.h index b08c315c..bbc86d9c 100644 --- a/src/npc.h +++ b/src/npc.h @@ -26,12 +26,10 @@ #include "being.h" -class Network; - class NPC : public Being { public: - NPC(Uint32 id, Uint16 job, Map *map, Network *network); + NPC(Uint32 id, Uint16 job, Map *map); virtual Type getType() const; @@ -41,9 +39,6 @@ class NPC : public Being void buy(); void sell(); - - protected: - Network *mNetwork; }; extern NPC *current_npc; -- cgit v1.2.3-70-g09d2 From e8f94fe7ca5e7e7838eaa84f1792b4b42b4bada3 Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Fri, 29 Sep 2006 23:59:08 +0000 Subject: Merged trunk changes from revision 2618 to 2716 into the 0.1.0 branch. --- ChangeLog | 339 ++++++++++++++++++++++++++++++--------- NEWS | 10 +- README | 3 +- data/graphics/images/Makefile.am | 9 +- data/help/changes.txt | 31 ++++ data/help/commands.txt | 1 + data/help/header.txt | 2 +- debian/changelog | 8 + debian/tmw-music.install | 2 + src/Makefile.am | 3 + src/animatedsprite.cpp | 87 +++++++--- src/animatedsprite.h | 16 +- src/animation.cpp | 33 +++- src/animation.h | 16 ++ src/being.cpp | 25 +-- src/beingmanager.cpp | 29 +++- src/beingmanager.h | 19 ++- src/engine.cpp | 4 +- src/floor_item.cpp | 4 +- src/game.cpp | 77 ++++++--- src/game.h | 17 +- src/gui/buy.cpp | 47 +++--- src/gui/buy.h | 12 +- src/gui/char_select.cpp | 22 +++ src/gui/char_select.h | 2 + src/gui/equipmentwindow.cpp | 4 +- src/gui/gui.cpp | 13 ++ src/gui/inventorywindow.cpp | 58 ++++--- src/gui/inventorywindow.h | 20 ++- src/gui/itemcontainer.cpp | 35 +++- src/gui/itemcontainer.h | 35 +++- src/gui/listbox.cpp | 57 ++++++- src/gui/listbox.h | 41 ++++- src/gui/minimap.cpp | 4 +- src/gui/playerbox.cpp | 2 +- src/gui/popupmenu.cpp | 2 +- src/gui/selectionlistener.h | 78 +++++++++ src/gui/sell.cpp | 40 +++-- src/gui/sell.h | 13 +- src/gui/setup.cpp | 4 +- src/gui/setup_video.cpp | 52 +++++- src/gui/setup_video.h | 4 + src/gui/trade.cpp | 63 ++++---- src/gui/trade.h | 10 +- src/gui/updatewindow.cpp | 18 ++- src/gui/updatewindow.h | 5 + src/gui/window.cpp | 12 +- src/item.h | 2 +- src/localplayer.h | 7 +- src/main.cpp | 108 +++++++------ src/map.cpp | 24 ++- src/net/inventoryhandler.cpp | 11 +- src/resources/image.cpp | 21 ++- src/resources/image.h | 7 + src/resources/iteminfo.cpp | 31 ++-- src/resources/iteminfo.h | 34 ++-- src/resources/itemmanager.cpp | 9 +- src/resources/itemmanager.h | 8 +- src/tmw.rc | 8 +- tools/Reorganize.java | 128 ++++++++++----- 60 files changed, 1336 insertions(+), 450 deletions(-) create mode 100644 src/gui/selectionlistener.h (limited to 'src/gui/sell.h') diff --git a/ChangeLog b/ChangeLog index aa54e32e..33fab8df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,148 @@ -2006-08-30 Yohann Ferreira +2006-09-28 Björn Steinbrink + + * src/map.cpp: Fix random crashes when map tiles are missing. + +2006-09-28 Bjørn Lindeijer + + * data/graphics/maps/new_2-1.tmx.gz: Matt Howe fixed up cave map. + +2006-09-26 Eugenio Favalli + + * data/graphics/maps/new_6-1.tmx.gz: Alderan fixed a map issue. + +2006-09-25 Bjørn Lindeijer + + * data/graphics/sprites/hairstyle*.png, + data/graphics/sprites/hairstyle*.xml, tools/Reorganize.java: Removed + unused frames from the hairsets. + * src/resources/image.h: Defined NO_SDL_GLEXT to prevent a + redefinition when gl.h also tries to define OpenGL extensions (patch + accepted from Rogier Polak). + +2006-09-23 Bjørn Lindeijer + + * data/maps/new_5-1.tmx.gz: Accepted new version by Matt Howe, fixing + several mapping issues. + +2006-09-21 Eugenio Favalli + + * data/graphics/tiles/Makefile.am: Added missing tileset. + * src/gui/updatewindow.cpp, src/gui/updatewindow.h: Made canceling the + update process non-blocking (Patch by VictorSan). + +2006-09-21 Philipp Sehmisch + + * src/animation.cpp, src/animation.h, src/animatedsprite.cpp, + src/animatedsprite.h: Removed some obsolete code and implemented + the posibility to define an token in the s + that allows to define an animation that doesn't loop and returns + to the STAND animation when finished. + * data/graphics/sprites/hairstyle*.xml, + data/graphics/sprites/item0*.xml, + data/graphics/sprites/monster*.xml, + data/graphics/sprites/weapons.xml: Used the token for all + attack animations fixing the problem with looping monster attack + animations. + +2006-09-20 Philipp Sehmisch + + * data/graphics/items/generic-whitefur.png, + data/graphics/items/generic-cavesnakelamp.png, + data/graphics/items/generic-hardspike.png, + data/graphics/items/generic-pinkantennae.png, + data/graphics/items/Makefile.am, data/items.xml: Added drops for new + monsters. + * src/gui/setup.cpp, src/gui/setup_video.cpp, + src/gui/setup_video.h: Added a slider for controlling the overlay + detail to the video setup dialog based on a patch by VictorSan. + * data/maps/new_14-1.tmx.gz, data/maps/new_16-1.tmx.gz: Added cloud + effect and minimap. + * data/images/Makefile.am: Updated makefile. + +2006-09-19 Bjørn Lindeijer + + * data/graphics/sprites/Makefile.am: Added missing monster19 sprite. + +2006-09-17 Eugenio Favalli + + * data/maps/Makefile.am: Added missing maps. + * data/maps/new_10-1.tmx.gz: Disabled layer compression. + +2006-09-18 Philipp Sehmisch + + * data/maps/new_9-1.tmx.gz: Fixed some mapping bugs (new walkmap + required). + +2006-09-17 Eugenio Favalli + + * data/maps/new_10-1.tmx.gz: Fixed transparent snow issue (Fix by + Pajarico). + +2006-09-17 Björn Steinbrink + + * src/game.cpp: Stop using the sticky window attribute which is + unneeded for the current implementation, instead adjust the set of + affected windows by the 'hide' shortcut. + +2006-09-17 Philipp Sehmisch + + * data/maps/new_14-1.tmx.gz, data/maps/new_15-1.tmx.gz, + data/maps/new_16-1.tmx.gz: fixed some mapping errors. + +2006-09-16 Philipp Sehmisch + + * src/animatedsprite.cpp, src/animatedsprite.h: Fixed the crash when + attacking without a weapon, some additional stability improvements and + more descriptive variable names in the parsing algorithmn. + +2006-09-16 Eugenio Favalli + + * data/help/changes.txt, data/help/header.txt, NEWS, README, + src/tmw.rc: Updated release infos. + +2006-09-14 Philipp Sehmisch + + * src/animation.h, src/animatedsprite.h, + data/graphics/sprites/weapon.xml: Some modifications at the animation + system. No more "undefined action foo" warnings in the tmw.log. Not + visible actions must now be declared explicitely. + * data/graphics/images/ambient/sandstorm.png, + data/graphics/images/ambient/clouds.png: Improved quality of the overlay + graphics. + +2006-09-14 Björn Steinbrink + + * src/gui/char_select.cpp: Remove debug output. + * src/gui/char_select.cpp, src/main.cpp: Fix the character name + matching loop and add support for saving the last used character + (based on a patch by Andrew Harrison). + * src/gui/char_select.cpp, src/gui/char_select.h, src/main.cpp: Clean + up the player selection stuff, it's a bit nicer now. + * src/main.cpp: Fix up the player selection command line option. + +2006-09-13 Yohann Ferreira * src/Makefile.am, src/gui/widgets, src/gui/widgets/dropdown.h, src/gui/widgets/dropdown.cpp, src/gui/serverdialog.h, src/gui/serverdialog.cpp: Added a reusable skinned dropdown widget in the new widgets folder. Other widgets will be be moved there later. +2006-09-12 Bjørn Lindeijer + + * src/game.cpp, src/game.h: Simplified fps limiting a bit and added + some comments. Now based on ConfigListener so that the fpslimit option + doesn't need to be queried the whole time. + * NEWS: Updated with some items. + +2006-09-11 Eugenio Favalli + + * src/game.cpp: Fixed more fps issues. + +2006-09-09 Bjørn Lindeijer + + * src/gui/gui.cpp: Removed easy targeting functionality since it + interferes with walking around too much. Targeting can still be rather + conveniently done with 'a' or the middle mouse button. 2006-09-09 Guillaume Melquiond @@ -13,6 +151,72 @@ * src/localplayer.h, src/being.cpp, src/net/beinghandler.cpp, src/being.h: Fitted being trajectories to synchronization messages. +2006-09-07 Björn Steinbrink + + * src/resources/image.cpp: Fixed a typo. + * src/resources/image.cpp: Worked around a memory leak when using + OpenGL. + +2006-09-06 Philipp Sehmisch + + * data/graphics/sprites/item010.png, data/graphics/sprites/item010.xml, + data/graphics/sprites/Makefile.am: Added santa hat sprites and updated + makefile. + +2006-09-06 Eugenio Favalli + + * src/game.cpp, src/gui/setup_video.cpp, src/main.cpp: Fixed fps + limiter issues and increased default limit to 60. + * src/game.cpp: Fixed fps limiter when disabled. + +2006-09-05 Philipp Sehmisch + * data/graphics/tiles/Woodland_ground.png, + data/graphics/tiles/Woodland_x2.png, + data/graphics/tiles/Woodland_x3.png: Some minor improvements and + additions at my tilesets. + * data/graphics/sprites/monster0.xml, + data/graphics/sprites/monster1.xml, + data/graphics/sprites/monster2.xml, + data/graphics/sprites/monster3.xml, + data/graphics/sprites/monster4.xml, + data/graphics/sprites/monster5.xml, + data/graphics/sprites/monster6.xml, + data/graphics/sprites/monster8.xml, + data/graphics/sprites/monster9.xml, + data/graphics/sprites/monster11.xml, + data/graphics/sprites/monster13.xml, + data/graphics/sprites/monster0.xml: Adjusted the animation speed of + several monsters. + +2006-09-03 Bjørn Lindeijer + + * src/floor_item.cpp, src/gui/equipmentwindow.cpp, src/gui/sell.cpp, + src/gui/trade.cpp, src/gui/inventorywindow.h, + src/gui/selectionlistener.h, src/gui/itemcontainer.h, + src/gui/inventorywindow.cpp, src/gui/buy.cpp, + src/gui/itemcontainer.cpp, src/gui/popupmenu.cpp, src/item.h, + src/net/inventoryhandler.cpp, src/Makefile.am, + src/resources/itemmanager.h, src/resources/iteminfo.cpp, + src/resources/iteminfo.h, src/resources/itemmanager.cpp: Introduced + SelectionListener to fix updating problem in inventory window (should + also be used to fix similar problem in trade, buy and sell dialogs). + Made the ItemInfo be passed around as a reference instead of a pointer, + since it is never NULL. + * src/gui/trade.cpp, src/gui/trade.h: Fixed updating of labels in + trade window. + * src/gui/sell.cpp, src/gui/listbox.h, src/gui/inventorywindow.h, + src/gui/buy.h, src/gui/buy.cpp, src/gui/sell.h, src/gui/listbox.cpp: + Fixed updating of labels in buy and sell dialogs. Also made our + listbox respond to mouse dragging to change the selection. + +2006-09-02 Bernard Lidicky + + * src/game.cpp, src/beingmanager.h, src/gui/gui.cpp, + src/beingmanager.cpp, src/localplayer.h, README, + data/help/commands.txt, NEWS: Added targeting nearest monster with + either keyboard or mouse. Also made clicking beings in general a bit + easier (patch applied by Bjørn Lindeijer). + 2006-09-02 Bjørn Lindeijer * src/gui/serverdialog.cpp, src/main.cpp: Fixed crash when using short @@ -32,10 +236,22 @@ 2006-09-01 Eugenio Favalli + * data/graphics/sprites/monster19.png, + data/graphics/sprites/monster19.xml, data/graphics/tiles/arena.png, + data/graphics/tiles/cave.png, data/maps/new_17-1.tmx.gz, + data/maps/new_6-1.tmx.gz: Added new big cave map, lamp-snake monster, + improved arena map. * src/gui/serverdialog.cpp, src/gui/serverdialog.h, src/net/network.h: Fixed some header issues. * The Mana World.dev, tmw.cbp: Updated project files. +2006-08-30 Philipp Sehmisch + + * data/graphics/sprites/item007.png, + data/graphics/sprites/item007.xml, data/graphics/sprites/item009.png, + data/graphics/sprites/item009.xml: + Added sprites for miners helm and standard headband. + 2006-08-30 Yohann Ferreira * src/main.cpp, src/main.h, src/Makefile.am, src/gui/connection.h, @@ -44,17 +260,29 @@ with an unskinned dropdown. Upgraded also the connection window a bit to handle Cancelling more gracefully. -2006-08-27 Guillaume Melquiond +2006-08-29 Bjørn Lindeijer - * src/engine.cpp, src/gui/gui.cpp: Fixed merge issues: printfs and - inconsistency between view and camera variables. Fixed lazy scrolling: - there is no "freaking out" when the correct function is used. + * src/map.cpp, src/beingmanager.h, src/gui/minimap.cpp, + src/engine.cpp, src/beingmanager.cpp: It's better to use a reference + when you don't need a pointer. + * NEWS: Updated with addition of config file option. -2006-08-28 Bjørn Lindeijer +2006-08-29 Andrew Harrison - * src/gui/gui.cpp: Fixed crash when map is not loaded yet. - * src/net/beinghandler.cpp, src/net/protocol.h: Added support for - entering monsters. + * src/main.cpp: Added command line option to specify which + configuration file to use (patch applied by Bjørn Lindeijer). + +2006-08-29 Matthias Hartmann + + * data/graphics/sprites/item006.png, + data/graphics/sprites/item006.xml, data/graphics/sprites/item008.xml: + Fixed fancy hat + silk headband positions. + +2006-08-29 Philipp Sehmisch + + * data/graphics/sprites/item008.png, + data/graphics/sprites/item008.xml, data/graphics/sprites/Makefile.am: + Added fancy hat sprite. 2006-08-28 Philipp Sehmisch @@ -70,6 +298,12 @@ data/graphics/sprites/item006.xml, data/graphics/sprites/Makefile.am: Added headband and fixed svn properties. +2006-08-28 Bjørn Lindeijer + + * src/gui/gui.cpp: Fixed crash when map is not loaded yet. + * src/net/beinghandler.cpp, src/net/protocol.h: Added support for + entering monsters. + 2006-08-27 Guillaume Melquiond * src/localplayer.cpp, src/net/protocol.h: Send move message @@ -89,11 +323,14 @@ src/monster.cpp, src/player.h: Cleaned the logic members. * src/engine.cpp, src/localplayer.cpp, src/gui/gui.cpp, src/being.cpp, src/being.h: Implemented pixel-grained movements. + * src/engine.cpp, src/gui/gui.cpp: Fixed merge issues: printfs and + inconsistency between view and camera variables. Fixed lazy scrolling: + there is no "freaking out" when the correct function is used. 2006-08-27 Bjørn Lindeijer - * src/net/inventoryhandler.cpp: Applied patch by AHarrison that adds - item pickup messages to the chat window. + * src/net/inventoryhandler.cpp: Applied patch by Andrew Harrison that + adds item pickup messages to the chat window. * NEWS: Updated with some recently added and fixed issues. Doesn't mention any of the recent content updates yet. * src/localplayer.cpp, src/gui/sell.cpp, src/gui/trade.cpp, @@ -173,7 +410,7 @@ * data/help/commands.txt, README, src/game.cpp, src/gui/chat.cpp, src/gui/window.cpp, src/gui/window.h: Added support for sticky windows - as discussed with doener. Patch by AHarrison. + as discussed with doener. Patch by Andrew Harrison. * data/items.xml: Added jeans shorts. 2006-08-24 Philipp Sehmisch @@ -235,11 +472,11 @@ 2006-08-20 Yohann Ferreira - * data/graphics/sprites/Makefile.am : Following the splitting from + * data/graphics/sprites/Makefile.am: Following the splitting from Philipp, moved out the items.png file from the Makefile.am. - * debian/control, debian/tmw-data.install : Updated debian package + * debian/control, debian/tmw-data.install: Updated debian package creation process. - * src/Makefile.am : Added iteminfo.cpp to avoid an undefined reference + * src/Makefile.am: Added iteminfo.cpp to avoid an undefined reference with gcc 4.1.2. Happy to be back :) 2006-08-20 Bjørn Lindeijer @@ -288,13 +525,13 @@ * src/itemmanager.cpp, data/items.xml: Replaced indices on the item spriteset with filenames. added names and descriptions for all missing items. Changed names and dascriptions of some items. - * src/engine.cpp: removed global item spriteset. + * src/engine.cpp: Removed global item spriteset. * src/floor_item.cpp, src/floor_item.h, src/iteminfo.cpp, src/iteminfo.h, src/equipmentwindow.cpp, src/equipmentwindow.h, - src/itemcontainer.cpp, src/itemcontainer.h: the iteminfo class now + src/itemcontainer.cpp, src/itemcontainer.h: The iteminfo class now provides a pointer to the item icon image instead of providing the index on the item spriteset. - * data/graphics/tiles/trans_desert-woodland.png: added transmission + * data/graphics/tiles/trans_desert-woodland.png: Added transmission tileset between desert and woodland. 2006-08-15 Bjørn Lindeijer @@ -527,8 +764,8 @@ char server selection dialog, and added character visualization in character selection dialog. * data/graphics/sprites/Makefile.am, data/graphics/tiles/Makefile.am, - data/maps/Makefile.am, data/maps/new_13-1.tmx.gz: Added map with inside - of snow village buildings and fixed makefiles. + data/maps/Makefile.am, data/maps/new_13-1.tmx.gz: Added map with + inside of snow village buildings and fixed makefiles. * src/being.cpp, src/being.h, src/player.cpp: Fixed direction and action issues when changing appeareance, frames are still out of sync. * data/maps/Makefile.am, data/maps/new_14-1.tmx.gz, @@ -704,8 +941,8 @@ 2006-07-12 Frode Lindeijer - * /tmw/trunk/data/graphics/sprites/item001.png: Completed the cotton - shirt equipment graphic. + * data/graphics/sprites/item001.png: Completed the cotton shirt + equipment graphic. 2006-07-06 Philipp Sehmisch @@ -755,68 +992,20 @@ * src/being.h, src/being.cpp, src/npc.cpp, src/npc.h, src/monster.cpp, src/monster.h: Moved all drawing code from the Being based classes into Being. - * data/graphics/sprites/monster0.png, - data/graphics/sprites/monster1.png, - data/graphics/sprites/monster2.png, - data/graphics/sprites/monster3.png, - data/graphics/sprites/monster4.png, - data/graphics/sprites/monster5.png, - data/graphics/sprites/monster6.png, - data/graphics/sprites/monster7.png, - data/graphics/sprites/monster8.png, - data/graphics/sprites/monster9.png, - data/graphics/sprites/monster10.png, - data/graphics/sprites/monster11.png, - data/graphics/sprites/monster12.png, - data/graphics/sprites/monster13.png, - data/graphics/sprites/monster14.png, - data/graphics/sprites/monster15.png, - data/graphics/sprites/monster16.png, - data/graphics/sprites/monster17.png: Resized and reorganized the + * data/graphics/sprites/monster*.png: Resized and reorganized the monster spritesets to fit the new animation system (thanks, Bjørn). - * data/graphics/sprites/monster0.xml, - data/graphics/sprites/monster1.xml, - data/graphics/sprites/monster2.xml, - data/graphics/sprites/monster3.xml, - data/graphics/sprites/monster4.xml, - data/graphics/sprites/monster5.xml, - data/graphics/sprites/monster6.xml, - data/graphics/sprites/monster7.xml, - data/graphics/sprites/monster8.xml, - data/graphics/sprites/monster9.xml, - data/graphics/sprites/monster10.xml, - data/graphics/sprites/monster11.xml, - data/graphics/sprites/monster12.xml, - data/graphics/sprites/monster13.xml, - data/graphics/sprites/monster14.xml, - data/graphics/sprites/monster15.xml, - data/graphics/sprites/monster16.xml, - data/graphics/sprites/monster17.xml: Added animation files for all + * data/graphics/sprites/monster*.xml: Added animation files for all monsters. * src/animation.cpp: The offset values of the Frames of animated sprites are now modified so every frame is drawn centered. - * data/graphics/sprites/hairstyle0.xml, - data/graphics/sprites/hairstyle1.xml, - data/graphics/sprites/hairstyle2.xml, - data/graphics/sprites/hairstyle3.xml, - data/graphics/sprites/hairstyle4.xml, - data/graphics/sprites/hairstyle5.xml, - data/graphics/sprites/hairstyle6.xml, - data/graphics/sprites/hairstyle7.xml: Retuned the offsets of the hair - sprites. + * data/graphics/sprites/hairstyle*.xml: Retuned the offsets of the + hair sprites. * src/animation.cpp: Small stability fix. * src/being.cpp, src/being.h: weapon animation now uses the new animation system. * data/graphics/sprites/player_male_base.xml data/graphics/sprites/player_female_base.xml - data/graphics/sprites/hairstyle0.xml, - data/graphics/sprites/hairstyle1.xml, - data/graphics/sprites/hairstyle2.xml, - data/graphics/sprites/hairstyle3.xml, - data/graphics/sprites/hairstyle4.xml, - data/graphics/sprites/hairstyle5.xml, - data/graphics/sprites/hairstyle6.xml, - data/graphics/sprites/hairstyle7.xml: Tuned walk speed and added bow + data/graphics/sprites/hairstyle*.xml: Tuned walk speed and added bow animations. 2006-07-03 Eugenio Favalli diff --git a/NEWS b/NEWS index cf837a25..2b77dca3 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1,18 @@ -0.0.21 (.. September 2006) +0.0.21 (17 September 2006) - Added item pickup messages to the chat dialog - Added XP bar to ministatus in the top left - Added configurable smooth and lazy scrolling - Added option to turn off the joystick -- Added --playername command line option for automatic character picking +- Added --playername option for automatic character picking +- Added --configfile option for specifying which configuration file to use +- Added shortcut and middle mouse button for targetting nearest monster +- Added support for map effect overlays +- Fixed FPS limiter - Fixed updating system on Windows - Fixed player animations going out of sync on changing equipment or hairstyle - Fixed SDL_image configure check on some systems by first checking for libpng +- Fixed big memory leak when using OpenGL +- Updated to work with Guichan 0.5.0 (older versions no longer supported) 0.0.20 (24 July 2006) - Added new hairstyle, and some fixes to the old ones diff --git a/README b/README index 5fad4312..0313fac3 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ THE MANA WORLD ============== - Version: 0.0.20 Date: 23/07/2006 + Version: 0.0.21 Date: 17/09/2006 Development team: @@ -53,6 +53,7 @@ Use arrow keys to move around. Other keys: - Alt + S sit down / stand up - Alt + F toggle debug pathfinding feature - Alt + P take screenshot +- A target nearest monster - H hide all non-sticky windows - G or Z pick up item - Enter focus chat window / send message diff --git a/data/graphics/images/Makefile.am b/data/graphics/images/Makefile.am index e0707698..fb54cb95 100644 --- a/data/graphics/images/Makefile.am +++ b/data/graphics/images/Makefile.am @@ -7,7 +7,12 @@ images_DATA = \ minimap_new_1-1.png \ minimap_new_2-1.png \ minimap_new_3-1.png \ - minimap_new_5-1.png + minimap_new_5-1.png \ + minimap_new_7-1.png \ + minimap_new_9-1.png \ + minimap_new_14-1.png \ + minimap_new_15-1.png \ + minimap_new_16-1.png EXTRA_DIST = \ - $(images_DATA) + $(images_DATA) \ No newline at end of file diff --git a/data/help/changes.txt b/data/help/changes.txt index 2d0f9d86..f8a3eb67 100644 --- a/data/help/changes.txt +++ b/data/help/changes.txt @@ -3,6 +3,37 @@ ##3 === RECENT CHANGES === + 0.0.21 (17 September 2006) + - Added item pickup messages to the chat dialog + - Added XP bar to ministatus in the top left + - Added configurable smooth and lazy scrolling + - Added option to turn off the joystick + - Added --playername option for automatic character picking + - Added --configfile option for specifying which configuration file to use + - Added shortcut and middle mouse button for targetting nearest monster + - Added support for map effect overlays + - Fixed FPS limiter + - Fixed updating system on Windows + - Fixed player animations going out of sync on changing equipment or hairstyle + - Fixed SDL_image configure check on some systems by first checking for libpng + - Fixed big memory leak when using OpenGL + - Updated to work with Guichan 0.5.0 (older versions no longer supported) + + 0.0.20 (24 July 2006) + - Added new hairstyle, and some fixes to the old ones + - Added slider to set FPS limit + - Added visible equipments + - Added new maps and monsters + - Added female characters + - Implemented a new animation system + - Updated the updating system + - Reduced size of textures to stay within the limits of some OpenGL drivers + - Fixed connection not being shut down completely in case of an error + - Fixed min size of a window when resizing + - Fixed some maps issues + - Some fixes to monsters and player graphics + - Minor bug fixes and lots of code cleanups + 0.0.19 (6 March 2006) - Added --username, --password and --defaults command line options diff --git a/data/help/commands.txt b/data/help/commands.txt index 37c77df2..ab93b54e 100644 --- a/data/help/commands.txt +++ b/data/help/commands.txt @@ -23,6 +23,7 @@ ##2Alt + S##P sit down / stand up ##2Alt + F##P toggle debug pathfinding feature ##2Alt + P##P take screenshot + ##2A##P target nearest monster ##2H##P hide all non-sticky windows ##2G or Z##P pick up item ##2Enter##P focus chat window / send message diff --git a/data/help/header.txt b/data/help/header.txt index d9188a3b..30c1dc93 100644 --- a/data/help/header.txt +++ b/data/help/header.txt @@ -2,7 +2,7 @@ ##1 T H E M A N A W O R L D ##1 ========================================== - ##2Version:##6 0.0.20 ##2Date:##6 23 July 2006 + ##2Version:##6 0.0.21 ##2Date:##6 17 September 2006 ##2 Website: http://themanaworld.org diff --git a/debian/changelog b/debian/changelog index eb420daf..5e71e51e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +tmw (0.0.21-1) unstable; urgency=low + + * New upstream release: + * Now linked against libguichan-0.5.0. + * Readded the correct music package. + + -- FERREIRA Yohann Wed, 27 Sep 2006 21:40:33 +0200 + tmw (0.0.20-1) unstable; urgency=low * Make use of a own desktop file for the Debian Package. Close the missing icon bug. diff --git a/debian/tmw-music.install b/debian/tmw-music.install index b3494726..b4a17199 100644 --- a/debian/tmw-music.install +++ b/debian/tmw-music.install @@ -1 +1,3 @@ data/music/*.ogg usr/share/games/tmw/data/music +data/music/*.mp3 usr/share/games/tmw/data/music + diff --git a/src/Makefile.am b/src/Makefile.am index 01f8a3b2..b621c63e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,6 +2,8 @@ AUTOMAKE_OPTIONS = subdir-objects bin_PROGRAMS = tmw tmw_SOURCES = graphic/imagerect.h \ + gui/widgets/dropdown.cpp \ + gui/widgets/dropdown.h \ gui/browserbox.cpp \ gui/browserbox.h \ gui/buddywindow.cpp \ @@ -77,6 +79,7 @@ tmw_SOURCES = graphic/imagerect.h \ gui/register.h \ gui/scrollarea.cpp \ gui/scrollarea.h \ + gui/selectionlistener.h \ gui/sell.cpp \ gui/sell.h \ gui/serverdialog.cpp \ diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp index f984d13f..3815f04a 100644 --- a/src/animatedsprite.cpp +++ b/src/animatedsprite.cpp @@ -18,7 +18,7 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: animation.cpp 2430 2006-07-24 00:13:24Z b_lindeijer $ + * $Id$ */ #include "animatedsprite.h" @@ -90,14 +90,9 @@ AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant): // get action else if (xmlStrEqual(node->name, BAD_CAST "action")) { - std::string name = getProperty(node, "name", ""); + std::string actionName = getProperty(node, "name", ""); std::string imageset = getProperty(node, "imageset", ""); - if (name.empty()) - { - logger->log("Warning: unnamed action in %s", - animationFile.c_str()); - } if (mSpritesets.find(imageset) == mSpritesets.end()) { logger->log("Warning: imageset \"%s\" not defined in %s", imageset.c_str(), @@ -107,10 +102,25 @@ AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant): continue; } - Action *action = new Action(); + SpriteAction actionType = makeSpriteAction(actionName); + if (actionType == ACTION_INVALID) + { + logger->log("Warning: Unknown action \"%s\" defined in %s", + actionName.c_str(), + animationFile.c_str()); + continue; + } + Action *action = new Action(); action->setSpriteset(mSpritesets[imageset]); - mActions[makeSpriteAction(name)] = action; + mActions[actionType] = action; + + // When first action set it as default direction + if (mActions.empty()) + { + mActions[ACTION_DEFAULT] = action; + } + // get animations for (xmlNodePtr animationNode = node->xmlChildrenNode; @@ -121,9 +131,20 @@ AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant): if (!xmlStrEqual(animationNode->name, BAD_CAST "animation")) continue; - std::string dir = getProperty(animationNode, "direction", ""); + std::string directionName = getProperty(animationNode, "direction", ""); + + SpriteDirection directionType = makeSpriteDirection(directionName); + if (directionType == DIRECTION_INVALID) + { + logger->log("Warning: Unknown direction \"%s\" defined for action %s in %s", + directionName.c_str(), + actionName.c_str(), + animationFile.c_str()); + continue; + } + Animation *animation = new Animation(); - action->setAnimation(makeSpriteDirection(dir), animation); + action->setAnimation(directionType, animation); // Get animation phases for (xmlNodePtr phaseNode = animationNode->xmlChildrenNode; @@ -156,12 +177,17 @@ AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant): start++; } } + else if (xmlStrEqual(phaseNode->name, BAD_CAST "end")) + { + animation->addTerminator(); + }; } // for phaseNode } // for animationNode } // if "" else if "" } // for node // Complete missing actions + substituteAction(ACTION_STAND, ACTION_DEFAULT); substituteAction(ACTION_WALK, ACTION_STAND); substituteAction(ACTION_WALK, ACTION_RUN); substituteAction(ACTION_ATTACK, ACTION_STAND); @@ -247,7 +273,7 @@ AnimatedSprite::reset() } void -AnimatedSprite::play(SpriteAction action, int time) +AnimatedSprite::play(SpriteAction action) { ActionIterator i = mActions.find(action); @@ -262,31 +288,31 @@ AnimatedSprite::play(SpriteAction action, int time) if (mAction != i->second) { mAction = i->second; - mLastTime = 0; - } - - if (!mAction || !time) - mSpeed = 1.0f; - else { - int animationLength = mAction->getAnimation(mDirection)->getLength(); - mSpeed = (float) animationLength / time; + //mAction->reset(); } } void AnimatedSprite::update(int time) { + bool notFinished = true; // Avoid freaking out at first frame or when tick_time overflows if (time < mLastTime || mLastTime == 0) mLastTime = time; - // If not enough time have passed yet, do nothing + // If not enough time has passed yet, do nothing if (time > mLastTime && mAction) { Animation *animation = mAction->getAnimation(mDirection); - animation->update((unsigned int)((time - mLastTime) * mSpeed)); + if (animation != NULL) { + notFinished = animation->update((unsigned int)(time - mLastTime));} mLastTime = time; } + + if (!notFinished) + { + play(ACTION_STAND); + } } bool @@ -296,6 +322,8 @@ AnimatedSprite::draw(Graphics* graphics, Sint32 posX, Sint32 posY) const return false; Animation *animation = mAction->getAnimation(mDirection); + if (animation == NULL) return false; + int phase = animation->getCurrentPhase(); if (phase < 0) return false; @@ -322,6 +350,9 @@ AnimatedSprite::getHeight() const SpriteAction AnimatedSprite::makeSpriteAction(const std::string& action) { + if (action == "" || action == "default") { + return ACTION_DEFAULT; + } if (action == "stand") { return ACTION_STAND; } @@ -365,14 +396,17 @@ AnimatedSprite::makeSpriteAction(const std::string& action) return ACTION_DEAD; } else { - return ACTION_DEFAULT; + return ACTION_INVALID; } } SpriteDirection AnimatedSprite::makeSpriteDirection(const std::string& direction) { - if (direction == "up") { + if (direction == "" || direction == "default") { + return DIRECTION_DEFAULT; + } + else if (direction == "up") { return DIRECTION_UP; } else if (direction == "left") { @@ -381,7 +415,10 @@ AnimatedSprite::makeSpriteDirection(const std::string& direction) else if (direction == "right") { return DIRECTION_RIGHT; } - else { + else if (direction == "down") { return DIRECTION_DOWN; } + else { + return DIRECTION_INVALID; + }; } diff --git a/src/animatedsprite.h b/src/animatedsprite.h index b73bdb5c..bda612ab 100644 --- a/src/animatedsprite.h +++ b/src/animatedsprite.h @@ -18,7 +18,7 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: animation.h 2430 2006-07-24 00:13:24Z b_lindeijer $ + * $Id$ */ #ifndef _TMW_ANIMATEDSPRITE_H @@ -50,15 +50,18 @@ enum SpriteAction ACTION_SIT, ACTION_SLEEP, ACTION_HURT, - ACTION_DEAD + ACTION_DEAD, + ACTION_INVALID }; enum SpriteDirection { - DIRECTION_DOWN = 0, + DIRECTION_DEFAULT = 0, + DIRECTION_DOWN, DIRECTION_UP, DIRECTION_LEFT, - DIRECTION_RIGHT + DIRECTION_RIGHT, + DIRECTION_INVALID }; /** @@ -85,11 +88,10 @@ class AnimatedSprite reset(); /** - * Plays an action using the current direction that will have a - * duration of the specified time, 0 means default. + * Plays an action using the current direction */ void - play(SpriteAction action, int time = 0); + play(SpriteAction action); /** * Inform the animation of the passed time so that it can output the diff --git a/src/animation.cpp b/src/animation.cpp index c1b27ebd..98a4abb8 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -39,45 +39,68 @@ Animation::reset() iCurrentPhase = mAnimationPhases.begin(); } -void + +bool Animation::update(unsigned int time) { mTime += time; if (mAnimationPhases.empty()) - return; + return true; + if (isTerminator(*iCurrentPhase)) + return false; unsigned int delay = iCurrentPhase->delay; - if (!delay) - return; while (mTime > delay) { + if (!delay) + return true; mTime -= delay; iCurrentPhase++; if (iCurrentPhase == mAnimationPhases.end()) { iCurrentPhase = mAnimationPhases.begin(); } + if (isTerminator(*iCurrentPhase)) + return false; + delay = iCurrentPhase->delay; } + return true; } + int Animation::getCurrentPhase() const { return mAnimationPhases.empty() ? -1 : iCurrentPhase->image; } + void Animation::addPhase(int image, unsigned int delay, int offsetX, int offsetY) { //add new phase to animation list - AnimationPhase newPhase = { image, delay, offsetX, offsetY }; + AnimationPhase newPhase = { image, delay, offsetX, offsetY}; mAnimationPhases.push_back(newPhase); //reset animation circle iCurrentPhase = mAnimationPhases.begin(); } +void +Animation::addTerminator() +{ + AnimationPhase terminator = { -1, 0, 0, 0}; + mAnimationPhases.push_back(terminator); + iCurrentPhase = mAnimationPhases.begin(); +} + +bool +Animation::isTerminator(AnimationPhase candidate) +{ + return (candidate.image < 0); +} + int Animation::getLength() { diff --git a/src/animation.h b/src/animation.h index 60dcd287..605d8cb1 100644 --- a/src/animation.h +++ b/src/animation.h @@ -61,10 +61,25 @@ class Animation void reset(); + /** + * Appends a new animation at the end of the sequence + */ void addPhase(int image, unsigned int delay, int offsetX, int offsetY); + /** + * Appends an animation terminator that states that the animation + * should not loop + */ void + addTerminator(); + + /** + * Updates animation phase. + * true indicates a still running animation while false indicates a + * finished animation + */ + bool update(unsigned int time); int @@ -89,6 +104,7 @@ class Animation getLength(); protected: + static bool isTerminator(AnimationPhase); std::list mAnimationPhases; std::list::iterator iCurrentPhase; unsigned int mTime; diff --git a/src/being.cpp b/src/being.cpp index 982b0ebf..4d542753 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -331,10 +331,24 @@ Being::setAction(Uint8 action) currentAction = ACTION_ATTACK; break; } + for (int i = 0; i < VECTOREND_SPRITE; i++) + { + if (mSprites[i]) + { + mSprites[i]->reset(); + } + } }; break; case MONSTER_ATTACK: currentAction = ACTION_ATTACK; + for (int i = 0; i < VECTOREND_SPRITE; i++) + { + if (mSprites[i]) + { + mSprites[i]->reset(); + } + } break; case DEAD: currentAction = ACTION_DEAD; @@ -346,16 +360,7 @@ Being::setAction(Uint8 action) for (int i = 0; i < VECTOREND_SPRITE; i++) { - if (!mSprites[i]) - continue; - - if (currentAction == ACTION_ATTACK || - currentAction == ACTION_ATTACK_STAB || - currentAction == ACTION_ATTACK_BOW) - { - mSprites[i]->play(currentAction, mAttackSpeed); - } - else + if (mSprites[i]) { mSprites[i]->play(currentAction); } diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp index d2db055a..30b68ee2 100644 --- a/src/beingmanager.cpp +++ b/src/beingmanager.cpp @@ -113,9 +113,9 @@ Being* BeingManager::findBeing(Uint16 x, Uint16 y, Being::Type type) return (i == mBeings.end()) ? NULL : *i; } -Beings* BeingManager::getAll() +Beings& BeingManager::getAll() { - return &mBeings; + return mBeings; } void BeingManager::logic() @@ -153,3 +153,28 @@ void BeingManager::clear() mBeings.push_back(player_node); } } + +Being* BeingManager::findNearestLivingBeing(Uint16 x, Uint16 y, int maxdist, + Being::Type type) +{ + Being *closestBeing = NULL; + int dist = 0; + + for (BeingIterator i = mBeings.begin(); i != mBeings.end(); i++) + { + Being *being = (*i); + int d = abs(being->mX - x) + abs(being->mY - y); + + if ((being->getType() == type || type == Being::UNKNOWN) + && (d < dist || closestBeing == NULL) // it is closer + && being->mAction != Being::DEAD // no dead beings + && being->mAction != Being::MONSTER_DEAD + ) + { + dist = d; + closestBeing = being; + } + } + + return (maxdist >= dist) ? closestBeing : NULL; +} diff --git a/src/beingmanager.h b/src/beingmanager.h index c32884a0..15a347de 100644 --- a/src/beingmanager.h +++ b/src/beingmanager.h @@ -46,29 +46,38 @@ class BeingManager void setPlayer(LocalPlayer *player); /** - * Create a being and add it to the list of beings + * Create a being and add it to the list of beings. */ Being* createBeing(Uint16 id, Uint16 job); /** - * Remove a Being + * Remove a Being. */ void destroyBeing(Being *being); /** - * Return a specific id Being + * Return a specific id Being. */ Being* findBeing(Uint16 id); /** - * Return a being at specific coordinates + * Return a being at specific coordinates. */ Being* findBeing(Uint16 x, Uint16 y, Being::Type type = Being::UNKNOWN); + /** + * Return a being nearest to specific coordinates. + * + * \param maxdist maximal distance. If minimal distance is larger, + * no being is returned + */ + Being* findNearestLivingBeing(Uint16 x, Uint16 y, int maxdist, + Being::Type type = Being::UNKNOWN); + /** * Returns the whole list of beings */ - Beings* getAll(); + Beings& getAll(); /** * Logic. diff --git a/src/engine.cpp b/src/engine.cpp index 253a8288..231313c4 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -266,8 +266,8 @@ void Engine::draw(Graphics *graphics) } // Draw player nickname, speech, and emotion sprite as needed - Beings *beings = beingManager->getAll(); - for (BeingIterator i = beings->begin(); i != beings->end(); i++) + Beings &beings = beingManager->getAll(); + for (BeingIterator i = beings.begin(); i != beings.end(); i++) { (*i)->drawSpeech(graphics, -camera_x, -camera_y); (*i)->drawName(graphics, -camera_x, -camera_y); diff --git a/src/floor_item.cpp b/src/floor_item.cpp index edd5d4a7..9a179a21 100644 --- a/src/floor_item.cpp +++ b/src/floor_item.cpp @@ -42,7 +42,7 @@ FloorItem::FloorItem(unsigned int id, mMap(map) { // Retrieve item image from item info - mImage = itemDb->getItemInfo(itemId)->getImage(); + mImage = itemDb->getItemInfo(itemId).getImage(); // Add ourselves to the map mSpriteIterator = mMap->addSprite(this); @@ -50,6 +50,6 @@ FloorItem::FloorItem(unsigned int id, FloorItem::~FloorItem() { - // Remove and delete the representative sprite + // Remove ourselves from the map mMap->removeSprite(mSpriteIterator); } diff --git a/src/game.cpp b/src/game.cpp index f5ebe095..5e4c24c2 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -202,9 +202,9 @@ void createGuiWindows() minimap->getHeight() + 30);*/ // Set initial window visibility - chatWindow->setSticky(true); - miniStatusWindow->setSticky(true); - menuWindow->setSticky(true); +// chatWindow->setSticky(true); +// miniStatusWindow->setSticky(true); +// menuWindow->setSticky(true); chatWindow->setVisible(true); miniStatusWindow->setVisible(true); @@ -277,6 +277,10 @@ Game::Game(): SDL_AddTimer(10, nextTick, NULL); // Logic counter SDL_AddTimer(1000, nextSecond, NULL); // Seconds counter + // Initialize frame limiting + config.addListener("fpslimit", this); + optionChanged("fpslimit"); + // Initialize beings beingManager->setPlayer(player_node); @@ -339,12 +343,23 @@ bool saveScreenshot(SDL_Surface *screenshot) return ImageWriter::writePNG(screenshot, filename.str()); } +void Game::optionChanged(const std::string &name) +{ + int fpsLimit = (int) config.getValue("fpslimit", 0); + + // Calculate new minimum frame time + mMinFrameTime = fpsLimit ? 1000 / fpsLimit : 0; + + // Reset draw time to current time + mDrawTime = tick_time * 10; +} + void Game::logic() { + // mDrawTime has a higher granularity than gameTime in order to be able to + // work with minimum frame durations in milliseconds. int gameTime = tick_time; - int drawTime = tick_time * 10; - int delta = 0; - int fpsLimit = 0; + mDrawTime = tick_time * 10; while (!done) { @@ -356,23 +371,35 @@ void Game::logic() gameTime++; } + // This is done because at some point tick_time will wrap. gameTime = tick_time; - fpsLimit = (int)config.getValue("fpslimit", 50); - delta = fpsLimit ? 1000 / fpsLimit : 0; - - // Update the screen when application is active, delay otherwise - if (SDL_GetAppState() & SDL_APPACTIVE && - (abs(tick_time * 10 - drawTime) >= delta)) + // Update the screen when application is active, delay otherwise. + if (SDL_GetAppState() & SDL_APPACTIVE) { - frame++; - engine->draw(graphics); - graphics->updateScreen(); - drawTime += delta; + // Draw a frame if either frames are not limited or enough time has + // passed since the last frame. + if (!mMinFrameTime || + get_elapsed_time(mDrawTime / 10) > mMinFrameTime) + { + frame++; + engine->draw(graphics); + graphics->updateScreen(); + mDrawTime += mMinFrameTime; + + // Make sure to wrap mDrawTime, since tick_time will wrap. + if (mDrawTime > MAX_TIME * 10) + mDrawTime -= MAX_TIME * 10; + } + else + { + SDL_Delay(10); + } } else { SDL_Delay(10); + mDrawTime = tick_time * 10; } // Handle network stuff @@ -463,10 +490,7 @@ void Game::handleInput() // Attempt to hide all windows case SDLK_h: - chatWindow->setVisible(false); - miniStatusWindow->setVisible(false); statusWindow->setVisible(false); - menuWindow->setVisible(false); buyDialog->setVisible(false); sellDialog->setVisible(false); buySellDialog->setVisible(false); @@ -474,12 +498,9 @@ void Game::handleInput() npcTextDialog->setVisible(false); npcListDialog->setVisible(false); skillDialog->setVisible(false); - //newSkillWindow->setVisible(false); setupWindow->setVisible(false); equipmentWindow->setVisible(false); chargeDialog->setVisible(false); - tradeWindow->setVisible(false); - //buddyWindow->setVisible(false); helpWindow->setVisible(false); debugWindow->setVisible(false); break; @@ -679,6 +700,18 @@ void Game::handleInput() player_node->attack(target, newTarget); } + // Target the nearest monster if 'a' pressed + if (keys[SDLK_a]) + { + Being *target = + beingManager->findNearestLivingBeing(x, y, 20, Being::MONSTER); + + if (target) + { + player_node->setTarget(target); + } + } + if (joystick) { if (joystick->buttonPressed(1)) diff --git a/src/game.h b/src/game.h index 7330052a..19a6054a 100644 --- a/src/game.h +++ b/src/game.h @@ -27,6 +27,8 @@ #include #include +#include "configlistener.h" + #define SPEECH_TIME 80 #define SPEECH_MAX_TIME 100 @@ -36,7 +38,7 @@ extern std::string map_path; extern volatile int fps; extern volatile int tick_time; -class Game +class Game : public ConfigListener { public: Game(); @@ -46,7 +48,15 @@ class Game void handleInput(); - protected: + void optionChanged(const std::string &name); + + private: + /** Used to determine whether to draw the next frame. */ + int mDrawTime; + + /** The minimum frame time (used for frame limiting). */ + int mMinFrameTime; + typedef std::auto_ptr MessageHandlerPtr; MessageHandlerPtr mBeingHandler; MessageHandlerPtr mBuySellHandler; @@ -61,8 +71,7 @@ class Game }; /** - * Returns elapsed time. (Warning: very unsafe function, it supposes the delay - * is always < 10 seconds) + * Returns elapsed time. (Warning: supposes the delay is always < 100 seconds) */ int get_elapsed_time(int start_time); diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index 165fa7dc..ae779503 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -91,6 +91,7 @@ BuyDialog::BuyDialog(): mSlider->setEventId("slider"); mItemList->addActionListener(this); + mItemList->addSelectionListener(this); mSlider->addActionListener(this); add(mScrollArea); @@ -140,7 +141,8 @@ void BuyDialog::addItem(short id, int price) { ITEM_SHOP item_shop; - item_shop.name = itemDb->getItemInfo(id)->getName() + " " + toString(price) + " GP"; + item_shop.name = itemDb->getItemInfo(id).getName() + " " + + toString(price) + " GP"; item_shop.price = price; item_shop.id = id; @@ -152,7 +154,8 @@ void BuyDialog::action(const std::string &eventId, gcn::Widget *widget) { int selectedItem = mItemList->getSelected(); - if (eventId == "item") { + if (eventId == "item") + { // Reset amount of items and update labels mAmountItems = 0; mSlider->setValue(0); @@ -175,23 +178,27 @@ void BuyDialog::action(const std::string &eventId, gcn::Widget *widget) mIncreaseButton->setEnabled(mMaxItems > 0); mSlider->setEnabled(mMaxItems > 0); } - else if (eventId == "quit") { + else if (eventId == "quit") + { setVisible(false); current_npc = 0; } // The following actions require a valid selection - if (selectedItem < 0 || selectedItem >= int(mShopItems->size())) { + if (selectedItem < 0 || selectedItem >= int(mShopItems->size())) + { return; } bool updateButtonsAndLabels = false; - if (eventId == "slider") { + if (eventId == "slider") + { mAmountItems = (int)(mSlider->getValue() * mMaxItems); updateButtonsAndLabels = true; } - else if (eventId == "+") { + else if (eventId == "+") + { if (mAmountItems < mMaxItems) { mAmountItems++; } else { @@ -201,7 +208,8 @@ void BuyDialog::action(const std::string &eventId, gcn::Widget *widget) mSlider->setValue(double(mAmountItems)/double(mMaxItems)); updateButtonsAndLabels = true; } - else if (eventId == "-") { + else if (eventId == "-") + { if (mAmountItems > 0) { mAmountItems--; } else { @@ -211,7 +219,7 @@ void BuyDialog::action(const std::string &eventId, gcn::Widget *widget) mSlider->setValue(double(mAmountItems)/double(mMaxItems)); updateButtonsAndLabels = true; } - // TODO Actually we'd have a bug elsewhere if this check for the number + // TODO: Actually we'd have a bug elsewhere if this check for the number // of items to be bought ever fails, Bertram removed the assertions, is // there a better way to ensure this fails in an _obivous_ way in C++? else if (eventId == "buy" && (mAmountItems > 0 && @@ -239,7 +247,8 @@ void BuyDialog::action(const std::string &eventId, gcn::Widget *widget) } // If anything has changed, we have to update the buttons and labels - if (updateButtonsAndLabels) { + if (updateButtonsAndLabels) + { // Update buttons mIncreaseButton->setEnabled(mAmountItems < mMaxItems); mDecreaseButton->setEnabled(mAmountItems > 0); @@ -255,19 +264,21 @@ void BuyDialog::action(const std::string &eventId, gcn::Widget *widget) } } -void BuyDialog::mouseClick(int x, int y, int button, int count) +void BuyDialog::selectionChanged(const SelectionEvent &event) { - Window::mouseClick(x, y, button, count); - int selectedItem = mItemList->getSelected(); + if (selectedItem > -1) { - int itemId = mShopItems->at(selectedItem).id; - ItemInfo *itemInfo = itemDb->getItemInfo(itemId); + const ItemInfo &info = + itemDb->getItemInfo(mShopItems->at(selectedItem).id); - mItemDescLabel->setCaption("Description: " + - itemInfo->getDescription()); - mItemEffectLabel->setCaption("Effect: " + - itemInfo->getEffect()); + mItemDescLabel->setCaption("Description: " + info.getDescription()); + mItemEffectLabel->setCaption("Effect: " + info.getEffect()); + } + else + { + mItemDescLabel->setCaption("Description:"); + mItemEffectLabel->setCaption("Effect:"); } } diff --git a/src/gui/buy.h b/src/gui/buy.h index 0ddea4c4..f5c163e1 100644 --- a/src/gui/buy.h +++ b/src/gui/buy.h @@ -27,17 +27,19 @@ #include #include "window.h" +#include "selectionlistener.h" #include "../guichanfwd.h" class ShopItems; +class ListBox; /** * The buy dialog. * * \ingroup Interface */ -class BuyDialog : public Window, public gcn::ActionListener +class BuyDialog : public Window, public gcn::ActionListener, SelectionListener { public: /** @@ -78,9 +80,11 @@ class BuyDialog : public Window, public gcn::ActionListener int getNumberOfElements(); /** - * Mouse callback + * Updates the labels according to the selected item. + * + * @see SelectionListener::selectionChanged */ - void mouseClick(int x, int y, int buton, int count); + void selectionChanged(const SelectionEvent &event); /** * Returns the name of item number i in the shop inventory. @@ -92,7 +96,7 @@ class BuyDialog : public Window, public gcn::ActionListener gcn::Button *mQuitButton; gcn::Button *mIncreaseButton; gcn::Button *mDecreaseButton; - gcn::ListBox *mItemList; + ListBox *mItemList; gcn::ScrollArea *mScrollArea; gcn::Label *mItemDescLabel; gcn::Label *mItemEffectLabel; diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index 042a5be8..3e6c4a5f 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -224,6 +224,28 @@ void CharSelectDialog::logic() updatePlayerInfo(); } +bool CharSelectDialog::selectByName(const std::string &name) +{ + if (mCharInfo->isLocked()) + return false; + + unsigned int oldPos = mCharInfo->getPos(); + + mCharInfo->select(0); + do { + LocalPlayer *player = mCharInfo->getEntry(); + + if (player && player->getName() == name) + return true; + + mCharInfo->next(); + } while (mCharInfo->getPos()); + + mCharInfo->select(oldPos); + + return false; +} + std::string CharSelectDialog::getName() { return mNameLabel->getCaption(); diff --git a/src/gui/char_select.h b/src/gui/char_select.h index 06881bb5..6d9d1a83 100644 --- a/src/gui/char_select.h +++ b/src/gui/char_select.h @@ -54,6 +54,8 @@ class CharSelectDialog : public Window, public gcn::ActionListener void logic(); + bool selectByName(const std::string &name); + /** * Returns name of selected player */ diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 2cbffde4..ec525c47 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -65,7 +65,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) continue; } - image = item->getInfo()->getImage(); + image = item->getInfo().getImage(); dynamic_cast(graphics)->drawImage( image, 36 * (i % 4) + 10, 36 * (i / 4) + 25); } @@ -76,7 +76,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) return; } - image = item->getInfo()->getImage(); + image = item->getInfo().getImage(); dynamic_cast(graphics)->drawImage(image, 160, 25); graphics->drawText(toString(item->getQuantity()), 170, 62, diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index ecf81712..33852f2b 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -322,6 +322,19 @@ Gui::mousePress(int mx, int my, int button) } } } + + if (button == gcn::MouseInput::MIDDLE) + { + // Find the being nearest to the clicked position + Being *target = beingManager->findNearestLivingBeing( + tilex, tiley, + 20, Being::MONSTER); + + if (target) + { + player_node->setTarget(target); + } + } } void diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 063e8836..ea0fd8c0 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -55,6 +55,8 @@ InventoryWindow::InventoryWindow(): mDropButton = new Button("Drop", "drop", this); mItems = new ItemContainer(player_node->mInventory.get()); + mItems->addSelectionListener(this); + mInvenScroll = new ScrollArea(mItems); mInvenScroll->setPosition(8, 8); mInvenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); @@ -123,33 +125,46 @@ void InventoryWindow::action(const std::string &eventId, gcn::Widget *widget) } } -void InventoryWindow::mouseClick(int x, int y, int button, int count) +void InventoryWindow::selectionChanged(const SelectionEvent &event) { - Window::mouseClick(x, y, button, count); - Item *item = mItems->getItem(); - if (!item) { - return; + // Update name, effect and description + if (!item) + { + mItemNameLabel->setCaption("Name:"); + mItemEffectLabel->setCaption("Effect:"); + mItemDescriptionLabel->setCaption("Description:"); + } + else + { + const ItemInfo& itemInfo = item->getInfo(); + std::string SomeText; + SomeText = "Name: " + itemInfo.getName(); + mItemNameLabel->setCaption(SomeText); + SomeText = "Effect: " + itemInfo.getEffect(); + mItemEffectLabel->setCaption(SomeText); + SomeText = "Description: " + itemInfo.getDescription(); + mItemDescriptionLabel->setCaption(SomeText); + + mItemNameLabel->adjustSize(); + mItemEffectLabel->adjustSize(); + mItemDescriptionLabel->adjustSize(); } +} - // Show Name and Description - std::string SomeText; - SomeText = "Name: " + item->getInfo()->getName(); - mItemNameLabel->setCaption(SomeText); - mItemNameLabel->adjustSize(); - SomeText = "Effect: " + item->getInfo()->getEffect(); - mItemEffectLabel->setCaption(SomeText); - mItemEffectLabel->adjustSize(); - SomeText = "Description: " + item->getInfo()->getDescription(); - mItemDescriptionLabel->setCaption(SomeText); - mItemDescriptionLabel->adjustSize(); +void InventoryWindow::mouseClick(int x, int y, int button, int count) +{ + Window::mouseClick(x, y, button, count); if (button == gcn::MouseInput::RIGHT) { - /* - * convert relative to the window coordinates to - * absolute screen coordinates + Item *item = mItems->getItem(); + + if (!item) return; + + /* Convert relative to the window coordinates to + * absolute screen coordinates. */ int mx = x + getX(); int my = y + getY(); @@ -223,11 +238,6 @@ void InventoryWindow::loadWindowState() updateWidgets(); } -void InventoryWindow::setDefaultSize(int defaultX, int defaultY, int defaultWidth, int defaultHeight) -{ - Window::setDefaultSize(defaultX, defaultY, defaultWidth, defaultHeight); -} - void InventoryWindow::resetToDefaultSize() { Window::resetToDefaultSize(); diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index da7a7ef2..d46e91e7 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -27,6 +27,7 @@ #include #include "window.h" +#include "selectionlistener.h" #include "../guichanfwd.h" @@ -38,7 +39,7 @@ class ItemContainer; * * \ingroup Interface */ -class InventoryWindow : public Window, gcn::ActionListener +class InventoryWindow : public Window, gcn::ActionListener, SelectionListener { public: /** @@ -47,14 +48,14 @@ class InventoryWindow : public Window, gcn::ActionListener InventoryWindow(); /** - * Logic (updates buttons and weight information) + * Logic (updates buttons and weight information). */ void logic(); /** * Called when receiving actions from the widgets. */ - void action(const std::string& eventId, gcn::Widget* widget); + void action(const std::string &eventId, gcn::Widget *widget); void mouseClick(int x, int y, int button, int count); @@ -64,14 +65,19 @@ class InventoryWindow : public Window, gcn::ActionListener void loadWindowState(); - void setDefaultSize(int defaultX, int defaultY, int defaultWidth, int defaultHeight); - void resetToDefaultSize(); + /** + * Updates labels to currently selected item. + * + * @see SelectionListener::selectionChanged. + */ + void selectionChanged(const SelectionEvent &event); + private: - void updateButtons(); /** Updates button states */ + void updateButtons(); /**< Updates button states. */ - void updateWidgets(); /** Updates widgets size/position */ + void updateWidgets(); /**< Updates widgets size/position. */ ItemContainer *mItems; diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index c7c55fd9..5bcd000d 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -25,6 +25,8 @@ #include +#include "selectionlistener.h" + #include "../graphics.h" #include "../inventory.h" #include "../item.h" @@ -38,14 +40,14 @@ #include "../utils/tostring.h" ItemContainer::ItemContainer(Inventory *inventory): - mInventory(inventory) + mInventory(inventory), + mSelectedItem(NULL) { ResourceManager *resman = ResourceManager::getInstance(); mSelImg = resman->getImage("graphics/gui/selection.png"); if (!mSelImg) logger->error("Unable to load selection.png"); - mSelectedItem = 0; // No item selected mMaxItems = mInventory->getLastUsedSlot() - 1; // Count from 0, usage from 2 addMouseListener(this); @@ -84,7 +86,7 @@ void ItemContainer::draw(gcn::Graphics* graphics) // sure somewhere else) if (mSelectedItem && mSelectedItem->getQuantity() <= 0) { - mSelectedItem = 0; + selectNone(); } /* @@ -111,7 +113,7 @@ void ItemContainer::draw(gcn::Graphics* graphics) // Draw item icon Image* image; - if ((image = item->getInfo()->getImage()) != NULL) + if ((image = item->getInfo().getImage()) != NULL) { dynamic_cast(graphics)->drawImage( image, itemX, itemY); @@ -150,7 +152,28 @@ Item* ItemContainer::getItem() void ItemContainer::selectNone() { - mSelectedItem = 0; + setSelectedItem(NULL); +} + +void ItemContainer::setSelectedItem(Item *item) +{ + if (mSelectedItem != item) + { + mSelectedItem = item; + fireSelectionChangedEvent(); + } +} + +void ItemContainer::fireSelectionChangedEvent() +{ + SelectionEvent event(this); + SelectionListeners::iterator i_end = mListeners.end(); + SelectionListeners::iterator i; + + for (i = mListeners.begin(); i != i_end; ++i) + { + (*i)->selectionChanged(event); + } } void ItemContainer::mousePress(int mx, int my, int button) @@ -166,6 +189,6 @@ void ItemContainer::mousePress(int mx, int my, int button) if (index > INVENTORY_SIZE) { index = INVENTORY_SIZE - 1; } - mSelectedItem = mInventory->getItem(index); + setSelectedItem(mInventory->getItem(index)); } } diff --git a/src/gui/itemcontainer.h b/src/gui/itemcontainer.h index f52f37ec..a2d5f0f7 100644 --- a/src/gui/itemcontainer.h +++ b/src/gui/itemcontainer.h @@ -27,9 +27,12 @@ #include #include +#include + class Image; class Inventory; class Item; +class SelectionListener; /** * An item container. Used to show items in inventory and trade dialog. @@ -76,16 +79,46 @@ class ItemContainer : public gcn::Widget, public gcn::MouseListener Item* getItem(); /** - * Set selected item to -1. + * Sets selected item to NULL. */ void selectNone(); + /** + * Adds a listener to the list that's notified each time a change to + * the selection occurs. + */ + void addSelectionListener(SelectionListener *listener) + { + mListeners.push_back(listener); + } + + /** + * Removes a listener from the list that's notified each time a change + * to the selection occurs. + */ + void removeSelectionListener(SelectionListener *listener) + { + mListeners.remove(listener); + } + private: + /** + * Sets the currently selected item. + */ + void setSelectedItem(Item *item); + + /** + * Sends out selection events to the list of selection listeners. + */ + void fireSelectionChangedEvent(); + Inventory *mInventory; Image *mSelImg; Item *mSelectedItem; int mMaxItems; + + std::list mListeners; }; #endif diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp index df03b81b..14626d06 100644 --- a/src/gui/listbox.cpp +++ b/src/gui/listbox.cpp @@ -23,12 +23,16 @@ #include "listbox.h" +#include "selectionlistener.h" + #include #include #include +#include ListBox::ListBox(gcn::ListModel *listModel): - gcn::ListBox(listModel) + gcn::ListBox(listModel), + mMousePressed(false) { } @@ -45,8 +49,8 @@ void ListBox::draw(gcn::Graphics *graphics) // Draw rectangle below the selected list element if (mSelected >= 0) { - graphics->fillRectangle( - gcn::Rectangle(0, fontHeight * mSelected, getWidth(), fontHeight)); + graphics->fillRectangle(gcn::Rectangle(0, fontHeight * mSelected, + getWidth(), fontHeight)); } // Draw the list elements @@ -55,3 +59,50 @@ void ListBox::draw(gcn::Graphics *graphics) graphics->drawText(mListModel->getElementAt(i), 1, y); } } + +void ListBox::setSelected(int selected) +{ + gcn::ListBox::setSelected(selected); + fireSelectionChangedEvent(); +} + +void ListBox::mousePress(int x, int y, int button) +{ + gcn::ListBox::mousePress(x, y, button); + + if (button == gcn::MouseInput::LEFT && hasMouse()) + { + mMousePressed = true; + } +} + +void ListBox::mouseRelease(int x, int y, int button) +{ + gcn::ListBox::mouseRelease(x, y, button); + + mMousePressed = false; +} + +void ListBox::mouseMotion(int x, int y) +{ + gcn::ListBox::mouseMotion(x, y); + + // Pretend mouse is pressed continuously while dragged. Causes list + // selection to be updated as is default in many GUIs. + if (mMousePressed) + { + mousePress(x, y, gcn::MouseInput::LEFT); + } +} + +void ListBox::fireSelectionChangedEvent() +{ + SelectionEvent event(this); + SelectionListeners::iterator i_end = mListeners.end(); + SelectionListeners::iterator i; + + for (i = mListeners.begin(); i != i_end; ++i) + { + (*i)->selectionChanged(event); + } +} diff --git a/src/gui/listbox.h b/src/gui/listbox.h index 5999f7a7..c1932f54 100644 --- a/src/gui/listbox.h +++ b/src/gui/listbox.h @@ -26,10 +26,12 @@ #include +class SelectionListener; + /** * A list box, meant to be used inside a scroll area. Same as the Guichan list * box except this one doesn't have a background, instead completely relying - * on the scroll area. + * on the scroll area. It also adds selection listener functionality. * * \ingroup GUI */ @@ -45,6 +47,43 @@ class ListBox : public gcn::ListBox * Draws the list box. */ void draw(gcn::Graphics *graphics); + + void mousePress(int x, int y, int button); + void mouseRelease(int x, int y, int button); + void mouseMotion(int x, int y); + + /** + * Adds a listener to the list that's notified each time a change to + * the selection occurs. + */ + void addSelectionListener(SelectionListener *listener) + { + mListeners.push_back(listener); + } + + /** + * Removes a listener from the list that's notified each time a change + * to the selection occurs. + */ + void removeSelectionListener(SelectionListener *listener) + { + mListeners.remove(listener); + } + + /** + * Sets the index of the selected element. + */ + void setSelected(int selected); + + private: + /** + * Sends out selection events to the list of selection listeners. + */ + void fireSelectionChangedEvent(); + + bool mMousePressed; /**< Keeps track of mouse pressed status. */ + + std::list mListeners; }; #endif diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index db6d4f15..69c5eb6e 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -76,10 +76,10 @@ void Minimap::draw(gcn::Graphics *graphics) mMapImage, getPadding(), getTitleBarHeight()); } - Beings *beings = beingManager->getAll(); + Beings &beings = beingManager->getAll(); BeingIterator bi; - for (bi = beings->begin(); bi != beings->end(); bi++) + for (bi = beings.begin(); bi != beings.end(); bi++) { Being *being = (*bi); int dotSize = 1; diff --git a/src/gui/playerbox.cpp b/src/gui/playerbox.cpp index ba97d54c..46cd7e85 100644 --- a/src/gui/playerbox.cpp +++ b/src/gui/playerbox.cpp @@ -97,7 +97,7 @@ void PlayerBox::draw(gcn::Graphics *graphics) if (mHairStyle > 0 && mHairColor < NR_HAIR_COLORS && mHairStyle < NR_HAIR_STYLES) { - int hf = 9 * mHairColor; + int hf = 5 * mHairColor; if (hf >= 0 && hf < (int)hairset[mHairStyle]->size()) { dynamic_cast(graphics)->drawImage( hairset[mHairStyle - 1]->get(hf), 35, 7); diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 59316de1..ab81f7d0 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -106,7 +106,7 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem) mBrowserBox->clearRows(); // Floor item can be picked up (single option, candidate for removal) - std::string name = itemDb->getItemInfo(mFloorItem->getItemId())->getName(); + std::string name = itemDb->getItemInfo(mFloorItem->getItemId()).getName(); mBrowserBox->addRow("@@pickup|Pick Up " + name + "@@"); //browserBox->addRow("@@look|Look To@@"); diff --git a/src/gui/selectionlistener.h b/src/gui/selectionlistener.h new file mode 100644 index 00000000..a2fc6533 --- /dev/null +++ b/src/gui/selectionlistener.h @@ -0,0 +1,78 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: selectionlistener.h 2651 2006-09-03 16:47:48Z b_lindeijer $ + */ + +#ifndef _TMW_SELECTIONLISTENER_H__ +#define _TMW_SELECTIONLISTENER_H__ + +#include + +/** + * An event that characterizes a change in the current selection. + * + * \ingroup GUI + */ +class SelectionEvent +{ + public: + /** + * Constructor. + */ + SelectionEvent(gcn::Widget *source): + mSource(source) + { + } + + /** + * The widget from which the event originated. + */ + gcn::Widget* getSource() const + { + return mSource; + } + + private: + gcn::Widget *mSource; +}; + +/** + * The listener that's notified when a selection value changes. + * + * \ingroup GUI + */ +class SelectionListener +{ + public: + /** + * Virtual destructor. + */ + virtual ~SelectionListener() {} + + /** + * Called whenever the value of the selection changes. + */ + virtual void selectionChanged(const SelectionEvent &event) = 0; +}; + +typedef std::list SelectionListeners; + +#endif diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index 33813271..d6d8cad5 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -94,6 +94,7 @@ SellDialog::SellDialog(): mSlider->setEventId("mSlider"); mItemList->addActionListener(this); + mItemList->addSelectionListener(this); mSlider->addActionListener(this); add(scrollArea); @@ -141,7 +142,7 @@ void SellDialog::addItem(Item *item, int price) ITEM_SHOP item_shop; - item_shop.name = item->getInfo()->getName() + " " + toString(price) + " GP"; + item_shop.name = item->getInfo().getName() + " " + toString(price) + " GP"; item_shop.price = price; item_shop.index = item->getInvIndex(); item_shop.id = item->getId(); @@ -155,7 +156,8 @@ void SellDialog::action(const std::string &eventId, gcn::Widget *widget) { int selectedItem = mItemList->getSelected(); - if (eventId == "item") { + if (eventId == "item") + { mAmountItems = 0; mSlider->setValue(0); mDecreaseButton->setEnabled(false); @@ -188,19 +190,22 @@ void SellDialog::action(const std::string &eventId, gcn::Widget *widget) bool updateButtonsAndLabels = false; - if (eventId == "mSlider") { + if (eventId == "mSlider") + { mAmountItems = (int)(mSlider->getValue() * mMaxItems); updateButtonsAndLabels = true; } - else if (eventId == "+") { + else if (eventId == "+") + { assert(mAmountItems < mMaxItems); mAmountItems++; mSlider->setValue(double(mAmountItems)/double(mMaxItems)); updateButtonsAndLabels = true; } - else if (eventId == "-") { + else if (eventId == "-") + { assert(mAmountItems > 0); mAmountItems--; @@ -208,7 +213,8 @@ void SellDialog::action(const std::string &eventId, gcn::Widget *widget) updateButtonsAndLabels = true; } - else if (eventId == "sell") { + else if (eventId == "sell") + { // Attempt sell assert(mAmountItems > 0 && mAmountItems <= mMaxItems); @@ -234,7 +240,8 @@ void SellDialog::action(const std::string &eventId, gcn::Widget *widget) } // If anything changed, we need to update the buttons and labels - if (updateButtonsAndLabels) { + if (updateButtonsAndLabels) + { // Update labels mQuantityLabel->setCaption(toString(mAmountItems)); mQuantityLabel->adjustSize(); @@ -250,16 +257,21 @@ void SellDialog::action(const std::string &eventId, gcn::Widget *widget) } } -void SellDialog::mouseClick(int x, int y, int button, int count) +void SellDialog::selectionChanged(const SelectionEvent &event) { - Window::mouseClick(x, y, button, count); - int selectedItem = mItemList->getSelected(); + if (selectedItem > -1) { - mItemDescLabel->setCaption("Description: " + - itemDb->getItemInfo(mShopItems->at(selectedItem).id)->getDescription()); - mItemEffectLabel->setCaption("Effect: " + - itemDb->getItemInfo(mShopItems->at(selectedItem).id)->getEffect()); + const ItemInfo &info = + itemDb->getItemInfo(mShopItems->at(selectedItem).id); + + mItemDescLabel->setCaption("Description: " + info.getDescription()); + mItemEffectLabel->setCaption("Effect: " + info.getEffect()); + } + else + { + mItemDescLabel->setCaption("Description"); + mItemEffectLabel->setCaption("Effect"); } } diff --git a/src/gui/sell.h b/src/gui/sell.h index be5185bd..69f8b089 100644 --- a/src/gui/sell.h +++ b/src/gui/sell.h @@ -27,19 +27,20 @@ #include #include "window.h" +#include "selectionlistener.h" #include "../guichanfwd.h" class Item; class ShopItems; - +class ListBox; /** * The sell dialog. * * \ingroup Interface */ -class SellDialog : public Window, public gcn::ActionListener +class SellDialog : public Window, gcn::ActionListener, SelectionListener { public: /** @@ -70,15 +71,17 @@ class SellDialog : public Window, public gcn::ActionListener void action(const std::string& eventId, gcn::Widget* widget); /** - * Mouse callback + * Updates labels according to selected item. + * + * @see SelectionListener::selectionChanged */ - void mouseClick(int x, int y, int buton, int count); + void selectionChanged(const SelectionEvent &event); private: gcn::Button *mSellButton; gcn::Button *mIncreaseButton; gcn::Button *mDecreaseButton; - gcn::ListBox *mItemList; + ListBox *mItemList; gcn::Label *mMoneyLabel; gcn::Label *mItemDescLabel; gcn::Label *mItemEffectLabel; diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp index d12ace75..78b10498 100644 --- a/src/gui/setup.cpp +++ b/src/gui/setup.cpp @@ -43,7 +43,7 @@ Setup::Setup(): Window("Setup") { int width = 230; - int height = 225; + int height = 245; setContentSize(width, height); const char *buttonNames[] = { @@ -58,7 +58,7 @@ Setup::Setup(): } TabbedContainer *panel = new TabbedContainer(); - panel->setDimension(gcn::Rectangle(5, 5, 220, 185)); + panel->setDimension(gcn::Rectangle(5, 5, 220, 205)); panel->setOpaque(false); SetupTab *tab; diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index 7c72975a..7a4aae03 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -106,7 +106,7 @@ Setup_Video::Setup_Video(): mOpenGLEnabled(config.getValue("opengl", 0)), mCustomCursorEnabled(config.getValue("customcursor", 1)), mOpacity(config.getValue("guialpha", 0.8)), - mFps((int)config.getValue("fpslimit", 50)), + mFps((int)config.getValue("fpslimit", 60)), mModeListModel(new ModeListModel()), mModeList(new ListBox(mModeListModel)), mFsCheckBox(new CheckBox("Full screen", mFullScreenEnabled)), @@ -121,7 +121,10 @@ Setup_Video::Setup_Video(): mScrollLazinessField(new TextField()), mOriginalScrollRadius((int) config.getValue("ScrollRadius", 32)), mScrollRadiusSlider(new Slider(0, 128)), - mScrollRadiusField(new TextField()) + mScrollRadiusField(new TextField()), + mOverlayDetail((int) config.getValue("OverlayDetail", 2)), + mOverlayDetailSlider(new Slider(0, 2)), + mOverlayDetailField(new gcn::Label("")) { setOpaque(false); @@ -163,6 +166,8 @@ Setup_Video::Setup_Video(): mScrollRadiusField->setEventId("scrollradiusfield"); mScrollLazinessSlider->setEventId("scrolllazinessslider"); mScrollLazinessField->setEventId("scrolllazinessfield"); + mOverlayDetailSlider->setEventId("overlaydetailslider"); + mOverlayDetailField->setEventId("overlaydetailfield"); mCustomCursorCheckBox->addActionListener(this); mAlphaSlider->addActionListener(this); @@ -173,6 +178,8 @@ Setup_Video::Setup_Video(): mScrollRadiusField->addKeyListener(this); mScrollLazinessSlider->addActionListener(this); mScrollLazinessField->addKeyListener(this); + mOverlayDetailSlider->addActionListener(this); + mOverlayDetailField->addKeyListener(this); mScrollRadiusSlider->setDimension(gcn::Rectangle(10, 120, 75, 10)); gcn::Label *scrollRadiusLabel = new gcn::Label("Scroll radius"); @@ -190,6 +197,25 @@ Setup_Video::Setup_Video(): mScrollLazinessField->setText(toString(mOriginalScrollLaziness)); mScrollLazinessSlider->setValue(mOriginalScrollLaziness); + mOverlayDetailSlider->setDimension(gcn::Rectangle(10, 160, 75, 10)); + gcn::Label *overlayDetailLabel = new gcn::Label("Ambient FX"); + overlayDetailLabel->setPosition(90, 160); + mOverlayDetailField->setPosition(180, 160); + mOverlayDetailField->setWidth(30); + switch (mOverlayDetail) + { + case 0: + mOverlayDetailField->setCaption("off"); + break; + case 1: + mOverlayDetailField->setCaption("low"); + break; + case 2: + mOverlayDetailField->setCaption("high"); + break; + } + mOverlayDetailSlider->setValue(mOverlayDetail); + add(scrollArea); add(mFsCheckBox); add(mOpenGLCheckBox); @@ -205,6 +231,9 @@ Setup_Video::Setup_Video(): add(mScrollLazinessSlider); add(scrollLazinessLabel); add(mScrollLazinessField); + add(mOverlayDetailSlider); + add(overlayDetailLabel); + add(mOverlayDetailField); } Setup_Video::~Setup_Video() @@ -258,6 +287,7 @@ void Setup_Video::apply() mFullScreenEnabled = config.getValue("screen", 0); mCustomCursorEnabled = config.getValue("customcursor", 1); mOpacity = config.getValue("guialpha", 0.8); + mOverlayDetail = (int)config.getValue("OverlayDetail", 2); mOpenGLEnabled = config.getValue("opengl", 0); } @@ -288,6 +318,7 @@ void Setup_Video::cancel() mOpenGLCheckBox->setMarked(mOpenGLEnabled); mCustomCursorCheckBox->setMarked(mCustomCursorEnabled); mAlphaSlider->setValue(mOpacity); + mOverlayDetailSlider->setValue(mOverlayDetail); mScrollRadiusField->setText(toString(mOriginalScrollRadius)); mScrollLazinessField->setText(toString(mOriginalScrollLaziness)); @@ -328,6 +359,23 @@ void Setup_Video::action(const std::string &event, gcn::Widget *widget) mScrollLazinessField->setText(toString(val)); config.setValue("ScrollLaziness", val); } + else if (event == "overlaydetailslider") + { + int val = (int)mOverlayDetailSlider->getValue(); + switch (val) + { + case 0: + mOverlayDetailField->setCaption("off"); + break; + case 1: + mOverlayDetailField->setCaption("low"); + break; + case 2: + mOverlayDetailField->setCaption("high"); + break; + } + config.setValue("OverlayDetail", val); + } else if (event == "fpslimitcheckbox") { if (mFpsCheckBox->isMarked()) diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h index a3fd8884..482d1c65 100644 --- a/src/gui/setup_video.h +++ b/src/gui/setup_video.h @@ -73,6 +73,10 @@ class Setup_Video : public SetupTab, public gcn::ActionListener, gcn::Slider *mScrollRadiusSlider; gcn::TextField *mScrollRadiusField; + int mOverlayDetail; + gcn::Slider *mOverlayDetailSlider; + gcn::Label *mOverlayDetailField; + void updateSliders(bool originalValues); diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index 0cd49013..44efbdb1 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -58,12 +58,14 @@ TradeWindow::TradeWindow(): mTradeButton = new Button("Trade", "trade", this); mMyItemContainer = new ItemContainer(mMyInventory.get()); + mMyItemContainer->addSelectionListener(this); mMyItemContainer->setPosition(2, 2); mMyScroll = new ScrollArea(mMyItemContainer); mMyScroll->setPosition(8, 8); mPartnerItemContainer = new ItemContainer(mPartnerInventory.get()); + mPartnerItemContainer->addSelectionListener(this); mPartnerItemContainer->setPosition(2, 58); mPartnerScroll = new ScrollArea(mPartnerItemContainer); @@ -219,53 +221,54 @@ void TradeWindow::tradeItem(Item *item, int quantity) outMsg.writeLong(quantity); } -void TradeWindow::mouseClick(int x, int y, int button, int count) +void TradeWindow::selectionChanged(const SelectionEvent &event) { - Window::mouseClick(x, y, button, count); - Item *item; - // mMyItems selected - if (x >= mMyScroll->getX() + 3 - && x <= mMyScroll->getX() + mMyScroll->getWidth() - 10 - && y >= mMyScroll->getY() + 16 - && y <= mMyScroll->getY() + mMyScroll->getHeight() + 15 - && (item = mMyItemContainer->getItem())) + /* If an item is selected in one container, make sure no item is selected + * in the other container. + */ + if (event.getSource() == mMyItemContainer && + (item = mMyItemContainer->getItem())) { - mPartnerItemContainer->selectNone(); - // mPartnerItems selected + mPartnerItemContainer->selectNone(); } - else if (x >= mPartnerScroll->getX() + 3 - && x <= mPartnerScroll->getX() + mPartnerScroll->getWidth() - 20 - && y >= mPartnerScroll->getY() + 16 - && y <= mPartnerScroll->getY() + mPartnerScroll->getHeight() + 15 - && (item = mPartnerItemContainer->getItem())) + else if ((item = mPartnerItemContainer->getItem())) { - mMyItemContainer->selectNone(); - } else { - return; + mMyItemContainer->selectNone(); } - // Show Name and Description - std::string SomeText; - SomeText = "Name: " + item->getInfo()->getName(); - mItemNameLabel->setCaption(SomeText); - mItemNameLabel->adjustSize(); - SomeText = "Description: " + item->getInfo()->getDescription(); - mItemDescriptionLabel->setCaption(SomeText); - mItemDescriptionLabel->adjustSize(); + // Update name and description + if (!item) + { + mItemNameLabel->setCaption("Name:"); + mItemDescriptionLabel->setCaption("Description:"); + } + else + { + std::string SomeText; + SomeText = "Name: " + item->getInfo().getName(); + mItemNameLabel->setCaption(SomeText); + mItemNameLabel->adjustSize(); + SomeText = "Description: " + item->getInfo().getDescription(); + mItemDescriptionLabel->setCaption(SomeText); + mItemDescriptionLabel->adjustSize(); + } } void TradeWindow::action(const std::string &eventId, gcn::Widget *widget) { Item *item = inventoryWindow->getItem(); - if (eventId == "add") { - if (!item) { + if (eventId == "add") + { + if (!item) + { return; } - if (mMyInventory->getFreeSlot() < 1) { + if (mMyInventory->getFreeSlot() < 1) + { return; } diff --git a/src/gui/trade.h b/src/gui/trade.h index fe60aac5..ebd05a52 100644 --- a/src/gui/trade.h +++ b/src/gui/trade.h @@ -29,6 +29,7 @@ #include #include "window.h" +#include "selectionlistener.h" #include "../guichanfwd.h" @@ -42,7 +43,7 @@ class ScrollArea; * * \ingroup Interface */ -class TradeWindow : public Window, gcn::ActionListener +class TradeWindow : public Window, gcn::ActionListener, SelectionListener { public: /** @@ -102,14 +103,15 @@ class TradeWindow : public Window, gcn::ActionListener tradeItem(Item *item, int quantity); /** - * Called on mouse click. + * Updates the labels and makes sure only one item is selected in + * either my inventory or partner inventory. */ - void mouseClick(int x, int y, int button, int count); + void selectionChanged(const SelectionEvent &event); /** * Called when receiving actions from the widgets. */ - void action(const std::string& eventId, gcn::Widget* widget); + void action(const std::string &eventId, gcn::Widget *widget); private: typedef std::auto_ptr InventoryPtr; diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index 77a026fe..00b10406 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -48,9 +48,9 @@ UpdaterWindow::UpdaterWindow(): Window("Updating..."), mThread(NULL), mMutex(NULL), mDownloadStatus(UPDATE_NEWS), mUpdateHost(""), mCurrentFile("news.txt"), mBasePath(""), - mStoreInMemory(true), mDownloadComplete(true), mDownloadedBytes(0), - mMemoryBuffer(NULL), mCurlError(new char[CURL_ERROR_SIZE]), - mFileIndex(0) + mStoreInMemory(true), mDownloadComplete(true), mUserCancel(false), + mDownloadedBytes(0), mMemoryBuffer(NULL), + mCurlError(new char[CURL_ERROR_SIZE]), mFileIndex(0) { mCurlError[0] = 0; @@ -133,6 +133,8 @@ void UpdaterWindow::action(const std::string &eventId, gcn::Widget *widget) { if (eventId == "cancel") { + // Register the user cancel + mUserCancel=true; // Skip the updating process if (mDownloadStatus == UPDATE_COMPLETE) { @@ -329,7 +331,15 @@ void UpdaterWindow::logic() case UPDATE_ERROR: if (mThread) { - SDL_WaitThread(mThread, NULL); + if(mUserCancel){ + // Kill the thread, because user has canceled + SDL_KillThread(mThread); + // Set the flag to false again + mUserCancel = false; + } + else{ + SDL_WaitThread(mThread, NULL); + } mThread = NULL; } addRow(""); diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h index 8a168be8..5016036d 100644 --- a/src/gui/updatewindow.h +++ b/src/gui/updatewindow.h @@ -161,6 +161,11 @@ class UpdaterWindow : public Window, public gcn::ActionListener */ bool mDownloadComplete; + /** + * Flag that show if the user has canceled the update + */ + bool mUserCancel; + /** * Byte count currently downloaded in mMemoryBuffer. */ diff --git a/src/gui/window.cpp b/src/gui/window.cpp index 2172baa8..c7860021 100644 --- a/src/gui/window.cpp +++ b/src/gui/window.cpp @@ -249,16 +249,18 @@ void Window::setSticky(bool sticky) mSticky = sticky; } -bool Window::isSticky() { +bool Window::isSticky() +{ return mSticky; } -void Window::setVisible(bool visible) { - if(isSticky()) +void Window::setVisible(bool visible) +{ + if (isSticky()) { gcn::Window::setVisible(true); - } - else + } + else { gcn::Window::setVisible(visible); } diff --git a/src/item.h b/src/item.h index c21f5ddf..1375886e 100644 --- a/src/item.h +++ b/src/item.h @@ -118,7 +118,7 @@ class Item /** * Returns information about this item type. */ - ItemInfo* + const ItemInfo& getInfo() const { return itemDb->getItemInfo(mId); } protected: diff --git a/src/localplayer.h b/src/localplayer.h index 7d5aef87..dbf2a147 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -96,12 +96,17 @@ class LocalPlayer : public Player * Sets the trading state of the player, i.e. whether or not he is * currently involved into some trade. */ - void setTrading(bool trading) { mTrading = trading; }; + void setTrading(bool trading) { mTrading = trading; } void attack(Being *target=NULL, bool keep=false); void stopAttack(); Being* getTarget() const; + /** + * Sets the target being of the player. + */ + void setTarget(Being* target) { mTarget = target; } + void walk(unsigned char dir); /** diff --git a/src/main.cpp b/src/main.cpp index 9d2a1e64..f881ddad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -107,6 +107,33 @@ namespace { } errorListener; } +/** + * A structure holding the values of various options that can be passed from + * the command line. + */ +struct Options +{ + /** + * Constructor. + */ + Options(): + printHelp(false), + skipUpdate(false), + chooseDefault(false), + serverPort(0) + {}; + + bool printHelp; + bool skipUpdate; + bool chooseDefault; + std::string playername; + std::string password; + std::string configPath; + + std::string serverName; + short serverPort; +}; + /** * Initializes the home directory. On UNIX and FreeBSD, ~/.tmw is used. On * Windows and other systems we use the current working directory. @@ -133,7 +160,7 @@ void initHomeDir() /** * Initialize configuration. */ -void initConfiguration() +void initConfiguration(const Options &options) { // Fill configuration with defaults config.setValue("host", "animesites.de"); @@ -158,7 +185,10 @@ void initConfiguration() // Checking if the configuration file exists... otherwise create it with // default options. FILE *tmwFile = 0; - std::string configPath = homeDir + "/config.xml"; + std::string configPath = options.configPath; + if (configPath == "") { + configPath = homeDir + "/config.xml"; + } tmwFile = fopen(configPath.c_str(), "r"); // If we can't read it, it doesn't exist ! @@ -176,7 +206,7 @@ void initConfiguration() } /** - * Do all initialization stuff + * Do all initialization stuff. */ void init_engine() { @@ -279,7 +309,8 @@ void init_engine() sound.init(); } sound.setSfxVolume((int)config.getValue("sfxVolume", defaultSfxVolume)); - sound.setMusicVolume((int)config.getValue("musicVolume", defaultMusicVolume)); + sound.setMusicVolume((int)config.getValue("musicVolume", + defaultMusicVolume)); } catch (const char *err) { state = STATE_ERROR; @@ -311,33 +342,6 @@ void exit_engine() ResourceManager::deleteInstance(); } -/** - * A structure holding the values of various options that can be passed from - * the command line. - */ -struct Options -{ - /** - * Constructor. - */ - Options(): - printHelp(false), - skipUpdate(false), - chooseDefault(false), - serverPort(0) - {}; - - bool printHelp; - bool skipUpdate; - bool chooseDefault; - std::string playername; - std::string password; - - std::string serverName; - short serverPort; - -}; - void printHelp() { std::cout @@ -351,12 +355,13 @@ void printHelp() << std::endl << " -s --server : Login Server name or IP" << std::endl << " -o --port : Login Server Port" << std::endl - << " -p --playername : Login with this player" << std::endl; + << " -p --playername : Login with this player" << std::endl + << " -C --configfile : Configuration file to use" << std::endl; } void parseOptions(int argc, char *argv[], Options &options) { - const char *optstring = "huU:P:Dp:s:o:"; + const char *optstring = "huU:P:Dp:s:o:C:"; const struct option long_options[] = { { "help", no_argument, 0, 'h' }, @@ -367,6 +372,7 @@ void parseOptions(int argc, char *argv[], Options &options) { "server", required_argument, 0, 's' }, { "port", required_argument, 0, 'o' }, { "playername", required_argument, 0, 'p' }, + { "configfile", required_argument, 0, 'C' }, { 0 } }; @@ -403,6 +409,9 @@ void parseOptions(int argc, char *argv[], Options &options) case 'p': options.playername = optarg; break; + case 'C': + options.configPath = optarg; + break; } } } @@ -480,6 +489,10 @@ void mapLogin(LoginData *loginData) { Network::registerHandler(&mapLoginHandler); + logger->log("Memorizing selected character %s", + player_node->getName().c_str()); + config.setValue("lastCharacter", player_node->getName()); + // Send connect messages with the magic token to game and chat servers MessageOut gameServerConnect(PGMSG_CONNECT); gameServerConnect.writeString(token, 32); @@ -510,7 +523,7 @@ int main(int argc, char *argv[]) PHYSFS_init(argv[0]); initHomeDir(); - initConfiguration(); + initConfiguration(options); // Configure logger logger = new Logger(); @@ -721,23 +734,16 @@ int main(int argc, char *argv[]) case STATE_CHAR_SELECT: logger->log("State: CHAR_SELECT"); currentDialog = new CharSelectDialog(&charInfo); - if (options.playername != "") { - n_character = 0; - while (((CharSelectDialog*) currentDialog)->getName() - != options.playername && - n_character < MAX_SLOT + 1) - { - ((CharSelectDialog*) currentDialog)->action("next", - NULL); - ((CharSelectDialog*) currentDialog)->updatePlayerInfo(); - n_character++; - } - n_character = MAX_SLOT + 1; - } - if (options.chooseDefault || options.playername != "") { - ((CharSelectDialog*)currentDialog)->action("ok", - NULL); - } + + if (((CharSelectDialog*)currentDialog)-> + selectByName(options.playername)) + options.chooseDefault = true; + else + ((CharSelectDialog*)currentDialog)->selectByName( + config.getValue("lastCharacter", "")); + + if (options.chooseDefault) + ((CharSelectDialog*)currentDialog)->action("ok", NULL); break; case STATE_ERROR: diff --git a/src/map.cpp b/src/map.cpp index 5063a754..3ccaafc0 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -63,8 +63,11 @@ Map::Map(int width, int height, int tileWidth, int tileHeight): mOnClosedList(1), mOnOpenList(2), mLastScrollX(0.0f), mLastScrollY(0.0f) { - mMetaTiles = new MetaTile[mWidth * mHeight]; - mTiles = new Image*[mWidth * mHeight * 3]; + int size = mWidth * mHeight; + + mMetaTiles = new MetaTile[size]; + mTiles = new Image*[size * 3]; + std::fill_n(mTiles, size * 3, (Image*)0); } Map::~Map() @@ -86,12 +89,17 @@ Map::~Map() void Map::setSize(int width, int height) { - mWidth = width; - mHeight = height; delete[] mMetaTiles; delete[] mTiles; - mMetaTiles = new MetaTile[mWidth * mHeight]; - mTiles = new Image*[mWidth * mHeight * 3]; + + mWidth = width; + mHeight = height; + + int size = width * height; + + mMetaTiles = new MetaTile[size]; + mTiles = new Image*[size * 3]; + std::fill_n(mTiles, size * 3, (Image*)0); } void @@ -330,8 +338,8 @@ Map::getWalk(int x, int y) /* // Check for collision with a being - Beings *beings = beingManager->getAll(); - for (BeingIterator i = beings->begin(); i != beings->end(); i++) { + Beings &beings = beingManager->getAll(); + for (BeingIterator i = beings.begin(); i != beings.end(); i++) { // job 45 is a portal, they don't collide if ((*i)->mX / 32 == x && (*i)->mY / 32 == y && (*i)->mJob != 45) { return false; diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp index c4192bc5..3f7e8709 100644 --- a/src/net/inventoryhandler.cpp +++ b/src/net/inventoryhandler.cpp @@ -92,14 +92,9 @@ void InventoryHandler::handleMessage(MessageIn &msg) if (msg.readByte()> 0) { chatWindow->chatLog("Unable to pick up item", BY_SERVER); } else { - ItemInfo *itemInfo = itemDb->getItemInfo(itemId); - if (itemInfo) { - chatWindow->chatLog("You picked up a " + - itemInfo->getName(), BY_SERVER); - } else { - chatWindow->chatLog("You picked up an unknown item", - BY_SERVER); - } + const ItemInfo &itemInfo = itemDb->getItemInfo(itemId); + chatWindow->chatLog("You picked up a " + + itemInfo.getName(), BY_SERVER); player_node->addInvItem(index, itemId, amount, equipType != 0); } break; diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 51899d3f..eb3a2409 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -260,11 +260,18 @@ void Image::unload() { mLoaded = false; - if (!mImage) return; + if (mImage) { + // Free the image surface. + SDL_FreeSurface(mImage); + mImage = NULL; + } - // Free the image surface. - SDL_FreeSurface(mImage); - mImage = NULL; +#ifdef USE_OPENGL + if (mGLImage) { + glDeleteTextures(1, &mGLImage); + mGLImage = 0; + } +#endif } Image *Image::getSubImage(int x, int y, int width, int height) @@ -341,7 +348,11 @@ SubImage::SubImage(Image *parent, GLuint image, SubImage::~SubImage() { - mImage = 0; // Avoid destruction of the image + // Avoid destruction of the image + mImage = 0; +#ifdef USE_OPENGL + mGLImage = 0; +#endif mParent->decRef(); } diff --git a/src/resources/image.h b/src/resources/image.h index 78751394..a1ab7f48 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -28,6 +28,13 @@ #include #ifdef USE_OPENGL + +/* The definition of OpenGL extensions by SDL is giving problems with recent + * gl.h headers, since they also include these definitions. As we're not using + * extensions anyway it's safe to just disable the SDL version. + */ +#define NO_SDL_GLEXT + #include #endif diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp index 5d39d832..b09d1cc0 100644 --- a/src/resources/iteminfo.cpp +++ b/src/resources/iteminfo.cpp @@ -23,22 +23,33 @@ #include "iteminfo.h" #include "resourcemanager.h" +#include "image.h" -Image* -ItemInfo::getImage() { - if (mImage == NULL && mImageName != "") { - mImage = ResourceManager::getInstance()->getImage(mImageName); + +ItemInfo::~ItemInfo() +{ + if (mImage != NULL) + { + mImage->decRef(); } - return mImage; } void -ItemInfo::setImage(const std::string &image) { +ItemInfo::setImage(const std::string &image) +{ mImageName = "graphics/items/" + image; -} -ItemInfo::~ItemInfo() { - if (mImage != NULL){ - mImage->decRef(); + if (mImageName != "") + { + if (mImage != NULL) + { + mImage->decRef(); + } + + mImage = ResourceManager::getInstance()->getImage(mImageName); + } + else + { + mImage = NULL; } } diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index afa2e857..9a04bb2e 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -26,7 +26,7 @@ #include -#include "image.h" +class Image; /** * Defines a class for storing item infos. @@ -40,8 +40,8 @@ class ItemInfo * Constructor. */ ItemInfo(): - mImage(NULL), mImageName(""), + mImage(NULL), mArt(0), mType(0), mWeight(0), @@ -53,19 +53,19 @@ class ItemInfo setArt(short art) { mArt = art; } short - getArt() { return mArt; } + getArt() const { return mArt; } void setName(const std::string &name) { mName = name; } - std::string - getName() { return mName; } + const std::string& + getName() const { return mName; } void setImage(const std::string &image); Image* - getImage(); + getImage() const { return mImage; } void setDescription(const std::string &description) @@ -73,32 +73,32 @@ class ItemInfo mDescription = description; } - std::string - getDescription() { return mDescription; } + const std::string& + getDescription() const { return mDescription; } void setEffect(const std::string &effect) { mEffect = effect; } - std::string - getEffect() { return mEffect; } + const std::string& + getEffect() const { return mEffect; } void setType(short type) { mType = type; } short - getType() { return mType; } + getType() const { return mType; } void setWeight(short weight) { mWeight = weight; } short - getWeight() { return mWeight; } + getWeight() const { return mWeight; } void setSlot(char slot) { mSlot = slot; } char - getSlot() { return mSlot; } + getSlot() const { return mSlot; } protected: /** @@ -106,8 +106,14 @@ class ItemInfo */ ~ItemInfo(); - Image* mImage; std::string mImageName; + + /* TODO (BL): I do not think the item info should keep a reference to + * the item icon. It would probably be better if this was kept in the + * Item class, so that the images can be lazily instantiated and also + * unloaded when no longer used. + */ + Image *mImage; short mArt; std::string mName; std::string mDescription; diff --git a/src/resources/itemmanager.cpp b/src/resources/itemmanager.cpp index a497b3c8..7d0b13f2 100644 --- a/src/resources/itemmanager.cpp +++ b/src/resources/itemmanager.cpp @@ -41,8 +41,7 @@ ItemManager::ItemManager() { - mUnknown = new ItemInfo(); - mUnknown->setName("Unknown item"); + mUnknown.setName("Unknown item"); ResourceManager *resman = ResourceManager::getInstance(); int size; @@ -163,14 +162,12 @@ ItemManager::~ItemManager() delete i->second; } mItemInfos.clear(); - - delete mUnknown; } -ItemInfo* +const ItemInfo& ItemManager::getItemInfo(int id) { ItemInfoIterator i = mItemInfos.find(id); - return (i != mItemInfos.end()) ? i->second : mUnknown; + return (i != mItemInfos.end()) ? *(i->second) : mUnknown; } diff --git a/src/resources/itemmanager.h b/src/resources/itemmanager.h index 06eee507..b1f2b95c 100644 --- a/src/resources/itemmanager.h +++ b/src/resources/itemmanager.h @@ -24,9 +24,9 @@ #ifndef _TMW_ITEM_MANAGER_H #define _TMW_ITEM_MANAGER_H -#include +#include "iteminfo.h" -class ItemInfo; +#include /** * Defines a class to load items database. @@ -44,14 +44,14 @@ class ItemManager */ ~ItemManager(); - ItemInfo *getItemInfo(int id); + const ItemInfo& getItemInfo(int id); protected: // Items database typedef std::map ItemInfos; typedef ItemInfos::iterator ItemInfoIterator; ItemInfos mItemInfos; - ItemInfo *mUnknown; + ItemInfo mUnknown; }; extern ItemManager *itemDb; diff --git a/src/tmw.rc b/src/tmw.rc index 31411b61..388b643d 100644 --- a/src/tmw.rc +++ b/src/tmw.rc @@ -7,8 +7,8 @@ A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "data/icons/tmw-icon.ico" // TO CHANGE VERSION INFORMATION, EDIT PROJECT OPTIONS... // 1 VERSIONINFO -FILEVERSION 0,0,20,0 -PRODUCTVERSION 0,0,20,0 +FILEVERSION 0,0,21,0 +PRODUCTVERSION 0,0,21,0 FILETYPE VFT_APP { BLOCK "StringFileInfo" @@ -16,14 +16,14 @@ FILETYPE VFT_APP BLOCK "040904E4" { VALUE "CompanyName", "The Mana World Development Team" - VALUE "FileVersion", "0.0.20" + VALUE "FileVersion", "0.0.21" VALUE "FileDescription", "The Mana World" VALUE "InternalName", "tmw.exe" VALUE "LegalCopyright", "2004-2006 (C)" VALUE "LegalTrademarks", "" VALUE "OriginalFilename", "tmw.exe" VALUE "ProductName", "The Mana World MMORPG" - VALUE "ProductVersion", "0.0.20" + VALUE "ProductVersion", "0.0.21" } } BLOCK "VarFileInfo" diff --git a/tools/Reorganize.java b/tools/Reorganize.java index 19a17b99..22f42604 100644 --- a/tools/Reorganize.java +++ b/tools/Reorganize.java @@ -12,7 +12,7 @@ import java.io.File; import javax.imageio.ImageIO; /** - * Very simple tool to reorganize the monster spritesets. + * Tool to reorganize the hair spritesets. */ public class Reorganize { @@ -20,6 +20,12 @@ public class Reorganize private static final int SPRITE_HEIGHT = 60; private static final int FRAMES = 10; private static final int DIRECTIONS = 4; + + private static final int HAIR_COLORS = 10; + private static final int HAIR_FRAMES = 9; + private static final int HAIR_SPRITE_WIDTH = 40; + private static final int HAIR_SPRITE_HEIGHT = 40; + private static final int TRANSPARENT = new Color(255, 0, 255).getRGB(); public static void main(String[] arg) @@ -38,30 +44,15 @@ public class Reorganize System.exit(1); } - Rectangle cropRect = null; - - // Read the existing frames into a vector and determine minimal - // rectangle that still can contain the contents of any frame. - Vector spriteSet = new Vector(); - for (int x = 0; x < DIRECTIONS; x++) { - for (int y = 0; y < FRAMES; y++) { - BufferedImage sprite = source.getSubimage( - x * SPRITE_WIDTH, - y * SPRITE_HEIGHT, - SPRITE_WIDTH, - SPRITE_HEIGHT); - - spriteSet.add(sprite); + // Read the existing frames into a vector + Vector spriteSet = gridCut(source, + HAIR_SPRITE_WIDTH, HAIR_SPRITE_HEIGHT, + HAIR_FRAMES, HAIR_COLORS); - Rectangle frameCropRect = determineCropRect(sprite); - - if (cropRect == null) { - cropRect = frameCropRect; - } else { - cropRect.add(frameCropRect); - } - } - } + // Determine minimal rectangle that can still contain the contents of + // any frame + /* + Rectangle cropRect = minimumCropRect(spriteSet); if (cropRect == null) { System.out.println( @@ -76,19 +67,61 @@ public class Reorganize System.out.println(arg[0] + ": width=\"" + cropRect.width + "\" height=\"" + cropRect.height + "\""); + */ + + filterHairstyle(spriteSet); + + BufferedImage target = gridDraw( + spriteSet, + new Rectangle(0, 0, HAIR_SPRITE_WIDTH, HAIR_SPRITE_HEIGHT), + HAIR_FRAMES - 4, HAIR_COLORS); - // Create a new image (with frame direction flipped) + // Save the target image + try { + ImageIO.write(target, "png", new File(arg[1])); + } catch (IOException e) { + System.out.println("Error while trying to write " + arg[1] + "."); + e.printStackTrace(); + System.exit(1); + } + } + + private static Vector gridCut( + BufferedImage source, + int width, int height, int xFrames, int yFrames) + { + Vector spriteSet = new Vector(); + + for (int y = 0; y < yFrames; y++) { + for (int x = 0; x < xFrames; x++) { + BufferedImage sprite = source.getSubimage( + x * width, + y * height, + width, + height); + + spriteSet.add(sprite); + } + } + + return spriteSet; + } + + private static BufferedImage gridDraw(Vector spriteSet, + Rectangle cropRect, int xFrames, int yFrames) + { + // Create a new image BufferedImage target = new BufferedImage( - FRAMES * cropRect.width, - DIRECTIONS * cropRect.height, + xFrames * cropRect.width, + yFrames * cropRect.height, BufferedImage.TYPE_INT_ARGB); // Draw the frames onto the target image Graphics g = target.getGraphics(); - for (int y = 0; y < DIRECTIONS; y++) { - for (int x = 0; x < FRAMES; x++) { + for (int y = 0; y < yFrames; y++) { + for (int x = 0; x < xFrames; x++) { g.drawImage( - spriteSet.get(x + FRAMES * y).getSubimage( + spriteSet.get(x + xFrames * y).getSubimage( cropRect.x, cropRect.y, cropRect.width, @@ -99,14 +132,24 @@ public class Reorganize } } - // Save the target image - try { - ImageIO.write(target, "png", new File(arg[1])); - } catch (IOException e) { - System.out.println("Error while trying to write " + arg[1] + "."); - e.printStackTrace(); - System.exit(1); + return target; + } + + private static Rectangle minimumCropRect(Vector spriteSet) + { + Rectangle cropRect = null; + + for (BufferedImage sprite : spriteSet) { + Rectangle frameCropRect = determineCropRect(sprite); + + if (cropRect == null) { + cropRect = frameCropRect; + } else { + cropRect.add(frameCropRect); + } } + + return cropRect; } private static Rectangle determineCropRect(BufferedImage image) @@ -130,4 +173,15 @@ public class Reorganize return rect; } + + private static void filterHairstyle(Vector spriteSet) + { + // Remove frame 1, 2, 6 and 7 from each color + for (int i = HAIR_COLORS - 1; i >= 0; i--) { + spriteSet.remove(i * HAIR_FRAMES + 7); + spriteSet.remove(i * HAIR_FRAMES + 6); + spriteSet.remove(i * HAIR_FRAMES + 2); + spriteSet.remove(i * HAIR_FRAMES + 1); + } + } } -- cgit v1.2.3-70-g09d2