From c7e7b62aa94bf295ca1dc556762ad6070221e0cd Mon Sep 17 00:00:00 2001 From: Eugenio Favalli Date: Tue, 25 Jul 2006 18:04:38 +0000 Subject: Switched client to use enet and modified login sequence to work with the new protocol from tmwserv. --- src/net/chathandler.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/net/chathandler.cpp') diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index 9095a4e1..d6f822f8 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -62,8 +62,8 @@ void ChatHandler::handleMessage(MessageIn *msg) { // Received speech from being case SMSG_BEING_CHAT: - chatMsgLength = msg->readInt16() - 8; - being = beingManager->findBeing(msg->readInt32()); + chatMsgLength = msg->readShort() - 8; + being = beingManager->findBeing(msg->readLong()); if (!being || chatMsgLength <= 0) { @@ -78,7 +78,7 @@ void ChatHandler::handleMessage(MessageIn *msg) case SMSG_PLAYER_CHAT: case SMSG_GM_CHAT: - chatMsgLength = msg->readInt16() - 4; + chatMsgLength = msg->readShort() - 4; if (chatMsgLength <= 0) { @@ -105,13 +105,13 @@ void ChatHandler::handleMessage(MessageIn *msg) break; case SMSG_WHO_ANSWER: - chatWindow->chatLog("Online users: " + toString(msg->readInt32()), + chatWindow->chatLog("Online users: " + toString(msg->readLong()), BY_SERVER); break; case 0x010c: // Display MVP player - msg->readInt32(); // id + msg->readLong(); // id chatWindow->chatLog("MVP player", BY_SERVER); break; } -- cgit v1.2.3-70-g09d2 From 2fe42d32c6d368a66586c605cc1b38ee8d85ed1d Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Sun, 20 Aug 2006 16:14:12 +0000 Subject: Changed MessageHandler::handleMessage to take a reference instead of a pointer. Removed unused Packet class. Added stub for handling GPMSG_BEING_ENTER. --- ChangeLog | 3 + src/Makefile.am | 2 - src/net/beinghandler.cpp | 237 +++++++++++++++++++++++------------------- src/net/beinghandler.h | 6 +- src/net/buysellhandler.cpp | 32 +++--- src/net/buysellhandler.h | 2 +- src/net/charserverhandler.cpp | 28 ++--- src/net/charserverhandler.h | 5 +- src/net/chathandler.cpp | 20 ++-- src/net/chathandler.h | 2 +- src/net/equipmenthandler.cpp | 46 ++++---- src/net/equipmenthandler.h | 2 +- src/net/inventoryhandler.cpp | 58 +++++------ src/net/inventoryhandler.h | 2 +- src/net/itemhandler.cpp | 16 +-- src/net/itemhandler.h | 2 +- src/net/loginhandler.cpp | 8 +- src/net/loginhandler.h | 2 +- src/net/maploginhandler.cpp | 6 +- src/net/maploginhandler.h | 2 +- src/net/messagehandler.h | 2 +- src/net/messagein.cpp | 2 - src/net/messageout.cpp | 2 - src/net/network.cpp | 2 +- src/net/npchandler.cpp | 18 ++-- src/net/npchandler.h | 2 +- src/net/packet.cpp | 40 ------- src/net/packet.h | 47 --------- src/net/playerhandler.cpp | 112 ++++++++++---------- src/net/playerhandler.h | 2 +- src/net/skillhandler.cpp | 34 +++--- src/net/skillhandler.h | 2 +- src/net/tradehandler.cpp | 26 ++--- src/net/tradehandler.h | 2 +- 34 files changed, 358 insertions(+), 416 deletions(-) delete mode 100644 src/net/packet.cpp delete mode 100644 src/net/packet.h (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index 12e30213..8f589dcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,9 @@ selection of player character and implemented sending of game and chat server tokens. It gets you in the game (or what's left of it), but not on any map yet. + * src/net/*: Changed MessageHandler::handleMessage to take a reference + instead of a pointer. Removed unused Packet class. Added stub for + handling GPMSG_BEING_ENTER. 2006-08-19 Bjørn Lindeijer diff --git a/src/Makefile.am b/src/Makefile.am index 42671f64..8f40c506 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -146,8 +146,6 @@ tmw_SOURCES = graphic/imagerect.h \ net/network.h \ net/npchandler.cpp \ net/npchandler.h \ - net/packet.cpp \ - net/packet.h \ net/playerhandler.cpp \ net/playerhandler.h \ net/protocol.cpp \ diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp index 549797f9..ed0fc4b2 100644 --- a/src/net/beinghandler.cpp +++ b/src/net/beinghandler.cpp @@ -41,24 +41,25 @@ const int EMOTION_TIME = 150; /**< Duration of emotion icon */ BeingHandler::BeingHandler() { static const Uint16 _messages[] = { - SMSG_BEING_VISIBLE, - SMSG_BEING_MOVE, - SMSG_BEING_REMOVE, - SMSG_BEING_ACTION, - SMSG_BEING_LEVELUP, - SMSG_BEING_EMOTION, - SMSG_BEING_CHANGE_LOOKS, - SMSG_BEING_NAME_RESPONSE, - SMSG_PLAYER_UPDATE_1, - SMSG_PLAYER_UPDATE_2, - SMSG_PLAYER_MOVE, - 0x0119, + //SMSG_BEING_VISIBLE, + //SMSG_BEING_MOVE, + //SMSG_BEING_REMOVE, + //SMSG_BEING_ACTION, + //SMSG_BEING_LEVELUP, + //SMSG_BEING_EMOTION, + //SMSG_BEING_CHANGE_LOOKS, + //SMSG_BEING_NAME_RESPONSE, + //SMSG_PLAYER_UPDATE_1, + //SMSG_PLAYER_UPDATE_2, + //SMSG_PLAYER_MOVE, + //0x0119, + GPMSG_BEING_ENTER, 0 }; handledMessages = _messages; } -void BeingHandler::handleMessage(MessageIn *msg) +void BeingHandler::handleMessage(MessageIn &msg) { Uint32 id; Uint16 job, speed; @@ -66,17 +67,21 @@ void BeingHandler::handleMessage(MessageIn *msg) Sint8 type; Being *srcBeing, *dstBeing; - switch (msg->getId()) + switch (msg.getId()) { + case GPMSG_BEING_ENTER: + handleBeingEnterMessage(msg); + break; + case SMSG_BEING_VISIBLE: case SMSG_BEING_MOVE: // Information about a being in range - id = msg->readLong(); - speed = msg->readShort(); - msg->readShort(); // unknown - msg->readShort(); // unknown - msg->readShort(); // option - job = msg->readShort(); // class + id = msg.readLong(); + speed = msg.readShort(); + msg.readShort(); // unknown + msg.readShort(); // unknown + msg.readShort(); // option + job = msg.readShort(); // class dstBeing = beingManager->findBeing(id); @@ -91,7 +96,7 @@ void BeingHandler::handleMessage(MessageIn *msg) dstBeing = beingManager->createBeing(id, job); } - else if (msg->getId() == 0x0078) + else if (msg.getId() == 0x0078) { dstBeing->clearPath(); dstBeing->mFrame = 0; @@ -104,33 +109,33 @@ void BeingHandler::handleMessage(MessageIn *msg) dstBeing->setWalkSpeed(speed); dstBeing->mJob = job; - dstBeing->setHairStyle(msg->readShort()); - dstBeing->setWeapon(msg->readShort()); - dstBeing->setVisibleEquipment(3, msg->readShort()); // head bottom + dstBeing->setHairStyle(msg.readShort()); + dstBeing->setWeapon(msg.readShort()); + dstBeing->setVisibleEquipment(3, msg.readShort()); // head bottom - if (msg->getId() == SMSG_BEING_MOVE) + if (msg.getId() == SMSG_BEING_MOVE) { - msg->readLong(); // server tick + msg.readLong(); // server tick } - msg->readShort(); // shield - dstBeing->setVisibleEquipment(4, msg->readShort()); // head top - dstBeing->setVisibleEquipment(5, msg->readShort()); // head mid - dstBeing->setHairColor(msg->readShort()); - msg->readShort(); // unknown - msg->readShort(); // head dir - msg->readShort(); // guild - msg->readShort(); // unknown - msg->readShort(); // unknown - msg->readShort(); // manner - msg->readShort(); // karma - msg->readByte(); // unknown - dstBeing->setSex(1 - msg->readByte()); // sex - - if (msg->getId() == SMSG_BEING_MOVE) + msg.readShort(); // shield + dstBeing->setVisibleEquipment(4, msg.readShort()); // head top + dstBeing->setVisibleEquipment(5, msg.readShort()); // head mid + dstBeing->setHairColor(msg.readShort()); + msg.readShort(); // unknown + msg.readShort(); // head dir + msg.readShort(); // guild + msg.readShort(); // unknown + msg.readShort(); // unknown + msg.readShort(); // manner + msg.readShort(); // karma + msg.readByte(); // unknown + dstBeing->setSex(1 - msg.readByte()); // sex + + if (msg.getId() == SMSG_BEING_MOVE) { //Uint16 srcX, srcY, dstX, dstY; - //msg->readCoordinatePair(srcX, srcY, dstX, dstY); + //msg.readCoordinatePair(srcX, srcY, dstX, dstY); //dstBeing->setAction(Being::STAND); //dstBeing->mX = srcX; //dstBeing->mY = srcY; @@ -138,22 +143,22 @@ void BeingHandler::handleMessage(MessageIn *msg) } else { - //msg->readCoordinates(dstBeing->mX, dstBeing->mY, dstBeing->mDirection); + //msg.readCoordinates(dstBeing->mX, dstBeing->mY, dstBeing->mDirection); } - msg->readByte(); // unknown - msg->readByte(); // unknown - msg->readByte(); // unknown / sit + msg.readByte(); // unknown + msg.readByte(); // unknown + msg.readByte(); // unknown / sit break; case SMSG_BEING_REMOVE: // A being should be removed or has died - dstBeing = beingManager->findBeing(msg->readLong()); + dstBeing = beingManager->findBeing(msg.readLong()); if (!dstBeing) break; - if (msg->readByte() == 1) + if (msg.readByte() == 1) { // Death switch (dstBeing->getType()) @@ -181,15 +186,15 @@ void BeingHandler::handleMessage(MessageIn *msg) break; case SMSG_BEING_ACTION: - srcBeing = beingManager->findBeing(msg->readLong()); - dstBeing = beingManager->findBeing(msg->readLong()); - msg->readLong(); // server tick - msg->readLong(); // src speed - msg->readLong(); // dst speed - param1 = msg->readShort(); - msg->readShort(); // param 2 - type = msg->readByte(); - msg->readShort(); // param 3 + srcBeing = beingManager->findBeing(msg.readLong()); + dstBeing = beingManager->findBeing(msg.readLong()); + msg.readLong(); // server tick + msg.readLong(); // src speed + msg.readLong(); // dst speed + param1 = msg.readShort(); + msg.readShort(); // param 2 + type = msg.readByte(); + msg.readShort(); // param 3 switch (type) { @@ -230,63 +235,63 @@ void BeingHandler::handleMessage(MessageIn *msg) break; case SMSG_BEING_LEVELUP: - if ((Uint32)msg->readLong() == player_node->getId()) { + if ((Uint32) msg.readLong() == player_node->getId()) { logger->log("Level up"); sound.playSfx("sfx/levelup.ogg"); } else { logger->log("Someone else went level up"); } - msg->readLong(); // type + msg.readLong(); // type break; case SMSG_BEING_EMOTION: - if (!(dstBeing = beingManager->findBeing(msg->readLong()))) + if (!(dstBeing = beingManager->findBeing(msg.readLong()))) { break; } - dstBeing->mEmotion = msg->readByte(); + dstBeing->mEmotion = msg.readByte(); dstBeing->mEmotionTime = EMOTION_TIME; break; case SMSG_BEING_CHANGE_LOOKS: { - if (!(dstBeing = beingManager->findBeing(msg->readLong()))) + if (!(dstBeing = beingManager->findBeing(msg.readLong()))) { break; } - int type = msg->readByte(); + int type = msg.readByte(); switch (type) { case 1: - dstBeing->setHairStyle(msg->readByte()); + dstBeing->setHairStyle(msg.readByte()); break; case 2: - dstBeing->setWeapon(msg->readByte()); + dstBeing->setWeapon(msg.readByte()); break; case 3: case 4: case 5: // Equip/unequip head 3. Bottom 4. Top 5. Middle - dstBeing->setVisibleEquipment(type, msg->readByte()); + dstBeing->setVisibleEquipment(type, msg.readByte()); // First 3 slots of mVisibleEquipments are reserved for // later use, probably accessories. break; case 6: - dstBeing->setHairColor(msg->readByte()); + dstBeing->setHairColor(msg.readByte()); break; default: - printf("c3: %i\n", msg->readByte()); // unsupported + printf("c3: %i\n", msg.readByte()); // unsupported break; } } break; case SMSG_BEING_NAME_RESPONSE: - if ((dstBeing = beingManager->findBeing(msg->readLong()))) + if ((dstBeing = beingManager->findBeing(msg.readLong()))) { - dstBeing->setName(msg->readString(24)); + dstBeing->setName(msg.readString(24)); } break; @@ -294,12 +299,12 @@ void BeingHandler::handleMessage(MessageIn *msg) case SMSG_PLAYER_UPDATE_2: case SMSG_PLAYER_MOVE: // An update about a player, potentially including movement. - id = msg->readLong(); - speed = msg->readShort(); - msg->readShort(); // option 1 - msg->readShort(); // option 2 - msg->readShort(); // option - job = msg->readShort(); + id = msg.readLong(); + speed = msg.readShort(); + msg.readShort(); // option 1 + msg.readShort(); // option 2 + msg.readShort(); // option + job = msg.readShort(); dstBeing = beingManager->findBeing(id); @@ -310,57 +315,57 @@ void BeingHandler::handleMessage(MessageIn *msg) dstBeing->setWalkSpeed(speed); dstBeing->mJob = job; - dstBeing->setHairStyle(msg->readShort()); - dstBeing->setWeaponById(msg->readShort()); // item id 1 - msg->readShort(); // item id 2 - dstBeing->setVisibleEquipment(3, msg->readShort()); // head bottom + dstBeing->setHairStyle(msg.readShort()); + dstBeing->setWeaponById(msg.readShort()); // item id 1 + msg.readShort(); // item id 2 + dstBeing->setVisibleEquipment(3, msg.readShort()); // head bottom - if (msg->getId() == SMSG_PLAYER_MOVE) + if (msg.getId() == SMSG_PLAYER_MOVE) { - msg->readLong(); // server tick + msg.readLong(); // server tick } - dstBeing->setVisibleEquipment(4, msg->readShort()); // head top - dstBeing->setVisibleEquipment(5, msg->readShort()); // head mid - dstBeing->setHairColor(msg->readShort()); - msg->readShort(); // unknown - msg->readShort(); // head dir - msg->readLong(); // guild - msg->readLong(); // emblem - msg->readShort(); // manner - msg->readByte(); // karma - dstBeing->setSex(1 - msg->readByte()); // sex - - if (msg->getId() == SMSG_PLAYER_MOVE) + dstBeing->setVisibleEquipment(4, msg.readShort()); // head top + dstBeing->setVisibleEquipment(5, msg.readShort()); // head mid + dstBeing->setHairColor(msg.readShort()); + msg.readShort(); // unknown + msg.readShort(); // head dir + msg.readLong(); // guild + msg.readLong(); // emblem + msg.readShort(); // manner + msg.readByte(); // karma + dstBeing->setSex(1 - msg.readByte()); // sex + + if (msg.getId() == SMSG_PLAYER_MOVE) { //Uint16 srcX, srcY, dstX, dstY; - //msg->readCoordinatePair(srcX, srcY, dstX, dstY); + //msg.readCoordinatePair(srcX, srcY, dstX, dstY); //dstBeing->mX = srcX; //dstBeing->mY = srcY; //dstBeing->setDestination(dstX, dstY); } else { - //msg->readCoordinates(dstBeing->mX, dstBeing->mY, dstBeing->mDirection); + //msg.readCoordinates(dstBeing->mX, dstBeing->mY, dstBeing->mDirection); } - msg->readByte(); // unknown - msg->readByte(); // unknown + msg.readByte(); // unknown + msg.readByte(); // unknown - if (msg->getId() == SMSG_PLAYER_UPDATE_1) + if (msg.getId() == SMSG_PLAYER_UPDATE_1) { - if (msg->readByte() == 2) + if (msg.readByte() == 2) { dstBeing->setAction(Being::SIT); } } - else if (msg->getId() == SMSG_PLAYER_MOVE) + else if (msg.getId() == SMSG_PLAYER_MOVE) { - msg->readByte(); // unknown + msg.readByte(); // unknown } - msg->readByte(); // Lv - msg->readByte(); // unknown + msg.readByte(); // Lv + msg.readByte(); // unknown dstBeing->mWalkTime = tick_time; dstBeing->mFrame = 0; @@ -368,9 +373,27 @@ void BeingHandler::handleMessage(MessageIn *msg) case 0x0119: // Change in players look - printf("0x0119 %li %i %i %x %i\n", msg->readLong(), - msg->readShort(), msg->readShort(), msg->readShort(), - msg->readByte()); + printf("0x0119 %li %i %i %x %i\n", msg.readLong(), + msg.readShort(), msg.readShort(), msg.readShort(), + msg.readByte()); break; } } + +void +BeingHandler::handleBeingEnterMessage(MessageIn &msg) +{ + // Not sure what do to exactly with this message yet. + /* + unsigned char type = msg.readByte(); + unsigned long id = msg.readLong(); + + if (type == OBJECT_PLAYER) + { + std::string name = msg.readString(); + unsigned char hairStyle = msg.readByte(); + unsigned char hairColor = msg.readByte(); + unsigned char gender = msg.readByte(); + } + */ +} diff --git a/src/net/beinghandler.h b/src/net/beinghandler.h index 03012f39..2dd81e1a 100644 --- a/src/net/beinghandler.h +++ b/src/net/beinghandler.h @@ -31,7 +31,11 @@ class BeingHandler : public MessageHandler public: BeingHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); + + private: + void + handleBeingEnterMessage(MessageIn &msg); }; #endif diff --git a/src/net/buysellhandler.cpp b/src/net/buysellhandler.cpp index 3b5fc87d..173c59d2 100644 --- a/src/net/buysellhandler.cpp +++ b/src/net/buysellhandler.cpp @@ -54,10 +54,10 @@ BuySellHandler::BuySellHandler() handledMessages = _messages; } -void BuySellHandler::handleMessage(MessageIn *msg) +void BuySellHandler::handleMessage(MessageIn &msg) { int n_items; - switch (msg->getId()) + switch (msg.getId()) { case SMSG_NPC_BUY_SELL_CHOICE: buyDialog->setVisible(false); @@ -65,38 +65,38 @@ void BuySellHandler::handleMessage(MessageIn *msg) sellDialog->setVisible(false); sellDialog->reset(); buySellDialog->setVisible(true); - current_npc = dynamic_cast(beingManager->findBeing(msg->readLong())); + current_npc = dynamic_cast(beingManager->findBeing(msg.readLong())); break; case SMSG_NPC_BUY: - msg->readShort(); // length - n_items = (msg->getLength() - 4) / 11; + msg.readShort(); // length + n_items = (msg.getLength() - 4) / 11; buyDialog->reset(); buyDialog->setMoney(player_node->mMoney); buyDialog->setVisible(true); for (int k = 0; k < n_items; k++) { - Sint32 value = msg->readLong(); - msg->readLong(); // DCvalue - msg->readByte(); // type - Sint16 itemId = msg->readShort(); + Sint32 value = msg.readLong(); + msg.readLong(); // DCvalue + msg.readByte(); // type + Sint16 itemId = msg.readShort(); buyDialog->addItem(itemId, value); } break; case SMSG_NPC_SELL: - msg->readShort(); // length - n_items = (msg->getLength() - 4) / 10; + msg.readShort(); // length + n_items = (msg.getLength() - 4) / 10; if (n_items > 0) { sellDialog->reset(); sellDialog->setVisible(true); for (int k = 0; k < n_items; k++) { - Sint16 index = msg->readShort(); - Sint32 value = msg->readLong(); - msg->readLong(); // OCvalue + Sint16 index = msg.readShort(); + Sint32 value = msg.readLong(); + msg.readLong(); // OCvalue Item *item = player_node->getInvItem(index); if (item && !(item->isEquipped())) { @@ -111,7 +111,7 @@ void BuySellHandler::handleMessage(MessageIn *msg) break; case SMSG_NPC_BUY_RESPONSE: - if (msg->readByte() == 0) { + if (msg.readByte() == 0) { chatWindow->chatLog("Thanks for buying", BY_SERVER); } else { chatWindow->chatLog("Unable to buy", BY_SERVER); @@ -119,7 +119,7 @@ void BuySellHandler::handleMessage(MessageIn *msg) break; case SMSG_NPC_SELL_RESPONSE: - if (msg->readByte() == 0) { + if (msg.readByte() == 0) { chatWindow->chatLog("Thanks for selling", BY_SERVER); } else { chatWindow->chatLog("Unable to sell", BY_SERVER); diff --git a/src/net/buysellhandler.h b/src/net/buysellhandler.h index 673aaac1..e242d373 100644 --- a/src/net/buysellhandler.h +++ b/src/net/buysellhandler.h @@ -31,7 +31,7 @@ class BuySellHandler : public MessageHandler public: BuySellHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp index 2bf2c4b4..5a2be683 100644 --- a/src/net/charserverhandler.cpp +++ b/src/net/charserverhandler.cpp @@ -48,20 +48,20 @@ CharServerHandler::CharServerHandler() } void -CharServerHandler::handleMessage(MessageIn *msg) +CharServerHandler::handleMessage(MessageIn &msg) { int slot; LocalPlayer *tempPlayer; - switch (msg->getId()) + switch (msg.getId()) { case APMSG_CHAR_CREATE_RESPONSE: - handleCharCreateResponse(*msg); + handleCharCreateResponse(msg); break; case APMSG_CHAR_DELETE_RESPONSE: { - int errMsg = msg->readByte(); + int errMsg = msg.readByte(); // Character deletion successful if (errMsg == ERRMSG_OK) { @@ -101,7 +101,7 @@ CharServerHandler::handleMessage(MessageIn *msg) break; case APMSG_CHAR_SELECT_RESPONSE: - handleCharSelectResponse(*msg); + handleCharSelectResponse(msg); break; } } @@ -193,18 +193,18 @@ CharServerHandler::handleCharSelectResponse(MessageIn &msg) } LocalPlayer* -CharServerHandler::readPlayerData(MessageIn *msg, int &slot) +CharServerHandler::readPlayerData(MessageIn &msg, int &slot) { LocalPlayer *tempPlayer = new LocalPlayer(mLoginData->account_ID, 0, NULL); - slot = msg->readByte(); // character slot - tempPlayer->mName = msg->readString(); - tempPlayer->mSex = msg->readByte(); - tempPlayer->setHairStyle(msg->readByte()); - tempPlayer->setHairColor(msg->readByte()); - tempPlayer->mLevel = msg->readByte(); - tempPlayer->mMoney = msg->readShort(); + slot = msg.readByte(); // character slot + tempPlayer->mName = msg.readString(); + tempPlayer->mSex = msg.readByte(); + tempPlayer->setHairStyle(msg.readByte()); + tempPlayer->setHairColor(msg.readByte()); + tempPlayer->mLevel = msg.readByte(); + tempPlayer->mMoney = msg.readShort(); for (int i = 0; i < 6; i++) { - tempPlayer->mAttr[i] = msg->readByte(); + tempPlayer->mAttr[i] = msg.readByte(); } return tempPlayer; } diff --git a/src/net/charserverhandler.h b/src/net/charserverhandler.h index b034b513..9ad11c6a 100644 --- a/src/net/charserverhandler.h +++ b/src/net/charserverhandler.h @@ -37,7 +37,7 @@ class CharServerHandler : public MessageHandler CharServerHandler(); void - handleMessage(MessageIn *msg); + handleMessage(MessageIn &msg); void setCharInfo(LockedArray *charInfo) @@ -58,7 +58,8 @@ class CharServerHandler : public MessageHandler LoginData *mLoginData; LockedArray *mCharInfo; - LocalPlayer* readPlayerData(MessageIn *msg, int &slot); + LocalPlayer* + readPlayerData(MessageIn &msg, int &slot); }; #endif diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index d6f822f8..795b2a27 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -52,25 +52,25 @@ ChatHandler::ChatHandler() handledMessages = _messages; } -void ChatHandler::handleMessage(MessageIn *msg) +void ChatHandler::handleMessage(MessageIn &msg) { Being *being; std::string chatMsg; Sint16 chatMsgLength; - switch (msg->getId()) + switch (msg.getId()) { // Received speech from being case SMSG_BEING_CHAT: - chatMsgLength = msg->readShort() - 8; - being = beingManager->findBeing(msg->readLong()); + chatMsgLength = msg.readShort() - 8; + being = beingManager->findBeing(msg.readLong()); if (!being || chatMsgLength <= 0) { break; } - chatMsg = msg->readString(chatMsgLength); + chatMsg = msg.readString(chatMsgLength); chatWindow->chatLog(chatMsg, BY_OTHER); chatMsg.erase(0, chatMsg.find(" : ", 0) + 3); being->setSpeech(chatMsg, SPEECH_TIME); @@ -78,16 +78,16 @@ void ChatHandler::handleMessage(MessageIn *msg) case SMSG_PLAYER_CHAT: case SMSG_GM_CHAT: - chatMsgLength = msg->readShort() - 4; + chatMsgLength = msg.readShort() - 4; if (chatMsgLength <= 0) { break; } - chatMsg = msg->readString(chatMsgLength); + chatMsg = msg.readString(chatMsgLength); - if (msg->getId() == SMSG_PLAYER_CHAT) + if (msg.getId() == SMSG_PLAYER_CHAT) { chatWindow->chatLog(chatMsg, BY_PLAYER); @@ -105,13 +105,13 @@ void ChatHandler::handleMessage(MessageIn *msg) break; case SMSG_WHO_ANSWER: - chatWindow->chatLog("Online users: " + toString(msg->readLong()), + chatWindow->chatLog("Online users: " + toString(msg.readLong()), BY_SERVER); break; case 0x010c: // Display MVP player - msg->readLong(); // id + msg.readLong(); // id chatWindow->chatLog("MVP player", BY_SERVER); break; } diff --git a/src/net/chathandler.h b/src/net/chathandler.h index eed19206..e9db3575 100644 --- a/src/net/chathandler.h +++ b/src/net/chathandler.h @@ -31,7 +31,7 @@ class ChatHandler : public MessageHandler public: ChatHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/equipmenthandler.cpp b/src/net/equipmenthandler.cpp index aa372961..1c0fd4ca 100644 --- a/src/net/equipmenthandler.cpp +++ b/src/net/equipmenthandler.cpp @@ -48,7 +48,7 @@ EquipmentHandler::EquipmentHandler() handledMessages = _messages; } -void EquipmentHandler::handleMessage(MessageIn *msg) +void EquipmentHandler::handleMessage(MessageIn &msg) { Sint32 itemCount; Sint16 index, equipPoint, itemId; @@ -57,22 +57,22 @@ void EquipmentHandler::handleMessage(MessageIn *msg) Being *being; Item *item; - switch (msg->getId()) + switch (msg.getId()) { case SMSG_PLAYER_EQUIPMENT: - msg->readShort(); // length - itemCount = (msg->getLength() - 4) / 20; + msg.readShort(); // length + itemCount = (msg.getLength() - 4) / 20; for (int loop = 0; loop < itemCount; loop++) { - index = msg->readShort(); - itemId = msg->readShort(); - msg->readByte(); // type - msg->readByte(); // identify flag - msg->readShort(); // equip type - equipPoint = msg->readShort(); - msg->readByte(); // attribute - msg->readByte(); // refine + index = msg.readShort(); + itemId = msg.readShort(); + msg.readByte(); // type + msg.readByte(); // identify flag + msg.readShort(); // equip type + equipPoint = msg.readShort(); + msg.readByte(); // attribute + msg.readByte(); // refine player_node->addInvItem(index, itemId, 1, true); @@ -92,9 +92,9 @@ void EquipmentHandler::handleMessage(MessageIn *msg) break; case SMSG_PLAYER_EQUIP: - index = msg->readShort(); - equipPoint = msg->readShort(); - type = msg->readByte(); + index = msg.readShort(); + equipPoint = msg.readShort(); + type = msg.readByte(); logger->log("Equipping: %i %i %i", index, equipPoint, type); @@ -128,10 +128,10 @@ void EquipmentHandler::handleMessage(MessageIn *msg) case 0x01d7: // Equipment related - being = beingManager->findBeing(msg->readLong()); - msg->readByte(); // equip point - itemId = msg->readShort(); - msg->readShort(); // item id 2 + being = beingManager->findBeing(msg.readLong()); + msg.readByte(); // equip point + itemId = msg.readShort(); + msg.readShort(); // item id 2 if (!being) break; @@ -140,9 +140,9 @@ void EquipmentHandler::handleMessage(MessageIn *msg) break; case SMSG_PLAYER_UNEQUIP: - index = msg->readShort(); - equipPoint = msg->readShort(); - type = msg->readByte(); + index = msg.readShort(); + equipPoint = msg.readShort(); + type = msg.readByte(); if (!type) { chatWindow->chatLog("Unable to unequip.", BY_SERVER); @@ -192,7 +192,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg) break; case SMSG_PLAYER_ARROW_EQUIP: - itemId = msg->readShort(); + itemId = msg.readShort(); if (itemId <= 1) break; diff --git a/src/net/equipmenthandler.h b/src/net/equipmenthandler.h index 656f7a73..c9c65d67 100644 --- a/src/net/equipmenthandler.h +++ b/src/net/equipmenthandler.h @@ -31,7 +31,7 @@ class EquipmentHandler : public MessageHandler public: EquipmentHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp index 51c71f8d..cb1883b0 100644 --- a/src/net/inventoryhandler.cpp +++ b/src/net/inventoryhandler.cpp @@ -46,27 +46,27 @@ InventoryHandler::InventoryHandler() handledMessages = _messages; } -void InventoryHandler::handleMessage(MessageIn *msg) +void InventoryHandler::handleMessage(MessageIn &msg) { Sint32 number; Sint16 index, amount, itemId, equipType; - switch (msg->getId()) + switch (msg.getId()) { case SMSG_PLAYER_INVENTORY: // Only called on map load / warp. First reset all items // to not load them twice on map change. player_node->clearInventory(); - msg->readShort(); // length - number = (msg->getLength() - 4) / 18; + msg.readShort(); // length + number = (msg.getLength() - 4) / 18; for (int loop = 0; loop < number; loop++) { - index = msg->readShort(); - itemId = msg->readShort(); - msg->readByte(); // type - msg->readByte(); // identify flag - amount = msg->readShort(); + index = msg.readShort(); + itemId = msg.readShort(); + msg.readByte(); // type + msg.readByte(); // identify flag + amount = msg.readShort(); player_node->addInvItem(index, itemId, amount, false); @@ -79,16 +79,16 @@ void InventoryHandler::handleMessage(MessageIn *msg) break; case SMSG_PLAYER_INVENTORY_ADD: - index = msg->readShort(); - amount = msg->readShort(); - itemId = msg->readShort(); - msg->readByte(); // identify flag - msg->readByte(); // attribute - msg->readByte(); // refine - equipType = msg->readShort(); - msg->readByte(); // type - - if (msg->readByte()> 0) { + index = msg.readShort(); + amount = msg.readShort(); + itemId = msg.readShort(); + msg.readByte(); // identify flag + msg.readByte(); // attribute + msg.readByte(); // refine + equipType = msg.readShort(); + msg.readByte(); // type + + if (msg.readByte()> 0) { chatWindow->chatLog("Unable to pick up item", BY_SERVER); } else { player_node->addInvItem(index, itemId, amount, equipType != 0); @@ -96,26 +96,26 @@ void InventoryHandler::handleMessage(MessageIn *msg) break; case SMSG_PLAYER_INVENTORY_REMOVE: - index = msg->readShort(); - amount = msg->readShort(); + index = msg.readShort(); + amount = msg.readShort(); player_node->getInvItem(index)->increaseQuantity(-amount); break; case SMSG_PLAYER_INVENTORY_USE: - index = msg->readShort(); - msg->readShort(); // item id - msg->readLong(); // id - amount = msg->readShort(); - msg->readByte(); // type + index = msg.readShort(); + msg.readShort(); // item id + msg.readLong(); // id + amount = msg.readShort(); + msg.readByte(); // type player_node->getInvItem(index)->setQuantity(amount); break; case SMSG_ITEM_USE_RESPONSE: - index = msg->readShort(); - amount = msg->readShort(); + index = msg.readShort(); + amount = msg.readShort(); - if (msg->readByte() == 0) { + if (msg.readByte() == 0) { chatWindow->chatLog("Failed to use item", BY_SERVER); } else { player_node->getInvItem(index)->setQuantity(amount); diff --git a/src/net/inventoryhandler.h b/src/net/inventoryhandler.h index aedbc3a1..4190bf83 100644 --- a/src/net/inventoryhandler.h +++ b/src/net/inventoryhandler.h @@ -31,7 +31,7 @@ class InventoryHandler : public MessageHandler public: InventoryHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/itemhandler.cpp b/src/net/itemhandler.cpp index 23a9fa60..2961f71b 100644 --- a/src/net/itemhandler.cpp +++ b/src/net/itemhandler.cpp @@ -40,28 +40,28 @@ ItemHandler::ItemHandler() handledMessages = _messages; } -void ItemHandler::handleMessage(MessageIn *msg) +void ItemHandler::handleMessage(MessageIn &msg) { Uint32 id; Uint16 x, y; Sint16 itemId; - switch (msg->getId()) + switch (msg.getId()) { case SMSG_ITEM_VISIBLE: case SMSG_ITEM_DROPPED: - id = msg->readLong(); - itemId = msg->readShort(); - msg->readByte(); // identify flag - x = msg->readShort(); - y = msg->readShort(); + id = msg.readLong(); + itemId = msg.readShort(); + msg.readByte(); // identify flag + x = msg.readShort(); + y = msg.readShort(); floorItemManager->create(id, itemId, x, y, engine->getCurrentMap()); break; case SMSG_ITEM_REMOVE: FloorItem *item; - item = floorItemManager->findById(msg->readLong()); + item = floorItemManager->findById(msg.readLong()); if (item) floorItemManager->destroy(item); break; diff --git a/src/net/itemhandler.h b/src/net/itemhandler.h index b2104722..5ffcb134 100644 --- a/src/net/itemhandler.h +++ b/src/net/itemhandler.h @@ -31,7 +31,7 @@ class ItemHandler : public MessageHandler public: ItemHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp index 4790d7d1..700fb75a 100644 --- a/src/net/loginhandler.cpp +++ b/src/net/loginhandler.cpp @@ -41,13 +41,13 @@ LoginHandler::LoginHandler() handledMessages = _messages; } -void LoginHandler::handleMessage(MessageIn *msg) +void LoginHandler::handleMessage(MessageIn &msg) { - switch (msg->getId()) + switch (msg.getId()) { case APMSG_LOGIN_RESPONSE: { - int errMsg = msg->readByte(); + int errMsg = msg.readByte(); // Successful login if (errMsg == ERRMSG_OK) { @@ -79,7 +79,7 @@ void LoginHandler::handleMessage(MessageIn *msg) break; case APMSG_REGISTER_RESPONSE: { - int errMsg = msg->readByte(); + int errMsg = msg.readByte(); // Successful registration if (errMsg == ERRMSG_OK) { diff --git a/src/net/loginhandler.h b/src/net/loginhandler.h index 1b15b736..508ec0f5 100644 --- a/src/net/loginhandler.h +++ b/src/net/loginhandler.h @@ -36,7 +36,7 @@ class LoginHandler : public MessageHandler public: LoginHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); void setLoginData(LoginData *loginData) { mLoginData = loginData; }; diff --git a/src/net/maploginhandler.cpp b/src/net/maploginhandler.cpp index 579e8542..323e07fb 100644 --- a/src/net/maploginhandler.cpp +++ b/src/net/maploginhandler.cpp @@ -40,14 +40,14 @@ MapLoginHandler::MapLoginHandler() handledMessages = _messages; } -void MapLoginHandler::handleMessage(MessageIn *msg) +void MapLoginHandler::handleMessage(MessageIn &msg) { //unsigned char direction; - switch (msg->getId()) + switch (msg.getId()) { case SMSG_LOGIN_SUCCESS: - msg->readLong(); // server tick + msg.readLong(); // server tick //logger->log("Protocol: Player start position: (%d, %d), Direction: %d", // player_node->mX, player_node->mY, direction); state = STATE_GAME; diff --git a/src/net/maploginhandler.h b/src/net/maploginhandler.h index fe597549..3f779753 100644 --- a/src/net/maploginhandler.h +++ b/src/net/maploginhandler.h @@ -31,7 +31,7 @@ class MapLoginHandler : public MessageHandler public: MapLoginHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/messagehandler.h b/src/net/messagehandler.h index c09037f6..9f92636d 100644 --- a/src/net/messagehandler.h +++ b/src/net/messagehandler.h @@ -37,7 +37,7 @@ class MessageHandler MessageHandler(); virtual ~MessageHandler(); - virtual void handleMessage(MessageIn *msg) =0; + virtual void handleMessage(MessageIn &msg) = 0; void setNetwork(Network *network); diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp index 7e85a813..23ea8181 100644 --- a/src/net/messagein.cpp +++ b/src/net/messagein.cpp @@ -27,8 +27,6 @@ #include -#include "packet.h" - MessageIn::MessageIn(const char *data, unsigned int length): mData(data), mLength(length), diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp index 426a1c0d..4fca662a 100644 --- a/src/net/messageout.cpp +++ b/src/net/messageout.cpp @@ -27,8 +27,6 @@ #include -#include "packet.h" - MessageOut::MessageOut(): mData(0), mDataSize(0), diff --git a/src/net/network.cpp b/src/net/network.cpp index 2ce6fc2b..08b5fe92 100644 --- a/src/net/network.cpp +++ b/src/net/network.cpp @@ -160,7 +160,7 @@ Network::dispatchMessage(ENetPacket *packet) if (iter != mMessageHandlers.end()) { logger->log("Received packet %x (%i B)", msg.getId(), msg.getLength()); - iter->second->handleMessage(&msg); + iter->second->handleMessage(msg); } else { logger->log("Unhandled packet %x (%i B)", diff --git a/src/net/npchandler.cpp b/src/net/npchandler.cpp index 62355180..9c89e71f 100644 --- a/src/net/npchandler.cpp +++ b/src/net/npchandler.cpp @@ -47,21 +47,23 @@ NPCHandler::NPCHandler() handledMessages = _messages; } -void NPCHandler::handleMessage(MessageIn *msg) +void NPCHandler::handleMessage(MessageIn &msg) { - switch (msg->getId()) + switch (msg.getId()) { case SMSG_NPC_CHOICE: - msg->readShort(); // length - current_npc = dynamic_cast(beingManager->findBeing(msg->readLong())); - npcListDialog->parseItems(msg->readString(msg->getLength() - 8)); + msg.readShort(); // length + current_npc = dynamic_cast( + beingManager->findBeing(msg.readLong())); + npcListDialog->parseItems(msg.readString(msg.getLength() - 8)); npcListDialog->setVisible(true); break; case SMSG_NPC_MESSAGE: - msg->readShort(); // length - current_npc = dynamic_cast(beingManager->findBeing(msg->readLong())); - npcTextDialog->addText(msg->readString(msg->getLength() - 8)); + msg.readShort(); // length + current_npc = dynamic_cast( + beingManager->findBeing(msg.readLong())); + npcTextDialog->addText(msg.readString(msg.getLength() - 8)); npcListDialog->setVisible(false); npcTextDialog->setVisible(true); break; diff --git a/src/net/npchandler.h b/src/net/npchandler.h index 903ecd10..0cb40f64 100644 --- a/src/net/npchandler.h +++ b/src/net/npchandler.h @@ -31,7 +31,7 @@ class NPCHandler : public MessageHandler public: NPCHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/packet.cpp b/src/net/packet.cpp deleted file mode 100644 index e77ac117..00000000 --- a/src/net/packet.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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$ - */ - -#include "packet.h" - -#include - -Packet::Packet(const char *data, int length): - mLength(length) -{ - // Create a copy of the data - mData = new char[mLength]; - memcpy(mData, data, mLength); -} - -Packet::~Packet() -{ - // Clean up the data - delete[] mData; -} diff --git a/src/net/packet.h b/src/net/packet.h deleted file mode 100644 index 84d16d5e..00000000 --- a/src/net/packet.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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$ - */ - -#ifndef _TMW_PACKET_ -#define _TMW_PACKET_ - -/** - * A packet wraps a certain amount of bytes for sending and receiving. - */ -class Packet -{ - public: - /** - * Constructor. - */ - Packet(const char *data, int length); - - /** - * Destructor. - */ - ~Packet(); - - char *mData; /**< Packet data */ - unsigned int mLength; /**< Length of data in bytes */ -}; - -#endif diff --git a/src/net/playerhandler.cpp b/src/net/playerhandler.cpp index d8ff81f4..f6065aaf 100644 --- a/src/net/playerhandler.cpp +++ b/src/net/playerhandler.cpp @@ -46,7 +46,9 @@ OkDialog *deathNotice = NULL; namespace { struct WeightListener : public gcn::ActionListener { - void action(const std::string &eventId, gcn::Widget *widget) { weightNotice = NULL; } + void action(const std::string &eventId, gcn::Widget *widget) { + weightNotice = NULL; + } } weightListener; } @@ -80,9 +82,9 @@ PlayerHandler::PlayerHandler() handledMessages = _messages; } -void PlayerHandler::handleMessage(MessageIn *msg) +void PlayerHandler::handleMessage(MessageIn &msg) { - switch (msg->getId()) + switch (msg.getId()) { case SMSG_WALK_RESPONSE: // It is assumed by the client any request to walk actually @@ -93,9 +95,9 @@ void PlayerHandler::handleMessage(MessageIn *msg) case SMSG_PLAYER_WARP: { - std::string mapPath = msg->readString(16); - Uint16 x = msg->readShort(); - Uint16 y = msg->readShort(); + std::string mapPath = msg.readString(16); + Uint16 x = msg.readShort(); + Uint16 y = msg.readShort(); logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y); @@ -114,13 +116,13 @@ void PlayerHandler::handleMessage(MessageIn *msg) case SMSG_PLAYER_STAT_UPDATE_1: { - Sint16 type = msg->readShort(); - Uint32 value = msg->readLong(); + Sint16 type = msg.readShort(); + Uint32 value = msg.readLong(); switch (type) { //case 0x0000: - // player_node->setWalkSpeed(msg->readLong()); + // player_node->setWalkSpeed(msg.readLong()); // break; case 0x0005: player_node->mHp = value; break; case 0x0006: player_node->mMaxHp = value; break; @@ -169,30 +171,30 @@ void PlayerHandler::handleMessage(MessageIn *msg) break; case SMSG_PLAYER_STAT_UPDATE_2: - switch (msg->readShort()) { + switch (msg.readShort()) { case 0x0001: - player_node->mXp = msg->readLong(); + player_node->mXp = msg.readLong(); break; case 0x0002: - player_node->mJobXp = msg->readLong(); + player_node->mJobXp = msg.readLong(); break; case 0x0014: - player_node->mMoney = msg->readLong(); + player_node->mMoney = msg.readLong(); break; case 0x0016: - player_node->mXpForNextLevel = msg->readLong(); + player_node->mXpForNextLevel = msg.readLong(); break; case 0x0017: - player_node->mJobXpForNextLevel = msg->readLong(); + player_node->mJobXpForNextLevel = msg.readLong(); break; } break; case SMSG_PLAYER_STAT_UPDATE_3: { - Sint32 type = msg->readLong(); - Sint32 base = msg->readLong(); - Sint32 bonus = msg->readLong(); + Sint32 type = msg.readLong(); + Sint32 base = msg.readLong(); + Sint32 bonus = msg.readLong(); Sint32 total = base + bonus; switch (type) { @@ -214,9 +216,9 @@ void PlayerHandler::handleMessage(MessageIn *msg) case SMSG_PLAYER_STAT_UPDATE_4: { - Sint16 type = msg->readShort(); - Sint8 fail = msg->readByte(); - Sint8 value = msg->readByte(); + Sint16 type = msg.readShort(); + Sint8 fail = msg.readByte(); + Sint8 value = msg.readByte(); if (fail != 1) break; @@ -240,60 +242,60 @@ void PlayerHandler::handleMessage(MessageIn *msg) // Updates stats and status points case SMSG_PLAYER_STAT_UPDATE_5: - player_node->mStatsPointsToAttribute = msg->readShort(); - player_node->mAttr[LocalPlayer::STR] = msg->readByte(); - player_node->mAttrUp[LocalPlayer::STR] = msg->readByte(); - player_node->mAttr[LocalPlayer::AGI] = msg->readByte(); - player_node->mAttrUp[LocalPlayer::AGI] = msg->readByte(); - player_node->mAttr[LocalPlayer::VIT] = msg->readByte(); - player_node->mAttrUp[LocalPlayer::VIT] = msg->readByte(); - player_node->mAttr[LocalPlayer::INT] = msg->readByte(); - player_node->mAttrUp[LocalPlayer::INT] = msg->readByte(); - player_node->mAttr[LocalPlayer::DEX] = msg->readByte(); - player_node->mAttrUp[LocalPlayer::DEX] = msg->readByte(); - player_node->mAttr[LocalPlayer::LUK] = msg->readByte(); - player_node->mAttrUp[LocalPlayer::LUK] = msg->readByte(); - player_node->ATK = msg->readShort(); // ATK - player_node->ATK_BONUS = msg->readShort(); // ATK bonus - player_node->MATK = msg->readShort(); // MATK max - player_node->MATK_BONUS = msg->readShort(); // MATK min - player_node->DEF = msg->readShort(); // DEF - player_node->DEF_BONUS = msg->readShort(); // DEF bonus - player_node->MDEF = msg->readShort(); // MDEF - player_node->MDEF_BONUS = msg->readShort(); // MDEF bonus - player_node->HIT = msg->readShort(); // HIT - player_node->FLEE = msg->readShort(); // FLEE - player_node->FLEE_BONUS = msg->readShort(); // FLEE bonus - msg->readShort(); // critical - msg->readShort(); // unknown + player_node->mStatsPointsToAttribute = msg.readShort(); + player_node->mAttr[LocalPlayer::STR] = msg.readByte(); + player_node->mAttrUp[LocalPlayer::STR] = msg.readByte(); + player_node->mAttr[LocalPlayer::AGI] = msg.readByte(); + player_node->mAttrUp[LocalPlayer::AGI] = msg.readByte(); + player_node->mAttr[LocalPlayer::VIT] = msg.readByte(); + player_node->mAttrUp[LocalPlayer::VIT] = msg.readByte(); + player_node->mAttr[LocalPlayer::INT] = msg.readByte(); + player_node->mAttrUp[LocalPlayer::INT] = msg.readByte(); + player_node->mAttr[LocalPlayer::DEX] = msg.readByte(); + player_node->mAttrUp[LocalPlayer::DEX] = msg.readByte(); + player_node->mAttr[LocalPlayer::LUK] = msg.readByte(); + player_node->mAttrUp[LocalPlayer::LUK] = msg.readByte(); + player_node->ATK = msg.readShort(); // ATK + player_node->ATK_BONUS = msg.readShort(); // ATK bonus + player_node->MATK = msg.readShort(); // MATK max + player_node->MATK_BONUS = msg.readShort(); // MATK min + player_node->DEF = msg.readShort(); // DEF + player_node->DEF_BONUS = msg.readShort(); // DEF bonus + player_node->MDEF = msg.readShort(); // MDEF + player_node->MDEF_BONUS = msg.readShort(); // MDEF bonus + player_node->HIT = msg.readShort(); // HIT + player_node->FLEE = msg.readShort(); // FLEE + player_node->FLEE_BONUS = msg.readShort(); // FLEE bonus + msg.readShort(); // critical + msg.readShort(); // unknown break; case SMSG_PLAYER_STAT_UPDATE_6: - switch (msg->readShort()) { + switch (msg.readShort()) { case 0x0020: - player_node->mAttrUp[LocalPlayer::STR] = msg->readByte(); + player_node->mAttrUp[LocalPlayer::STR] = msg.readByte(); break; case 0x0021: - player_node->mAttrUp[LocalPlayer::AGI] = msg->readByte(); + player_node->mAttrUp[LocalPlayer::AGI] = msg.readByte(); break; case 0x0022: - player_node->mAttrUp[LocalPlayer::VIT] = msg->readByte(); + player_node->mAttrUp[LocalPlayer::VIT] = msg.readByte(); break; case 0x0023: - player_node->mAttrUp[LocalPlayer::INT] = msg->readByte(); + player_node->mAttrUp[LocalPlayer::INT] = msg.readByte(); break; case 0x0024: - player_node->mAttrUp[LocalPlayer::DEX] = msg->readByte(); + player_node->mAttrUp[LocalPlayer::DEX] = msg.readByte(); break; case 0x0025: - player_node->mAttrUp[LocalPlayer::LUK] = msg->readByte(); + player_node->mAttrUp[LocalPlayer::LUK] = msg.readByte(); break; } break; case SMSG_PLAYER_ARROW_MESSAGE: { - Sint16 type = msg->readShort(); + Sint16 type = msg.readShort(); switch (type) { case 0: diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h index b28a23f5..6d0baef7 100644 --- a/src/net/playerhandler.h +++ b/src/net/playerhandler.h @@ -31,7 +31,7 @@ class PlayerHandler : public MessageHandler public: PlayerHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp index 89009e47..d9bea775 100644 --- a/src/net/skillhandler.cpp +++ b/src/net/skillhandler.cpp @@ -39,27 +39,27 @@ SkillHandler::SkillHandler() handledMessages = _messages; } -void SkillHandler::handleMessage(MessageIn *msg) +void SkillHandler::handleMessage(MessageIn &msg) { int skillCount; - switch (msg->getId()) + switch (msg.getId()) { case SMSG_PLAYER_SKILLS: - msg->readShort(); // length - skillCount = (msg->getLength() - 4) / 37; + msg.readShort(); // length + skillCount = (msg.getLength() - 4) / 37; skillDialog->cleanList(); for (int k = 0; k < skillCount; k++) { - Sint16 skillId = msg->readShort(); - msg->readShort(); // target type - msg->readShort(); // unknown - Sint16 level = msg->readShort(); - Sint16 sp = msg->readShort(); - msg->readShort(); // range - std::string skillName = msg->readString(24); - Sint8 up = msg->readByte(); + Sint16 skillId = msg.readShort(); + msg.readShort(); // target type + msg.readShort(); // unknown + Sint16 level = msg.readShort(); + Sint16 sp = msg.readShort(); + msg.readShort(); // range + std::string skillName = msg.readString(24); + Sint8 up = msg.readByte(); if (level != 0 || up != 0) { @@ -77,11 +77,11 @@ void SkillHandler::handleMessage(MessageIn *msg) // Action failed (ex. sit because you have not reached the // right level) CHATSKILL action; - action.skill = msg->readShort(); - action.bskill = msg->readShort(); - action.unused = msg->readShort(); // unknown - action.success = msg->readByte(); - action.reason = msg->readByte(); + action.skill = msg.readShort(); + action.bskill = msg.readShort(); + action.unused = msg.readShort(); // unknown + action.success = msg.readByte(); + action.reason = msg.readByte(); if (action.success != SKILL_FAILED && action.bskill == BSKILL_EMOTE) { diff --git a/src/net/skillhandler.h b/src/net/skillhandler.h index 820a7b6a..8c0653d4 100644 --- a/src/net/skillhandler.h +++ b/src/net/skillhandler.h @@ -31,7 +31,7 @@ class SkillHandler : public MessageHandler public: SkillHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif diff --git a/src/net/tradehandler.cpp b/src/net/tradehandler.cpp index b0baa5ea..2ebc160f 100644 --- a/src/net/tradehandler.cpp +++ b/src/net/tradehandler.cpp @@ -63,9 +63,9 @@ TradeHandler::TradeHandler() handledMessages = _messages; } -void TradeHandler::handleMessage(MessageIn *msg) +void TradeHandler::handleMessage(MessageIn &msg) { - switch (msg->getId()) + switch (msg.getId()) { case SMSG_TRADE_REQUEST: // If a trade window or request window is already open, send a @@ -81,7 +81,7 @@ void TradeHandler::handleMessage(MessageIn *msg) } player_node->setTrading(true); - tradePartnerName = msg->readString(24); + tradePartnerName = msg.readString(24); ConfirmDialog *dlg; dlg = new ConfirmDialog("Request for trade", tradePartnerName + @@ -90,7 +90,7 @@ void TradeHandler::handleMessage(MessageIn *msg) break; case SMSG_TRADE_RESPONSE: - switch (msg->readByte()) + switch (msg.readByte()) { case 0: // Too far away chatWindow->chatLog("Trading isn't possible. " @@ -126,11 +126,11 @@ void TradeHandler::handleMessage(MessageIn *msg) case SMSG_TRADE_ITEM_ADD: { - Sint32 amount = msg->readLong(); - Sint16 type = msg->readShort(); - msg->readByte(); // identified flag - msg->readByte(); // attribute - msg->readByte(); // refine + Sint32 amount = msg.readLong(); + Sint16 type = msg.readShort(); + msg.readByte(); // identified flag + msg.readByte(); // attribute + msg.readByte(); // refine // TODO: handle also identified, etc if (type == 0) { @@ -144,10 +144,10 @@ void TradeHandler::handleMessage(MessageIn *msg) case SMSG_TRADE_ITEM_ADD_RESPONSE: // Trade: New Item add response (was 0x00ea, now 01b1) { - Item *item = player_node->getInvItem(msg->readShort()); - Sint16 quantity = msg->readShort(); + Item *item = player_node->getInvItem(msg.readShort()); + Sint16 quantity = msg.readShort(); - switch (msg->readByte()) + switch (msg.readByte()) { case 0: // Successfully added item @@ -175,7 +175,7 @@ void TradeHandler::handleMessage(MessageIn *msg) case SMSG_TRADE_OK: // 0 means ok from myself, 1 means ok from other; - tradeWindow->receivedOk(msg->readByte() == 0); + tradeWindow->receivedOk(msg.readByte() == 0); break; case SMSG_TRADE_CANCEL: diff --git a/src/net/tradehandler.h b/src/net/tradehandler.h index a1971004..0b73c871 100644 --- a/src/net/tradehandler.h +++ b/src/net/tradehandler.h @@ -33,7 +33,7 @@ class TradeHandler : public MessageHandler public: TradeHandler(); - void handleMessage(MessageIn *msg); + void handleMessage(MessageIn &msg); }; #endif -- cgit v1.2.3-70-g09d2 From 5cc5c903df7b535c6bf27987b89a405812d89735 Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Sat, 26 Aug 2006 13:28:35 +0000 Subject: Implemented "say around" chat. --- ChangeLog | 7 +++++++ src/gui/chat.cpp | 9 ++++----- src/net/beinghandler.cpp | 27 ++++++++++++++++----------- src/net/chathandler.cpp | 17 +++++++++++++++++ src/net/protocol.h | 2 +- 5 files changed, 45 insertions(+), 17 deletions(-) (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index 035f2688..3406dbdc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-08-26 Guillaume Melquiond + + * src/net/chathandler.cpp, src/gui/chat.cpp, src/net/protocol.h: Added + support for "say around" messages. + * src/net/beinghandler.cpp: Partly implemented being creation, so that + chat works. + 2006-08-21 Eugenio Favalli * The Mana World.dev, tmw.cbp: Updated project files. diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 592439fc..e8bb1cc6 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -37,6 +37,7 @@ #include "../localplayer.h" #include "../net/messageout.h" +#include "../net/network.h" #include "../net/protocol.h" ChatWindow::ChatWindow(Network *network): @@ -249,12 +250,10 @@ ChatWindow::chatSend(const std::string &nick, std::string msg) // Prepare ordinary message if (msg.substr(0, 1) != "/") { - msg = nick + " : " + msg; - MessageOut outMsg; - outMsg.writeShort(CMSG_CHAT_MESSAGE); - outMsg.writeShort(msg.length() + 4); - outMsg.writeString(msg, msg.length()); + outMsg.writeShort(PGMSG_SAY); + outMsg.writeString(msg); + network->send(Network::GAME, outMsg); } else if (msg.substr(0, IS_ANNOUNCE_LENGTH) == IS_ANNOUNCE) { diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp index ed0fc4b2..10de5351 100644 --- a/src/net/beinghandler.cpp +++ b/src/net/beinghandler.cpp @@ -383,17 +383,22 @@ void BeingHandler::handleMessage(MessageIn &msg) void BeingHandler::handleBeingEnterMessage(MessageIn &msg) { - // Not sure what do to exactly with this message yet. - /* - unsigned char type = msg.readByte(); - unsigned long id = msg.readLong(); - - if (type == OBJECT_PLAYER) + msg.readByte(); // type + int id = msg.readLong(); + std::string name = msg.readString(); + Being *being; + if (player_node->getName() == name) + { + being = player_node; + being->setId(id); + } + else { - std::string name = msg.readString(); - unsigned char hairStyle = msg.readByte(); - unsigned char hairColor = msg.readByte(); - unsigned char gender = msg.readByte(); + // assume type is player for now, so job 0, TODO + being = beingManager->createBeing(id, 0); + being->setName(name); } - */ + being->setHairStyle(msg.readByte() + 1); + being->setHairColor(msg.readByte() + 1); + being->setSex(msg.readByte()); } diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index 795b2a27..02f99c41 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -42,11 +42,14 @@ extern Being *player_node; ChatHandler::ChatHandler() { static const Uint16 _messages[] = { + GPMSG_SAY, + /* SMSG_BEING_CHAT, SMSG_PLAYER_CHAT, SMSG_GM_CHAT, SMSG_WHO_ANSWER, 0x10c, // MVP + */ 0 }; handledMessages = _messages; @@ -60,6 +63,20 @@ void ChatHandler::handleMessage(MessageIn &msg) switch (msg.getId()) { + case GPMSG_SAY: + being = beingManager->findBeing(msg.readLong()); + chatMsg = msg.readString(); + if (being) + { + chatWindow->chatLog(being->getName() + " : " + chatMsg, being == player_node ? BY_PLAYER : BY_OTHER); + being->setSpeech(chatMsg, SPEECH_TIME); + } + else + { + chatWindow->chatLog("John Doe : " + chatMsg, BY_OTHER); + } + break; + // Received speech from being case SMSG_BEING_CHAT: chatMsgLength = msg.readShort() - 8; diff --git a/src/net/protocol.h b/src/net/protocol.h index 6927f3fd..33d72c96 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -157,7 +157,7 @@ enum { GPMSG_BEING_LEAVE = 0x0201, // B type, L being id PGMSG_WALK = 0x0260, // L*2 destination PGMSG_SAY = 0x02A0, // S text - GPMSG_SAY = 0x02A1, // S being, S text + GPMSG_SAY = 0x02A1, // L being id, S text PGMSG_USE_ITEM = 0x0300, // L item id GPMSG_USE_RESPONSE = 0x0301, // B error PGMSG_EQUIP = 0x0302, // L item id, B slot -- cgit v1.2.3-70-g09d2 From 2b322bf18d80acb464a9dc1820e581e7204cca1e Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Sat, 2 Sep 2006 11:58:35 +0000 Subject: Switched to short IDs for beings. --- ChangeLog | 8 ++++++++ src/being.cpp | 2 +- src/being.h | 8 ++++---- src/beingmanager.cpp | 4 ++-- src/beingmanager.h | 4 ++-- src/localplayer.cpp | 4 ++-- src/localplayer.h | 2 +- src/monster.cpp | 2 +- src/monster.h | 2 +- src/net/beinghandler.cpp | 9 ++++----- src/net/charserverhandler.cpp | 2 +- src/net/chathandler.cpp | 6 ++++-- src/net/protocol.h | 9 +++++---- src/npc.cpp | 2 +- src/npc.h | 2 +- src/player.cpp | 2 +- src/player.h | 2 +- 17 files changed, 40 insertions(+), 30 deletions(-) (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index 28f87459..492fc2b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-09-02 Guillaume Melquiond + + * src/localplayer.cpp, src/beingmanager.h, src/beingmanager.cpp, + src/npc.cpp, src/player.cpp, src/monster.h, src/being.cpp, src/npc.h, + src/monster.cpp, src/player.h, src/net/beinghandler.cpp, src/being.h, + src/net/charserverhandler.cpp, src/net/protocol.h, src/localplayer.h, + src/net/chathandler.cpp: Switched to short IDs for beings. + 2006-09-01 Eugenio Favalli * src/gui/serverdialog.cpp, src/gui/serverdialog.h, src/net/network.h: diff --git a/src/being.cpp b/src/being.cpp index b497d58f..a4bee426 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -46,7 +46,7 @@ PATH_NODE::PATH_NODE(Uint16 iX, Uint16 iY): { } -Being::Being(Uint32 id, Uint16 job, Map *map): +Being::Being(Uint16 id, Uint16 job, Map *map): mJob(job), mX(0), mY(0), mDirection(DOWN), mAction(STAND), diff --git a/src/being.h b/src/being.h index 7c08ab81..b2495a29 100644 --- a/src/being.h +++ b/src/being.h @@ -112,7 +112,7 @@ class Being : public Sprite /** * Constructor. */ - Being(Uint32 id, Uint16 job, Map *map); + Being(Uint16 id, Uint16 job, Map *map); /** * Destructor. @@ -274,14 +274,14 @@ class Being : public Sprite /** * Gets the sprite id. */ - Uint32 + Uint16 getId() const { return mId; } /** * Sets the sprite id. */ void - setId(Uint32 id) { mId = id; } + setId(Uint16 id) { mId = id; } /** * Sets the map the being is on @@ -348,7 +348,7 @@ class Being : public Sprite SpriteDirection getSpriteDirection() const; - Uint32 mId; /**< Unique sprite id */ + Uint16 mId; /**< Unique being id */ Uint8 mSex; /**< Character's gender */ Uint16 mWeapon; /**< Weapon picture id */ Uint16 mWalkSpeed; /**< Walking speed */ diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp index 0156ce33..d2db055a 100644 --- a/src/beingmanager.cpp +++ b/src/beingmanager.cpp @@ -62,7 +62,7 @@ void BeingManager::setPlayer(LocalPlayer *player) mBeings.push_back(player); } -Being* BeingManager::createBeing(Uint32 id, Uint16 job) +Being* BeingManager::createBeing(Uint16 id, Uint16 job) { Being *being; @@ -90,7 +90,7 @@ void BeingManager::destroyBeing(Being *being) delete being; } -Being* BeingManager::findBeing(Uint32 id) +Being* BeingManager::findBeing(Uint16 id) { for (BeingIterator i = mBeings.begin(); i != mBeings.end(); i++) { diff --git a/src/beingmanager.h b/src/beingmanager.h index 0dbafcc6..c32884a0 100644 --- a/src/beingmanager.h +++ b/src/beingmanager.h @@ -48,7 +48,7 @@ class BeingManager /** * Create a being and add it to the list of beings */ - Being* createBeing(Uint32 id, Uint16 job); + Being* createBeing(Uint16 id, Uint16 job); /** * Remove a Being @@ -58,7 +58,7 @@ class BeingManager /** * Return a specific id Being */ - Being* findBeing(Uint32 id); + Being* findBeing(Uint16 id); /** * Return a being at specific coordinates diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 9df3ac3f..87a55744 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -37,8 +37,8 @@ LocalPlayer *player_node = NULL; -LocalPlayer::LocalPlayer(Uint32 id, Uint16 job, Map *map): - Player(id, job, map), +LocalPlayer::LocalPlayer(): + Player(65535, 0, NULL), mLevel(1), mInventory(new Inventory()), mTarget(NULL), mPickUpTarget(NULL), diff --git a/src/localplayer.h b/src/localplayer.h index 613f196a..886c3d11 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -42,7 +42,7 @@ class LocalPlayer : public Player STR = 0, AGI, VIT, INT, DEX, LUK }; - LocalPlayer(Uint32 id, Uint16 job, Map *map); + LocalPlayer(); virtual ~LocalPlayer(); diff --git a/src/monster.cpp b/src/monster.cpp index aba242b6..a4317e5e 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -29,7 +29,7 @@ #include "utils/tostring.h" -Monster::Monster(Uint32 id, Uint16 job, Map *map): +Monster::Monster(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { mSprites[BASE_SPRITE] = new AnimatedSprite("graphics/sprites/monster" + toString(job - 1002) + ".xml", 0); diff --git a/src/monster.h b/src/monster.h index 6ce0d69d..0314a035 100644 --- a/src/monster.h +++ b/src/monster.h @@ -29,7 +29,7 @@ class Monster : public Being { public: - Monster(Uint32 id, Uint16 job, Map *map); + Monster(Uint16 id, Uint16 job, Map *map); virtual Type getType() const; }; diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp index e3eb6eba..8ccd3dd6 100644 --- a/src/net/beinghandler.cpp +++ b/src/net/beinghandler.cpp @@ -398,7 +398,7 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg) { int type = msg.readByte(); // type - int id = msg.readLong(); + int id = msg.readShort(); switch (type) { case OBJECT_PLAYER: @@ -431,8 +431,7 @@ BeingHandler::handleBeingEnterMessage(MessageIn &msg) void BeingHandler::handleBeingLeaveMessage(MessageIn &msg) { - msg.readByte(); // type, assume player for now, TODO - Being *being = beingManager->findBeing(msg.readLong()); + Being *being = beingManager->findBeing(msg.readShort()); if (!being) return; if (being == player_node->getTarget()) { @@ -443,9 +442,9 @@ void BeingHandler::handleBeingLeaveMessage(MessageIn &msg) void BeingHandler::handleBeingsMoveMessage(MessageIn &msg) { - for (int nb = (msg.getLength() - 2) / (4 + 4 * 2); nb > 0; --nb) + for (int nb = (msg.getLength() - 2) / (2 + 4 * 2); nb > 0; --nb) { - Uint32 id = msg.readLong(); + Uint16 id = msg.readShort(); Being *being = beingManager->findBeing(id); if (!being) continue; int sx = msg.readShort(), sy = msg.readShort(), diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp index d67949cc..4e251524 100644 --- a/src/net/charserverhandler.cpp +++ b/src/net/charserverhandler.cpp @@ -195,7 +195,7 @@ CharServerHandler::handleCharSelectResponse(MessageIn &msg) LocalPlayer* CharServerHandler::readPlayerData(MessageIn &msg, int &slot) { - LocalPlayer *tempPlayer = new LocalPlayer(mLoginData->account_ID, 0, NULL); + LocalPlayer *tempPlayer = new LocalPlayer; slot = msg.readByte(); // character slot tempPlayer->mName = msg.readString(); tempPlayer->setSex(msg.readByte()); diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index 02f99c41..f765f0f4 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -59,12 +59,12 @@ void ChatHandler::handleMessage(MessageIn &msg) { Being *being; std::string chatMsg; - Sint16 chatMsgLength; + //Sint16 chatMsgLength; switch (msg.getId()) { case GPMSG_SAY: - being = beingManager->findBeing(msg.readLong()); + being = beingManager->findBeing(msg.readShort()); chatMsg = msg.readString(); if (being) { @@ -77,6 +77,7 @@ void ChatHandler::handleMessage(MessageIn &msg) } break; + /* // Received speech from being case SMSG_BEING_CHAT: chatMsgLength = msg.readShort() - 8; @@ -131,5 +132,6 @@ void ChatHandler::handleMessage(MessageIn &msg) msg.readLong(); // id chatWindow->chatLog("MVP player", BY_SERVER); break; + */ } } diff --git a/src/net/protocol.h b/src/net/protocol.h index 6feee9d4..f056f003 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -152,13 +152,14 @@ enum { // [, S32 token, S server, W port] PGMSG_PICKUP = 0x0110, GPMSG_PICKUP_RESPONSE = 0x0111, - GPMSG_BEING_ENTER = 0x0200, // B type, L being id + GPMSG_BEING_ENTER = 0x0200, // B type, W being id // player: S name, B hair style, B hair color, B gender - GPMSG_BEING_LEAVE = 0x0201, // B type, L being id + // monster: W type id + GPMSG_BEING_LEAVE = 0x0201, // W being id PGMSG_WALK = 0x0260, // W*2 destination - GPMSG_BEINGS_MOVE = 0x0280, // { L being id, W*2 position, W*2 destination }* + GPMSG_BEINGS_MOVE = 0x0280, // { W being id, W*2 position, W*2 destination }* PGMSG_SAY = 0x02A0, // S text - GPMSG_SAY = 0x02A1, // L being id, S text + GPMSG_SAY = 0x02A1, // W being id, S text PGMSG_USE_ITEM = 0x0300, // L item id GPMSG_USE_RESPONSE = 0x0301, // B error PGMSG_EQUIP = 0x0302, // L item id, B slot diff --git a/src/npc.cpp b/src/npc.cpp index 13025469..b2b426dd 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -33,7 +33,7 @@ extern Spriteset *npcset; NPC *current_npc = 0; -NPC::NPC(Uint32 id, Uint16 job, Map *map): +NPC::NPC(Uint16 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 bbc86d9c..3b61123b 100644 --- a/src/npc.h +++ b/src/npc.h @@ -29,7 +29,7 @@ class NPC : public Being { public: - NPC(Uint32 id, Uint16 job, Map *map); + NPC(Uint16 id, Uint16 job, Map *map); virtual Type getType() const; diff --git a/src/player.cpp b/src/player.cpp index af9a3344..f5f42e9f 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -32,7 +32,7 @@ #include "gui/gui.h" -Player::Player(Uint32 id, Uint16 job, Map *map): +Player::Player(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { /* Load the weapon sprite. When there are more different weapons this diff --git a/src/player.h b/src/player.h index 65b0303d..6ff4babe 100644 --- a/src/player.h +++ b/src/player.h @@ -38,7 +38,7 @@ class Player : public Being /** * Constructor. */ - Player(Uint32 id, Uint16 job, Map *map); + Player(Uint16 id, Uint16 job, Map *map); virtual Type getType() const; -- cgit v1.2.3-70-g09d2 From 7a6e4d3c87ca4d7cc851af47fd9ebb616168f4c9 Mon Sep 17 00:00:00 2001 From: Philipp Sehmisch Date: Tue, 27 Feb 2007 16:39:17 +0000 Subject: Implementation of chat channels by Trapdoor. --- ChangeLog | 12 ++- src/game.cpp | 6 +- src/graphics.h | 2 +- src/gui/button.cpp | 9 +- src/gui/button.h | 7 ++ src/gui/chat.cpp | 185 +++++++++++++++++++++++++++++++++----- src/gui/chat.h | 54 +++++++++-- src/gui/tabbedcontainer.cpp | 36 ++++++-- src/gui/tabbedcontainer.h | 10 ++- src/net/chathandler.cpp | 76 ++++++++++++++++ src/net/chatserver/chatserver.cpp | 15 +++- src/net/chatserver/chatserver.h | 5 +- src/net/protocol.h | 9 +- 13 files changed, 376 insertions(+), 50 deletions(-) (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index 62585ceb..8b22ac39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,14 @@ -2007-02-25 Bjørn Lindeijer +2007-02-27 Philipp Sehmisch + * gui/button.cpp, src/guibutton.h, + src/gui/tabbedcontainer.cpp, src/gui/tabbedcontainer.h:: Tabbed + containers now display the button of the active tab pressed all + the time. + * src/game.cpp, src/gui/chat.cpp, src/gui/chat.h, src/chathandler.cpp, + src/net/chatserver/chatserver.cpp, src/net/chatserver/chatserver.h, + src/net/protocol.h: Implementation of chat channels by Trapdoor. + * src/graphics.h: MSVC Compilation fix by Trapdoor. + +2007-02-25 Bjørn Lindeijer * src/CMakeLists.txt: Updated CMake file. diff --git a/src/game.cpp b/src/game.cpp index 9eaa0693..ba4e2b9d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -32,6 +32,7 @@ #include #include "beingmanager.h" +#include "channelmanager.h" #include "configuration.h" #include "engine.h" #include "flooritemmanager.h" @@ -118,6 +119,7 @@ DebugWindow *debugWindow; BeingManager *beingManager = NULL; FloorItemManager *floorItemManager = NULL; +ChannelManager *channelManager = NULL; const int MAX_TIME = 10000; @@ -238,6 +240,7 @@ Game::Game(): beingManager = new BeingManager; floorItemManager = new FloorItemManager(); + channelManager = new ChannelManager(); // Initialize timers tick_time = 0; @@ -281,6 +284,7 @@ Game::~Game() delete beingManager; delete floorItemManager; + delete channelManager; delete joystick; beingManager = NULL; @@ -303,7 +307,7 @@ bool saveScreenshot(SDL_Surface *screenshot) do { screenshotCount++; filename.str(""); -#if (defined __USE_UNIX98 || defined __FreeBSD__) +#if (defined __USE_UNIX98 || defined __FreeBSD__ || defined __APPLE__) filename << PHYSFS_getUserDir() << "/"; #endif filename << "TMW_Screenshot_" << screenshotCount << ".png"; diff --git a/src/graphics.h b/src/graphics.h index b3d36653..4637973f 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -29,7 +29,7 @@ class Image; class ImageRect; -class SDL_Surface; +struct SDL_Surface; /** * 9 images defining a rectangle. 4 corners, 4 sides and a middle area. The diff --git a/src/gui/button.cpp b/src/gui/button.cpp index 0055c89a..e607b66a 100644 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -38,8 +38,9 @@ ImageRect Button::button[4]; int Button::mInstances = 0; Button::Button(const std::string& caption, const std::string &actionEventId, - gcn::ActionListener *listener): - gcn::Button(caption) + gcn::ActionListener *listener): + gcn::Button(caption), + mIsLogged(false) { setBorderSize(0); @@ -100,7 +101,7 @@ Button::draw(gcn::Graphics *graphics) if (!isEnabled()) { mode = 3; } - else if (isPressed()) { + else if (isPressed() || mIsLogged) { mode = 2; } else if (mHasMouse) { @@ -130,7 +131,7 @@ Button::draw(gcn::Graphics *graphics) textX = getWidth() - 4; break; default: - throw GCN_EXCEPTION("Button::draw. Uknown alignment."); + throw GCN_EXCEPTION("Button::draw. Unknown alignment."); } graphics->setFont(getFont()); diff --git a/src/gui/button.h b/src/gui/button.h index 1c2ec41b..eb73e311 100644 --- a/src/gui/button.h +++ b/src/gui/button.h @@ -53,9 +53,16 @@ class Button : public gcn::Button { */ void draw(gcn::Graphics* graphics); + /** + * Enable/Disable highlighting + */ + void setLogged(bool enable) + { mIsLogged = enable; } + private: static ImageRect button[4]; /**< Button state graphics */ static int mInstances; /**< Number of button instances */ + bool mIsLogged; /**< Makes the button appear pressed all the time */ }; #endif diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index d992c6dd..eb6b7612 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -29,17 +29,22 @@ #include #include "browserbox.h" +#include "../channelmanager.h" +#include "../channel.h" #include "chatinput.h" +#include "gccontainer.h" #include "scrollarea.h" +#include "tabbedcontainer.h" #include "windowcontainer.h" #include "../game.h" #include "../localplayer.h" #include "../net/chatserver/chatserver.h" - #include "../net/gameserver/player.h" +#include "../utils/dtor.h" + ChatWindow::ChatWindow(): Window(""), mTmpVisible(false) @@ -56,17 +61,34 @@ ChatWindow::ChatWindow(): mChatInput->setActionEventId("chatinput"); mChatInput->addActionListener(this); - mTextOutput = new BrowserBox(BrowserBox::AUTO_WRAP); - mTextOutput->setOpaque(false); - mTextOutput->disableLinksAndUserColors(); - mScrollArea = new ScrollArea(mTextOutput); - mScrollArea->setPosition( - mScrollArea->getBorderSize(), mScrollArea->getBorderSize()); - mScrollArea->setScrollPolicy( + BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP); + textOutput->setOpaque(false); + textOutput->disableLinksAndUserColors(); + ScrollArea *scrollArea = new ScrollArea(textOutput); + scrollArea->setPosition( + scrollArea->getBorderSize(), scrollArea->getBorderSize()); + scrollArea->setScrollPolicy( gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS); - mScrollArea->setOpaque(false); + scrollArea->setOpaque(false); + + GCContainer *tab = new GCContainer(); + tab->setWidth(getWidth() - 2 * tab->getBorderSize()); + tab->setHeight(getHeight() - 2 * tab->getBorderSize()); + tab->setOpaque(false); + tab->add(scrollArea); + + mContainer = new TabbedContainer(); + mContainer->addTab(tab, "General"); + mContainer->setOpaque(false); + mChannelOutput["General"] = textOutput; + mChannelScroll["General"] = scrollArea; + + mTabs["General"] = tab; + + mTextOutput = textOutput; + mScrollArea = scrollArea; - add(mScrollArea); + add(mContainer); add(mChatInput); // Add key listener to chat input to be able to respond to up/down @@ -74,6 +96,11 @@ ChatWindow::ChatWindow(): mCurHist = mHistory.end(); } +ChatWindow::~ChatWindow() +{ + for_each(mTabs.begin(), mTabs.end(), make_dtor(mTabs)); +} + void ChatWindow::logic() { @@ -85,14 +112,17 @@ ChatWindow::logic() area.height - mChatInput->getHeight() - mChatInput->getBorderSize()); mChatInput->setWidth(area.width - 2 * mChatInput->getBorderSize()); + mContainer->setWidth(area.width - 2 * mContainer->getBorderSize()); + mContainer->setHeight(area.height - 2 * mContainer->getBorderSize() - + mChatInput->getHeight() - 5); mScrollArea->setWidth(area.width - 2 * mScrollArea->getBorderSize()); mScrollArea->setHeight(area.height - 2 * mScrollArea->getBorderSize() - - mChatInput->getHeight() - 5); + mChatInput->getHeight() - 26); mScrollArea->logic(); } void -ChatWindow::chatLog(std::string line, int own) +ChatWindow::chatLog(std::string line, int own, std::string channelName) { // Delete overhead from the end of the list while ((int)mChatlog.size() > mItemsKeep) { @@ -103,6 +133,9 @@ ChatWindow::chatLog(std::string line, int own) tmp.own = own; tmp.nick = ""; + mTextOutput = mChannelOutput[channelName]; + mScrollArea = mChannelScroll[channelName]; + // Fix the owner of welcome message. if (line.substr(0, 7) == "Welcome") { @@ -196,7 +229,7 @@ ChatWindow::action(const gcn::ActionEvent &event) mCurHist = mHistory.end(); // Send the message to the server - chatSend(player_node->getName(), message); + chatSend(player_node->getName(), message, mContainer->getActiveWidget()); // Clear the text from the chat input mChatInput->setText(""); @@ -241,7 +274,7 @@ ChatWindow::isFocused() } void -ChatWindow::chatSend(const std::string &nick, std::string msg) +ChatWindow::chatSend(const std::string &nick, std::string msg, std::string channelName) { /* Some messages are managed client side, while others * require server handling by proper packet. Probably @@ -249,7 +282,15 @@ ChatWindow::chatSend(const std::string &nick, std::string msg) // Prepare ordinary message if (msg.substr(0, 1) != "/") { - Net::GameServer::Player::say(msg); + if(mContainer->getActiveWidget() == "General") + { + Net::GameServer::Player::say(msg); + } + else + { + short channelId = channelManager->findByName(channelName)->getId(); + Net::ChatServer::chat(channelId, msg); + } } else if (msg.substr(0, IS_ANNOUNCE_LENGTH) == IS_ANNOUNCE) { @@ -258,11 +299,15 @@ ChatWindow::chatSend(const std::string &nick, std::string msg) } else if (msg.substr(0, IS_HELP_LENGTH) == IS_HELP) { - chatLog("-- Help --", BY_SERVER); - chatLog("/help : Display this help.", BY_SERVER); - chatLog("/announce : Global announcement (GM only)", BY_SERVER); - chatLog("/where : Display map name", BY_SERVER); - chatLog("/who : Display number of online users", BY_SERVER); + chatLog("-- Help --", BY_SERVER, channelName); + chatLog("/help > Display this help.", BY_SERVER, channelName); + chatLog("/announce > Global announcement (GM only)", BY_SERVER, channelName); + chatLog("/where > Display map name", BY_SERVER, channelName); + chatLog("/who > Display number of online users", BY_SERVER, channelName); + chatLog("/list > Display all public channels", BY_SERVER, channelName); + chatLog("/register > Register a new channel", BY_SERVER, channelName); + chatLog("/join > Join an already registered channel", BY_SERVER, channelName); + chatLog("/quit > Leave a channel", BY_SERVER, channelName); } else if (msg.substr(0, IS_WHERE_LENGTH) == IS_WHERE) { @@ -275,9 +320,46 @@ ChatWindow::chatSend(const std::string &nick, std::string msg) MessageOut outMsg(0x00c1); */ } + else if (msg.substr(0, IS_REGCHANNEL_LENGTH) == IS_REGCHANNEL) + { + std::string channel = msg.substr(IS_REGCHANNEL_LENGTH, msg.size()); + chatLog("Requesting to register channel", BY_SERVER); + Net::ChatServer::registerChannel(channel, "", "", false); + } + else if (msg.substr(0, IS_JOINCHANNEL_LENGTH) == IS_JOINCHANNEL) + { + //TODO: have passwords too + msg = msg.substr(IS_JOINCHANNEL_LENGTH, msg.size()); + chatLog("Requesting to join channel " + msg, BY_SERVER); + if(msg != "") + { + enterChannel(msg, "None"); + } + else + { + chatLog("No channel name given", BY_SERVER); + } + } + else if (msg.substr(0, IS_LISTCHANNELS_LENGTH) == IS_LISTCHANNELS) + { + Net::ChatServer::getChannelList(); + } + else if (msg.substr(0, IS_QUITCHANNEL_LENGTH) == IS_QUITCHANNEL) + { + Channel* channel; + channel = channelManager->findByName(channelName); + if(channel) + { + Net::ChatServer::quitChannel(channel->getId()); + } + else + { + chatLog("Unable to quit this channel", BY_SERVER); + } + } else { - chatLog("Unknown command", BY_SERVER); + chatLog("Unknown command", BY_SERVER, channelName); } } @@ -359,6 +441,67 @@ ChatWindow::const_msg(CHATSKILL act) return msg; } +void +ChatWindow::addChannel(short channelId, std::string channelName) +{ + Channel* channel = new Channel(channelId); + channel->setName(channelName); + channelManager->addChannel(channel); +} + +void +ChatWindow::removeChannel(short channelId) +{ + Channel* channel = channelManager->findById(channelId); + if(channel) + { + mContainer->removeTab(channel->getName()); + mTabs.erase(channel->getName()); + mChannelOutput.erase(channel->getName()); + mChannelScroll.erase(channel->getName()); + channelManager->removeChannel(channel); + mTextOutput = mChannelOutput["General"]; + mScrollArea = mChannelScroll["General"]; + } +} + +void +ChatWindow::createNewChannelTab(std::string channelName) +{ + BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP); + textOutput->setOpaque(false); + textOutput->disableLinksAndUserColors(); + ScrollArea *scrollArea = new ScrollArea(textOutput); + scrollArea->setPosition(scrollArea->getBorderSize(), scrollArea->getBorderSize()); + scrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS); + scrollArea->setOpaque(false); + GCContainer *tab = new GCContainer(); + tab->setWidth(getWidth() - 2 * tab->getBorderSize()); + tab->setHeight(getHeight() - 2 * tab->getBorderSize()); + tab->add(scrollArea); + tab->setOpaque(false); + mContainer->addTab(tab, channelName); + mTabs[channelName] = tab; + mChannelOutput[channelName] = textOutput; + mChannelScroll[channelName] = scrollArea; + mScrollArea = scrollArea; + mTextOutput = textOutput; + logic(); +} + +void +ChatWindow::enterChannel(std::string channel, std::string password) +{ + Net::ChatServer::enterChannel(channel, password); +} + +void +ChatWindow::sendToChannel(short channelId, std::string user, std::string msg) +{ + std::string channelName = channelManager->findById(channelId)->getName(); + chatLog(user + ": " + msg, user == player_node->getName() ? BY_PLAYER : BY_OTHER, channelName); +} + void ChatWindow::keyPressed(gcn::KeyEvent &event) { diff --git a/src/gui/chat.h b/src/gui/chat.h index 963e5e98..c7e51ebf 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -36,6 +37,8 @@ class BrowserBox; class ScrollArea; +class TabbedContainer; +class GCContainer; #define BY_GM 0 // those should be self-explanatory =) #define BY_PLAYER 1 @@ -53,6 +56,14 @@ class ScrollArea; #define IS_WHERE_LENGTH 6 #define IS_WHO "/who" #define IS_WHO_LENGTH 4 +#define IS_JOINCHANNEL "/join " +#define IS_JOINCHANNEL_LENGTH 6 +#define IS_REGCHANNEL "/register " +#define IS_REGCHANNEL_LENGTH 10 +#define IS_LISTCHANNELS "/list" +#define IS_LISTCHANNELS_LENGTH 5 +#define IS_QUITCHANNEL "/quit" +#define IS_QUITCHANNEL_LENGTH 5 /** * gets in between usernick and message text depending on @@ -117,6 +128,11 @@ class ChatWindow : public Window, public gcn::ActionListener, */ ChatWindow(); + /** + * + */ + ~ChatWindow(); + /** * Logic (updates components' size) */ @@ -128,7 +144,7 @@ class ChatWindow : public Window, public gcn::ActionListener, * @param line Text message. * @parem own Type of message (usually the owner-type). */ - void chatLog(std::string line, int own); + void chatLog(std::string line, int own, std::string channelName = "General"); /* * Calls original chat_log() after processing the packet. @@ -175,7 +191,27 @@ class ChatWindow : public Window, public gcn::ActionListener, * chatlog.chat_send("Zaeiru", "Hello to all users on the screen!"); */ void - chatSend(const std::string &nick, std::string msg); + chatSend(const std::string &nick, std::string msg, std::string channelName); + + /** Called to add the channel to the channel manager */ + void + addChannel(short channel, std::string channelName); + + /** Called to remove the channel from the channel manager */ + void + removeChannel(short channel); + + /** Called to create a new channel tab */ + void + createNewChannelTab(std::string channelName); + + /** Called to join channel */ + void + enterChannel(std::string channel, std::string password = "None"); + + /** Called to output text to a specific channel */ + void + sendToChannel(short channel, std::string user, std::string msg); /** Called when key is pressed */ void @@ -192,7 +228,9 @@ class ChatWindow : public Window, public gcn::ActionListener, private: bool mTmpVisible; - /** One item in the chat log */ + int mItems; + int mItemsKeep; + typedef struct CHATLOG { std::string nick; @@ -200,15 +238,17 @@ class ChatWindow : public Window, public gcn::ActionListener, int own; }; - std::list mChatlog; /**< Chat log */ - - int mItems; - int mItemsKeep; + std::list mChatlog; /** Constructs failed messages for actions */ std::string const_msg(CHATSKILL); + std::map mTabs; + TabbedContainer *mContainer; /**< Tabbed container for tabbing between channels */ + GCContainer *mTab; /**< Tabs */ gcn::TextField *mChatInput; /**< Input box for typing chat messages */ + std::map mChannelOutput; /**< Map each TextOutput to a tab */ + std::map mChannelScroll; /**< Map each ScrollArea to a tab */ BrowserBox *mTextOutput; /**< Text box for displaying chat history */ ScrollArea *mScrollArea; /**< Scroll area around text output */ diff --git a/src/gui/tabbedcontainer.cpp b/src/gui/tabbedcontainer.cpp index 75f9f3cf..5d6d21d1 100644 --- a/src/gui/tabbedcontainer.cpp +++ b/src/gui/tabbedcontainer.cpp @@ -26,6 +26,7 @@ #include "button.h" #include "../utils/tostring.h" +#include "../utils/dtor.h" #define TABWIDTH 60 #define TABHEIGHT 20 @@ -37,10 +38,7 @@ TabbedContainer::TabbedContainer(): TabbedContainer::~TabbedContainer() { - for (WidgetIterator i = mTabs.begin(); i != mTabs.end(); i++) { - remove(*i); - delete (*i); - } + for_each(mTabs.begin(), mTabs.end(), make_dtor(mTabs)); mTabs.clear(); mContents.clear(); @@ -55,7 +53,7 @@ void TabbedContainer::addTab(gcn::Widget *widget, const std::string &caption) tab->setSize(TABWIDTH, TABHEIGHT); add(tab, TABWIDTH * tabNumber, 0); - mTabs.push_back(tab); + mTabs[caption] = tab; mContents.push_back(widget); widget->setPosition(0, TABHEIGHT); @@ -64,7 +62,18 @@ void TabbedContainer::addTab(gcn::Widget *widget, const std::string &caption) if (!mActiveContent) { mActiveContent = widget; add(mActiveContent); + tab->setLogged(true); } + + mWidgets[widget] = caption; +} + +void TabbedContainer::removeTab(const std::string &caption) +{ + gcn::ActionEvent actionEvent(this, "0"); + action(actionEvent); + remove(mTabs[caption]); + mTabs.erase(caption); } void TabbedContainer::logic() @@ -80,16 +89,21 @@ void TabbedContainer::logic() void TabbedContainer::action(const gcn::ActionEvent &event) { - std::stringstream ss(event.getId()); int tabNo; + std::stringstream ss(event.getId()); ss >> tabNo; gcn::Widget *newContent = mContents[tabNo]; + if (newContent) { if (mActiveContent) { + // Unhighlight old tab + ((Button*)mTabs[mWidgets[mActiveContent]])->setLogged(false); remove(mActiveContent); } mActiveContent = newContent; + // Highlight new tab + ((Button*)mTabs[mWidgets[mActiveContent]])->setLogged(true); add(newContent); } } @@ -98,3 +112,13 @@ void TabbedContainer::setOpaque(bool opaque) { Container::setOpaque(opaque); } + +short TabbedContainer::getNumberOfTabs() +{ + return mTabs.size(); +} + +std::string TabbedContainer::getActiveWidget() +{ + return mWidgets[mActiveContent]; +} diff --git a/src/gui/tabbedcontainer.h b/src/gui/tabbedcontainer.h index 2dc017ae..7f8deef9 100644 --- a/src/gui/tabbedcontainer.h +++ b/src/gui/tabbedcontainer.h @@ -26,6 +26,7 @@ #include #include +#include #include @@ -41,18 +42,25 @@ class TabbedContainer : public gcn::Container, public gcn::ActionListener void addTab(gcn::Widget *widget, const std::string &caption); + void removeTab(const std::string &caption); + void logic(); void action(const gcn::ActionEvent &event); void setOpaque(bool opaque); + short getNumberOfTabs(); + + std::string getActiveWidget(); + private: typedef std::vector Widgets; typedef Widgets::iterator WidgetIterator; - Widgets mTabs; // The actual tabs at the top + std::map mTabs; // tabs mapped to their channel name Widgets mContents; // The contents of the tabs + std::map mWidgets; gcn::Widget *mActiveContent; }; diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index f765f0f4..076be056 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "messagein.h" #include "protocol.h" @@ -43,6 +44,11 @@ ChatHandler::ChatHandler() { static const Uint16 _messages[] = { GPMSG_SAY, + CPMSG_REGISTER_CHANNEL_RESPONSE, + CPMSG_ENTER_CHANNEL_RESPONSE, + CPMSG_LIST_CHANNELS_RESPONSE, + CPMSG_PUBMSG, + CPMSG_QUIT_CHANNEL_RESPONSE, /* SMSG_BEING_CHAT, SMSG_PLAYER_CHAT, @@ -59,6 +65,9 @@ void ChatHandler::handleMessage(MessageIn &msg) { Being *being; std::string chatMsg; + short channelId; + std::string userNick; + std::string channelName; //Sint16 chatMsgLength; switch (msg.getId()) @@ -76,7 +85,74 @@ void ChatHandler::handleMessage(MessageIn &msg) chatWindow->chatLog("John Doe : " + chatMsg, BY_OTHER); } break; + case CPMSG_REGISTER_CHANNEL_RESPONSE: + if(msg.readByte() == ERRMSG_OK) + { + channelId = msg.readShort(); + std::string channelName = msg.readString(); + chatWindow->chatLog("Registered Channel " + channelName, BY_SERVER); + chatWindow->addChannel(channelId, channelName); + chatWindow->createNewChannelTab(channelName); + } + else + { + chatWindow->chatLog("Error registering channel", BY_SERVER); + } + break; + case CPMSG_ENTER_CHANNEL_RESPONSE: + if(msg.readByte() == ERRMSG_OK) + { + channelId = msg.readShort(); + channelName = msg.readString(); + std::string announcement = msg.readString(); + std::vector userList; + while(msg.getUnreadLength()) + { + userList.push_back(msg.readString()); + } + chatWindow->addChannel(channelId, channelName); + chatWindow->createNewChannelTab(channelName); + chatWindow->chatLog(announcement, BY_SERVER, channelName); + } + else + { + chatWindow->chatLog("Error joining channel", BY_SERVER); + } + break; + + case CPMSG_LIST_CHANNELS_RESPONSE: + chatWindow->chatLog("Listing Channels", BY_SERVER); + while(msg.getUnreadLength()) + { + channelName = msg.readString(); + std::ostringstream numUsers; + numUsers << msg.readShort(); + if(channelName != "") + { + channelName += " - "; + channelName += numUsers.str(); + chatWindow->chatLog(channelName, BY_SERVER); + } + } + chatWindow->chatLog("End of channel list", BY_SERVER); + break; + case CPMSG_PUBMSG: + channelId = msg.readShort(); + userNick = msg.readString(); + chatMsg = msg.readString(); + + chatWindow->sendToChannel(channelId, userNick, chatMsg); + break; + + case CPMSG_QUIT_CHANNEL_RESPONSE: + if(msg.readByte() == ERRMSG_OK) + { + channelId = msg.readShort(); + // remove the chat tab + chatWindow->removeChannel(channelId); + } + break; /* // Received speech from being case SMSG_BEING_CHAT: diff --git a/src/net/chatserver/chatserver.cpp b/src/net/chatserver/chatserver.cpp index 32979ea5..f24e4cd5 100644 --- a/src/net/chatserver/chatserver.cpp +++ b/src/net/chatserver/chatserver.cpp @@ -81,14 +81,14 @@ void Net::ChatServer::privMsg(const std::string &recipient, } void Net::ChatServer::registerChannel(const std::string &name, - const std::string &annoucement, const std::string &password, + const std::string &announcement, const std::string &password, char isPrivate) { MessageOut msg(PCMSG_REGISTER_CHANNEL); msg.writeByte(isPrivate); msg.writeString(name); - msg.writeString(annoucement); + msg.writeString(announcement); msg.writeString(password); connection->send(msg); @@ -103,11 +103,11 @@ void Net::ChatServer::unregisterChannel(short channel) connection->send(msg); } -void Net::ChatServer::enterChannel(short channel, const std::string &password) +void Net::ChatServer::enterChannel(const std::string &channel, const std::string &password) { MessageOut msg(PCMSG_ENTER_CHANNEL); - msg.writeShort(channel); + msg.writeString(channel); msg.writeString(password); connection->send(msg); @@ -121,3 +121,10 @@ void Net::ChatServer::quitChannel(short channel) connection->send(msg); } + +void Net::ChatServer::getChannelList() +{ + MessageOut msg(PCMSG_LIST_CHANNELS); + + connection->send(msg); +} diff --git a/src/net/chatserver/chatserver.h b/src/net/chatserver/chatserver.h index cf86baf3..c4e0003d 100644 --- a/src/net/chatserver/chatserver.h +++ b/src/net/chatserver/chatserver.h @@ -48,9 +48,12 @@ namespace Net void unregisterChannel(short channel); - void enterChannel(short channel, const std::string &password); + void enterChannel(const std::string &channel, const std::string &password); void quitChannel(short channel); + + void getChannelList(); + } } diff --git a/src/net/protocol.h b/src/net/protocol.h index 78a42e42..eb27af7d 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -119,7 +119,7 @@ enum { // Login/Register PAMSG_REGISTER = 0x0000, // L version, S username, S password, S email APMSG_REGISTER_RESPONSE = 0x0002, // B error - PAMSG_UNREGISTER = 0x0003, // S username, S password + PAMSG_UNREGISTER = 0x0003, // - APMSG_UNREGISTER_RESPONSE = 0x0004, // B error PAMSG_LOGIN = 0x0010, // L version, S username, S password APMSG_LOGIN_RESPONSE = 0x0012, // B error @@ -175,6 +175,7 @@ enum { PGMSG_USE_ITEM = 0x0300, // L item id GPMSG_USE_RESPONSE = 0x0301, // B error GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }* + GPMSG_BEING_DEAD = 0xDEAD, // W being id // Chat CPMSG_ERROR = 0x0401, // B error @@ -186,14 +187,16 @@ enum { PCMSG_PRIVMSG = 0x0412, // S user, S text // -- Channeling PCMSG_REGISTER_CHANNEL = 0x0413, // B pub/priv, S name, S announcement, S password - CPMSG_REGISTER_CHANNEL_RESPONSE = 0x0414, // B error + CPMSG_REGISTER_CHANNEL_RESPONSE = 0x0414, // B error, W channel, S channel PCMSG_UNREGISTER_CHANNEL = 0x0415, // W channel CPMSG_UNREGISTER_CHANNEL_RESPONSE = 0x0416, // B error CPMSG_CHANNEL_EVENT = 0x0418, // W channel, B event, S user PCMSG_ENTER_CHANNEL = 0x0419, // W channel, S password - CPMSG_ENTER_CHANNEL_RESPONSE = 0x0420, // B error + CPMSG_ENTER_CHANNEL_RESPONSE = 0x0420, // B error, W channel, S channel PCMSG_QUIT_CHANNEL = 0x0421, // W channel CPMSG_QUIT_CHANNEL_RESPONSE = 0x0422, // B error + PCMSG_LIST_CHANNELS = 0x0423, // - + CPMSG_LIST_CHANNELS_RESPONSE = 0x0424, // W number of channels, S channels XXMSG_INVALID = 0x7FFF }; -- cgit v1.2.3-70-g09d2 From 4062d2cd386ae67e6901d0f1de953e0a0aa58e68 Mon Sep 17 00:00:00 2001 From: Rogier Polak Date: Tue, 13 Mar 2007 00:00:20 +0000 Subject: Removed some tabs --- src/net/chathandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/net/chathandler.cpp') diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index 076be056..3efe3174 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -119,7 +119,7 @@ void ChatHandler::handleMessage(MessageIn &msg) chatWindow->chatLog("Error joining channel", BY_SERVER); } break; - + case CPMSG_LIST_CHANNELS_RESPONSE: chatWindow->chatLog("Listing Channels", BY_SERVER); while(msg.getUnreadLength()) @@ -141,10 +141,10 @@ void ChatHandler::handleMessage(MessageIn &msg) channelId = msg.readShort(); userNick = msg.readString(); chatMsg = msg.readString(); - + chatWindow->sendToChannel(channelId, userNick, chatMsg); break; - + case CPMSG_QUIT_CHANNEL_RESPONSE: if(msg.readByte() == ERRMSG_OK) { -- cgit v1.2.3-70-g09d2 From 1a9320fafb23940d0463e6f384713d0f99fc0c61 Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Wed, 19 Sep 2007 17:28:33 +0000 Subject: Merged 0.0 changes from revision 3362 to 3580 to trunk. --- ChangeLog | 306 ++++++++++++++++++++++++++++++- data/graphics/gui/CMakeLists.txt | 4 + data/graphics/gui/Makefile.am | 4 + data/graphics/gui/close_button.png | Bin 0 -> 650 bytes data/graphics/gui/hits_yellow.png | Bin 356 -> 894 bytes data/graphics/gui/item_shortcut_bgr.png | Bin 0 -> 1026 bytes data/graphics/gui/mouse.png | Bin 1134 -> 4508 bytes data/graphics/gui/unknown-item.png | Bin 0 -> 540 bytes data/graphics/images/login_wallpaper.png | Bin 215527 -> 643307 bytes src/CMakeLists.txt | 22 ++- src/Makefile.am | 38 ++-- src/animationparticle.cpp | 3 +- src/being.cpp | 90 ++------- src/being.h | 42 +---- src/game.cpp | 179 ++++++++++-------- src/gui/button.cpp | 20 +- src/gui/button.h | 10 +- src/gui/buy.cpp | 125 ++++++++----- src/gui/buy.h | 10 +- src/gui/char_select.cpp | 12 +- src/gui/char_select.h | 31 ++-- src/gui/chat.cpp | 10 +- src/gui/debugwindow.cpp | 14 +- src/gui/debugwindow.h | 9 +- src/gui/equipmentwindow.cpp | 1 + src/gui/gui.cpp | 45 +++-- src/gui/gui.h | 43 +++-- src/gui/inventorywindow.cpp | 13 +- src/gui/inventorywindow.h | 11 +- src/gui/itemcontainer.cpp | 4 + src/gui/itemshortcutcontainer.cpp | 224 ++++++++++++++++++++++ src/gui/itemshortcutcontainer.h | 115 ++++++++++++ src/gui/itemshortcutwindow.cpp | 74 ++++++++ src/gui/itemshortcutwindow.h | 69 +++++++ src/gui/menuwindow.cpp | 12 +- src/gui/popupmenu.cpp | 6 - src/gui/selectionlistener.h | 16 +- src/gui/sell.cpp | 127 +++++++------ src/gui/sell.h | 16 +- src/gui/setup.cpp | 10 +- src/gui/setup_keyboard.cpp | 187 +++++++++++++++++++ src/gui/setup_keyboard.h | 84 +++++++++ src/gui/shoplistbox.cpp | 20 +- src/gui/skill.cpp | 6 +- src/gui/skill.h | 1 - src/gui/status.cpp | 6 +- src/gui/status.h | 3 +- src/gui/updatewindow.cpp | 4 +- src/gui/viewport.cpp | 25 +-- src/gui/viewport.h | 13 -- src/gui/window.cpp | 198 +++++++++++++++++--- src/gui/window.h | 99 +++++++++- src/gui/windowlistener.h | 86 +++++++++ src/imageparticle.cpp | 8 +- src/itemshortcut.cpp | 87 +++++++++ src/itemshortcut.h | 130 +++++++++++++ src/keyboardconfig.cpp | 144 +++++++++++++++ src/keyboardconfig.h | 185 +++++++++++++++++++ src/localplayer.cpp | 43 ++++- src/localplayer.h | 22 +++ src/main.cpp | 19 +- src/monster.cpp | 10 +- src/net/beinghandler.cpp | 84 +++++---- src/net/chathandler.cpp | 2 + src/net/inventoryhandler.cpp | 2 + src/net/playerhandler.cpp | 3 +- src/particle.cpp | 96 +++++----- src/particle.h | 112 +++++------ src/particleemitter.cpp | 30 ++- src/player.cpp | 50 ++--- src/player.h | 3 - src/resources/equipmentdb.cpp | 156 ---------------- src/resources/equipmentdb.h | 55 ------ src/resources/equipmentinfo.h | 52 ------ src/resources/itemdb.cpp | 126 ++++++++++--- src/resources/iteminfo.cpp | 86 ++++++++- src/resources/iteminfo.h | 118 +++++++----- src/resources/mapreader.cpp | 2 +- src/resources/monsterdb.cpp | 8 +- src/resources/monsterinfo.cpp | 12 +- src/resources/monsterinfo.h | 16 +- src/resources/spritedef.h | 4 +- src/textparticle.cpp | 11 +- src/textparticle.h | 17 +- src/utils/fastsqrt.h | 2 + src/utils/minmax.h | 1 + src/utils/trim.h | 53 ++++++ src/vector.h | 134 ++++++++++++++ tools/adler32.c | 67 +++++++ 89 files changed, 3257 insertions(+), 1140 deletions(-) create mode 100644 data/graphics/gui/close_button.png create mode 100644 data/graphics/gui/item_shortcut_bgr.png create mode 100644 data/graphics/gui/unknown-item.png create mode 100644 src/gui/itemshortcutcontainer.cpp create mode 100644 src/gui/itemshortcutcontainer.h create mode 100644 src/gui/itemshortcutwindow.cpp create mode 100644 src/gui/itemshortcutwindow.h create mode 100644 src/gui/setup_keyboard.cpp create mode 100644 src/gui/setup_keyboard.h create mode 100644 src/gui/windowlistener.h create mode 100644 src/itemshortcut.cpp create mode 100644 src/itemshortcut.h create mode 100644 src/keyboardconfig.cpp create mode 100644 src/keyboardconfig.h delete mode 100644 src/resources/equipmentdb.cpp delete mode 100644 src/resources/equipmentdb.h delete mode 100644 src/resources/equipmentinfo.h create mode 100644 src/utils/trim.h create mode 100644 src/vector.h create mode 100644 tools/adler32.c (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index 082c9b94..d0e43d40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,19 @@ * src/gui/button.cpp: Fixed improper const qualifier. +2007-09-12 Bjørn Lindeijer + + * data/items.xml, data/equipment.xml: Added temporary weapon IDs below + 256 to use as view-ID in eAthena's item DB. + * src/gui/shoplistbox.cpp, src/gui/buy.h, src/gui/buy.cpp: Allowed + selection of items that cannot be afforded, so that their descriptions + are still accessible. Also made sure the player's money value of + ShopItemList gets updated. + +2007-09-11 Eugenio Favalli + + * src/gui/chat.cpp, tmw.cbp: Fixed admin commands. + 2007-09-10 Eugenio Favalli * configure.ac, data/fonts/dejavusans.ttf, @@ -18,17 +31,103 @@ * po/LINGUAS: Added German to the list of available languages. * po/de.po: Fixed two syntax errors preventing compilation. -2007-08-27 Matthias Hartmann +2007-09-08 Philipp Sehmisch + + * data/graphics/particles/aniblaze.png, + data/graphics/particles/cookingfire.particle.xml, + data/graphics/particles/fireplace.particle.xml, + data/graphics/particles/flame.particle.xml: Improved fire effects by + using animated particles. - * po/de.po: Added german translation. +2007-09-06 Philipp Sehmisch + + * src/animationparticle.cpp, src/imageparticle.cpp: Fixed animated + particles. + +2007-09-01 Bjørn Lindeijer + + * src/Makefile.am: Fixed the entry for windowlistener.h. + +2007-08-30 Bjørn Lindeijer + + * src/localplayer.cpp, src/player.cpp, src/main.cpp, src/being.cpp, + src/CMakeLists.txt, src/Makefile.am, src/resources/iteminfo.h, + src/resources/equipmentdb.h, src/resources/equipmentinfo.h, + src/resources/itemdb.cpp, src/resources/iteminfo.cpp, + src/resources/equipmentdb.cpp, src/resources/equipmentinfo.cpp, + src/resources/spritedef.h, src/being.h, data/items.xml, + data/equipment.xml: Merged equipment database with items database and + got rid of the unused item art attribute. + * src/net/beinghandler.cpp, src/net/charserverhandler.cpp: Removed the + now unnecessary multiplication of weapon IDs with 10000. + * src/resources/iteminfo.cpp, data/graphics/items/unknown.png: Added + fallback item icon and use it for unknown items or when item image + fails to load. + * NEWS: Updated with changes since last update. + * data/items.xml, data/equipment.xml: Reverted equipment database and + included original low-ID items in items.xml for compatibility with + eAthena, which doesn't support View ID to come above 255. + * src/resources/itemdb.cpp: Accept items without a name. + +2007-08-29 Bjørn Lindeijer + + * src/gui/sell.cpp, src/gui/inventorywindow.cpp, src/gui/sell.h: Made + sell dialog resizable and tweaked inventory resize code a bit. + * data/items.xml: Fixed typo in chainmail description. + +2007-08-28 Bjørn Lindeijer + + * src/gui/window.cpp, src/gui/inventorywindow.h, + src/gui/selectionlistener.h, src/gui/buy.h, + src/gui/itemshortcutwindow.cpp, src/gui/inventorywindow.cpp, + src/gui/buy.cpp, src/gui/window.h, src/gui/windowlistener.h, + src/gui/itemshortcutwindow.h, src/CMakeLists.txt, src/Makefile.am: + Made buy dialog resizable and added a WindowListener class for + listening for window resize and move events. + * src/textparticle.h, src/particle.h, src/CMakeLists.txt, + src/particle.cpp, src/imageparticle.cpp, src/vector.h, + src/textparticle.cpp, src/Makefile.am: Added Vector class and used it + in the particle engine. + +2007-08-27 Bjørn Lindeijer + + * src/engine.cpp, src/resources/mapreader.cpp: Made client search for + both compressed and non-compressed map files. 2007-08-27 Eugenio Favalli + * src/game.cpp: Assigned unused emotions to Alt +/-. (applied a patch + by Quiche_on_a_leash). + * data/maps/new_1-1.tmx, data/maps/new_1-1.tmx.gz, + data/maps/new_10-1.tmx, data/maps/new_10-1.tmx.gz, + data/maps/new_11-1.tmx, data/maps/new_11-1.tmx.gz, + data/maps/new_12-1.tmx, data/maps/new_12-1.tmx.gz, + data/maps/new_13-1.tmx, data/maps/new_13-1.tmx.gz, + data/maps/new_14-1.tmx, data/maps/new_14-1.tmx.gz, + data/maps/new_15-1.tmx, data/maps/new_15-1.tmx.gz, + data/maps/new_16-1.tmx, data/maps/new_16-1.tmx.gz, + data/maps/new_17-1.tmx, data/maps/new_17-1.tmx.gz, + data/maps/new_18-1.tmx, data/maps/new_18-1.tmx.gz, + data/maps/new_19-1.tmx, data/maps/new_19-1.tmx.gz, + data/maps/new_2-1.tmx, data/maps/new_2-1.tmx.gz, + data/maps/new_20-1.tmx, data/maps/new_20-1.tmx.gz, + data/maps/new_3-1.tmx, data/maps/new_3-1.tmx.gz, + data/maps/new_4-1.tmx, data/maps/new_4-1.tmx.gz, + data/maps/new_5-1.tmx, data/maps/new_5-1.tmx.gz, + data/maps/new_6-1.tmx, data/maps/new_6-1.tmx.gz, + data/maps/new_7-1.tmx, data/maps/new_7-1.tmx.gz, + data/maps/new_8-1.tmx, data/maps/new_8-1.tmx.gz, + data/maps/new_9-1.tmx, data/maps/new_9-1.tmx.gz: Replaced compressed + maps with layer compressed maps. * data/maps/new_1-1.tmx.gz: Added test npcs. * src/openglgraphics.cpp, tmw.cbp: Fixed compilation with old OpenGL headers. * po/it.po: Updated italian translation. +2007-08-27 Matthias Hartmann + + * po/de.po: Added German translation. + 2007-08-27 Guillaume Melquiond * src/gui/chat.h, src/gui/chat.cpp: Added "/admin" chat command for @@ -36,6 +135,11 @@ * src/engine.cpp, src/resources/mapreader.cpp: Ported patch from 0.0, in order to support missing extensions and uncompressed maps. +2007-08-26 Eugenio Favalli + + * src/gui/updatewindow.cpp, src/main.cpp, tmw.cbp: Removed home dir + from config file to avoid encoding issues. + 2007-08-26 Guillaume Melquiond * src/gui/button.cpp: Fixed incorrect button dimensions, as they mess @@ -58,10 +162,103 @@ for rectangle OpenGL textures when available, in order to reduce video memory usage. +2007-08-24 Bjørn Lindeijer + + * src/gui/gui.h, src/gui/gui.cpp: Removed useless logic method and + reverted mouse cursor to non-static since there can be only one Gui + instance so there is no point in supporting a shared resource. + * src/gui/window.cpp, src/gui/gui.h: Removed unnecessary + Gui::isCustomCursor method. + * src/gui/char_select.h, src/gui/char_select.cpp, src/utils/trim.h: + Added trimming of name for new character creation. + * src/net/chathandler.cpp: Added trimming of chat messages appearing + above players. + * src/gui/window.cpp, src/gui/window.h: Improved resize mouse cursor + indication, removing duplicated code and fixing indicator above resize + grip. + +2007-08-23 Bjørn Lindeijer + + * src/gui/viewport.h, src/gui/viewport.cpp: Removed two useless popup + related methods. + * src/gui/debugwindow.h, src/gui/debugwindow.cpp: Use generic close + button functionality. + * src/particle.h, src/particleemitter.cpp, src/particle.cpp: Renamed + Particle::mVector to Particle::mVelocity for clarity. + * src/localplayer.cpp, src/gui/ministatus.cpp, src/gui/status.cpp, + src/being.cpp, src/net/charserverhandler.cpp, + src/net/playerhandler.cpp, src/localplayer.h, src/being.h: Changed XP + gaining effect to appear on the player instead. + * data/graphics/gui/hits_yellow.png: Restored shadow of yellow font. + +2007-08-22 Bjørn Lindeijer + + * src/gui/itemshortcutcontainer.h: Fixed compiler warning. + * src/CMakeLists.txt, src/Makefile.am: Updated source lists. + * data/graphics/gui/CMakeLists.txt, data/graphics/gui/Makefile.am: + Added close button and item shortcut backgrounds to files that will be + installed. + * src/gui/itemshortcutcontainer.cpp: Make sure mGridWidth and + mGridHeight are initialized properly (fixes arithmetic exception in + ItemShortcutContainer::draw). + * src/keyboardconfig.cpp: Changed default sitting key back to 's'. + * src/net/equipmenthandler.cpp: Removed a line that attempted to set + the player's weapon sprite with each kind of equipment. Seems to work + fine without as well. + * src/gui/chat.cpp, src/utils/trim.h, src/CMakeLists.txt, + src/Makefile.am: Added trimming of chat messages. + +2007-08-22 Philipp Sehmisch + + * data/graphics/sprites/chest-lightplatemail-male.png, + data/graphics/sprites/chest-lightplatemail-female.png, + data/graphics/items/armor-chest-lightplatemail.png, + data/graphics/tiles/woodland_indoor_x2.png: Another color correction + at the light platemail (looks more metalic now) + * data/maps/new_18-1.tmx.gz, data/maps/new_19-1.tmx.gz, + data/images/minimap_new_18-1.png, data/images/minimap_new_19-1.png: + Removed a tree that prevented people from sitting on one of the + benches properly. Added correct minimap to woodland village and + surrounding. + +2007-08-22 Joshua Langley + + * data/graphics/gui/item_shortcut_bgr.png, src/game.cpp, + src/gui/gui.cpp, src/gui/itemcontainer.cpp, + src/gui/itemshortcutcontainer.cpp, src/gui/itemshortcutcontainer.h, + src/gui/itemshortcutwindow.cpp, src/gui/itemshortcutwindow.h, + src/gui/menuwindow.cpp, src/gui/setup_keyboard.cpp, src/gui/window.h, + src/itemshortcut.cpp, src/itemshortcut.h, src/keyboardconfig.cpp, + src/keyboardconfig.h, src/localplayer.cpp, src/localplayer.h, + src/main.cpp, src/net/inventoryhandler.cpp, src/utils/tostring.h, + tmw.cbp: Added item shortcut bar. + +2007-08-20 Joshua Langley + + * data/graphics/gui/mouse.png, src/gui/equipmentwindow.cpp, + src/gui/gui.cpp, src/gui/gui.h, src/gui/inventorywindow.cpp, + src/gui/setup.cpp, src/gui/skill.cpp, src/gui/skill.h, + src/gui/status.cpp, src/gui/window.cpp, src/gui/window.h, + data/graphics/gui/close_button.png: Added close button functionality, + resize cursor cues. + * data/graphics/gui/hits_yellow.png, src/being.cpp, src/being.h, + src/gui/gui.cpp, src/localplayer.cpp, src/localplayer.h, + src/net/charserverhandler.cpp, src/net/playerhandler.cpp, + src/particle.cpp, src/particle.h: Added monster killed xp notification + effect. + 2007-08-19 Bjørn Lindeijer - * src/CMakeLists.txt: Updated CMake file. * data/equipment.xml: Fixed typo in female light plate mail. + * NEWS: Updated with changes since 0.0.23. + * src/CMakeLists.txt: Updated CMake file. + +2007-08-19 Joshua Langley + + * src/keyboardconfig.cpp, src/keyboardconfig.h: Minor cleanup. + * src/gui/buy.cpp, src/gui/sell.cpp: Buy/sell fixed minimum quantity. + * src/gui/setup_keyboard.cpp, src/gui/setup_keyboard.h: Fixed bug - + reverts unassigned key. 2007-08-19 Guillaume Melquiond @@ -73,6 +270,23 @@ src/net/playerhandler.cpp, src/localplayer.h: Adapted to new server handling of character attributes. +2007-08-17 Bjørn Lindeijer + + * tools/adler32.c: Added little program for calculating adler32 + checksums of files. + * src/gui/setup_keyboard.cpp: Fixed compile issue related to array + bound not being an integer constant. + +2007-08-15 Philipp Sehmisch + + * data/graphics/sprites/npcs.png, data/graphics/sprites/npc.xml: + Added farmer NPC for woodland village. + +2007-08-14 Eugenio Favalli + + * src/gui/popupmenu.cpp, src/gui/viewport.cpp, src/gui/viewport.h, + tmw.cbp: Fixed popup menu requiring one more click after being used. + 2007-08-14 Guillaume Melquiond * src/net/messagein.h, src/net/messagein.cpp: Fixed error-prone @@ -111,6 +325,15 @@ * src/gui/npclistdialog.cpp, src/gui/npclistdialog.h, src/net/npchandler.cpp: Removed colon in NPC choice messages. +2007-08-09 Philipp Sehmisch + + * data/graphics/sprites/chest-lightplatemail-male.png, + data/graphics/sprites/chest-lightplatemail-female.png, + data/graphics/items/armor-chest-lightplatemail.png, + data/graphics/tiles/woodland_indoor_x2.png: Gave the platemail + armor a blue tint. Looks less boring and makes recoloring through + hue shifting possible. + 2007-08-09 Guillaume Melquiond * po/POTFILES.in: Updated list of translatable source files. @@ -133,9 +356,29 @@ data/graphics/images/EquipBackground.png: Re-designed equipment window, un-equip created. +2007-08-08 Philipp Sehmisch + + * data/graphics/particles/cookingfire.particle.xml, + data/graphics/particles/fireplace.particle.xml, + data/maps/new_20-1.tmx.gz: Added particle effects and music to the + woodland village indoor map. + * data/maps/new_19-1.tmx.gz: Added overlay effect and music to + woodland village outdoor map. + * data/maps/new_18-1.tmx.gz: Fixed some collision map errors and added + music and overlay effect to the surrounding of the woodland village. + +2007-08-07 Philipp Sehmisch + + * data/graphics/sprites/npcs.png: Added two new NPCs and gave some + of the older NPCs a makeover to look more like the style of the new + playerset. + * data/maps/new_20-1.tmx.gz: Corrected a few mapping errors in the + new woodland village. + * data/items.xml: Tweaked description and values of the scythe. + 2007-08-07 Guillaume Melquiond - * po/Makevars, src/main.cpp: Replaced PACKAGE by tmw to reduce + * po/Makevars, src/main.cpp: Replaced PACKAGE by tmw to reduce preprocessing hell. Set gettext charset to utf8. * src/gui/menuwindow.cpp, src/gui/connection.cpp, src/gui/register.cpp, src/gui/equipmentwindow.cpp, @@ -172,6 +415,14 @@ Makefile.am, autogen.sh: Used autopoint for generating gettext environment, and removed conflicting files. +2007-08-05 Philipp Sehmisch + + * data/graphics/tiles/woodland_indoor.png, + data/graphics/tiles/woodland_indoor_x2.png, + data/graphics/tiles/woodland_indoor_x3.png: Added woodland + village indoor tilesets. + * data/maps/new_20-1.tmx.gz: Added woodland village indoor map. + 2007-08-05 Guillaume Melquiond * configure.ac, Makefile.am, po, src/Makefile.am, src/main.cpp, @@ -222,12 +473,22 @@ src/gui/itemcontainer.cpp, src/gui/checkbox.cpp, src/gui/minimap.cpp, src/gui/scrollarea.cpp, src/gui/popupmenu.cpp: Removed useless yet costly dynamic casts. - -2007-07-25 Guillaume Melquiond - * src/net/beinghandler.cpp, src/net/protocol.h: Added being speed to protocol. +2007-07-25 Joshua Langley + + * src/gui/setup.cpp, src/gui/setup_keyboard.cpp, + src/gui/setup_keyboard.h, src/keyboardconfig.cpp, + src/keyboardconfig.h, src/main.cpp: Minor changes to keyboard config, + keyboard setup gui re-designed. + +2007-07-24 Bjørn Lindeijer + + * src/CMakeLists.txt, src/Makefile.am: Added setup_keyboard.* and + keyboardconfig.* to the list of source files. + * src/keyboardconfig.h: Fixed initialization order. + 2007-07-23 Eugenio Favalli * data/maps/new_1-1.tar.gz, data/maps/new_3-1.tar.gz: Fixed warp @@ -247,8 +508,21 @@ * data/maps/new_1-1.tar.gz: Fixed insecure filenames. +2007-07-17 Joshua Langley + + * src/game.cpp: Only one key per function. + * src/main.cpp: Keyboard configuration included. + * src/gui/button.cpp, src/gui/button.h: Default constructor and + init function added. + * src/gui/setup.cpp: Keyboard setup tab added. + * src/gui/setup_keyboard.cpp, src/gui/setup_keyboard.h: Add to project + file, it is the keyboard setup tab. + * src/keyboardconfig.cpp, src/keyboardconfig.h: Add to project file, + the main keyboard config operations. + 2007-07-16 Eugenio Favalli + * data/items.xml: Fixed description of silk headband. * data/maps/new_1-1.tar.gz, data/maps/new_3-1.tar.gz: Added warp and spawn areas. @@ -262,6 +536,24 @@ * src/net/beinghandler.cpp, src/net/beinghandler.h, src/net/protocol.h: Added support for visible equipment. +2007-07-11 Philipp Sehmisch + + * src/resources/monsterdb.cpp, src/resources/monsterinfo.cpp, + src/resources/monsterinfo.h, src/monster.cpp: Renamed SoundEvent + to MonsterSoundEvent. + * src/resources/equipmentdb.cpp, src/resources/equipmentinfo.cpp, + src/resources/equipmentinfo.h: EquipmentDB now holds the type of + attack animation and the sounds of weapons. + * src/being.cpp. src/being.h, src/localplayer.cpp, + src/net/beinghandler.cpp, src/net/charserverhandler.cpp, + src/net/equipmenthandler.cpp, src/player.cpp, src/player.h: The + type of weapon player characters are using is now set using + setVisibleEquipment() instead of setWeapon() or setWeaponById(). + * src/CMakeLists.txt, src/Makefile.AM, tmw.cbp, The Mana World.dev: + Updated project files and buildscripts. + * data/graphics/images/login-wallpaper.png: Replaced login wallpaper + with a new one by Irukard. + 2007-07-11 Bjørn Lindeijer * src/gui/window.cpp: Fixed resizing windows by their resize grip. diff --git a/data/graphics/gui/CMakeLists.txt b/data/graphics/gui/CMakeLists.txt index 5a02d7f1..649e0917 100644 --- a/data/graphics/gui/CMakeLists.txt +++ b/data/graphics/gui/CMakeLists.txt @@ -7,6 +7,7 @@ SET (FILES button.png buttonpress.png checkbox.png + close_button.png deepbox.png fixedfont.png hits_blue.png @@ -18,6 +19,8 @@ SET (FILES hscroll_right_default.png hscroll_right_highlight.png hscroll_right_pressed.png + item_shortcut_bgr.png + mouse.png menuitemD.png menuitemF.png menuitemN.png @@ -37,6 +40,7 @@ SET (FILES target-cursor-red-m.png target-cursor-red-s.png thickborder.png + unknown-item.png vscroll_blue.png vscroll_down_default.png vscroll_down_highlight.png diff --git a/data/graphics/gui/Makefile.am b/data/graphics/gui/Makefile.am index 92e4f3bb..7287d717 100644 --- a/data/graphics/gui/Makefile.am +++ b/data/graphics/gui/Makefile.am @@ -10,6 +10,7 @@ gui_DATA = \ buttonhi.png \ buttonpress.png \ checkbox.png \ + close_button.png \ deepbox.png \ equip_bg.png \ fixedfont.png \ @@ -22,6 +23,8 @@ gui_DATA = \ hscroll_right_default.png \ hscroll_right_highlight.png \ hscroll_right_pressed.png \ + item_shortcut_bgr.png \ + mouse.png \ menuitemD.png \ menuitemF.png \ menuitemN.png \ @@ -41,6 +44,7 @@ gui_DATA = \ target-cursor-red-m.png \ target-cursor-red-s.png \ thickborder.png \ + unknown-item.png \ vscroll_blue.png \ vscroll_down_default.png \ vscroll_down_highlight.png \ diff --git a/data/graphics/gui/close_button.png b/data/graphics/gui/close_button.png new file mode 100644 index 00000000..f87cc2a9 Binary files /dev/null and b/data/graphics/gui/close_button.png differ diff --git a/data/graphics/gui/hits_yellow.png b/data/graphics/gui/hits_yellow.png index f917bc67..d77b7c05 100644 Binary files a/data/graphics/gui/hits_yellow.png and b/data/graphics/gui/hits_yellow.png differ diff --git a/data/graphics/gui/item_shortcut_bgr.png b/data/graphics/gui/item_shortcut_bgr.png new file mode 100644 index 00000000..e878fc7a Binary files /dev/null and b/data/graphics/gui/item_shortcut_bgr.png differ diff --git a/data/graphics/gui/mouse.png b/data/graphics/gui/mouse.png index 2eeb0e51..84dc2ad1 100644 Binary files a/data/graphics/gui/mouse.png and b/data/graphics/gui/mouse.png differ diff --git a/data/graphics/gui/unknown-item.png b/data/graphics/gui/unknown-item.png new file mode 100644 index 00000000..9201d688 Binary files /dev/null and b/data/graphics/gui/unknown-item.png differ diff --git a/data/graphics/images/login_wallpaper.png b/data/graphics/images/login_wallpaper.png index 54692dfd..7af4f913 100644 Binary files a/data/graphics/images/login_wallpaper.png and b/data/graphics/images/login_wallpaper.png differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fa19cfb5..96338338 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,6 +97,12 @@ SET(SRCS gui/item_amount.h gui/itemcontainer.cpp gui/itemcontainer.h + gui/itemshortcutcontainer.cpp + gui/itemshortcutcontainer.h + gui/itemshortcutwindow.cpp + gui/itemshortcutwindow.h + gui/item_amount.cpp + gui/item_amount.h gui/linkhandler.h gui/listbox.cpp gui/listbox.h @@ -143,6 +149,8 @@ SET(SRCS gui/setup.h gui/setup_joystick.cpp gui/setup_joystick.h + gui/setup_keyboard.cpp + gui/setup_keyboard.h gui/setuptab.h gui/setup_video.cpp gui/setup_video.h @@ -170,12 +178,13 @@ SET(SRCS gui/updatewindow.h gui/vbox.cpp gui/vbox.h - gui/windowcontainer.cpp - gui/windowcontainer.h gui/viewport.cpp gui/viewport.h gui/window.cpp gui/window.h + gui/windowcontainer.cpp + gui/windowcontainer.h + gui/windowlistener.h gui/widgets/dropdown.cpp gui/widgets/dropdown.h net/beinghandler.cpp @@ -239,9 +248,6 @@ SET(SRCS resources/buddylist.h resources/animation.cpp resources/animation.h - resources/equipmentdb.cpp - resources/equipmentdb.h - resources/equipmentinfo.h resources/image.cpp resources/image.h resources/imagewriter.cpp @@ -281,6 +287,7 @@ SET(SRCS utils/strprintf.cpp utils/strprintf.h utils/tostring.h + utils/trim.h utils/xml.cpp utils/xml.h animatedsprite.cpp @@ -317,8 +324,12 @@ SET(SRCS inventory.h item.cpp item.h + itemshortcut.cpp + itemshortcut.h joystick.cpp joystick.h + keyboardconfig.cpp + keyboardconfig.h localplayer.cpp localplayer.h lockedarray.h @@ -351,6 +362,7 @@ SET(SRCS textparticle.cpp textparticle.h tileset.h + vector.h ) ADD_EXECUTABLE(tmw ${SRCS}) diff --git a/src/Makefile.am b/src/Makefile.am index 7006f66e..2f29e299 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/widgets/dropdown.h \ gui/widgets/resizegrip.cpp \ gui/widgets/resizegrip.h \ + gui/box.h \ + gui/box.cpp \ gui/browserbox.cpp \ gui/browserbox.h \ gui/buddywindow.cpp \ @@ -39,12 +41,20 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/gccontainer.h \ gui/gui.cpp \ gui/gui.h \ + gui/hbox.h \ + gui/hbox.cpp \ gui/help.cpp \ gui/help.h \ + gui/inttextbox.h \ + gui/inttextbox.cpp \ gui/inventorywindow.cpp \ gui/inventorywindow.h \ gui/itemcontainer.cpp \ gui/itemcontainer.h \ + gui/itemshortcutcontainer.cpp \ + gui/itemshortcutcontainer.h \ + gui/itemshortcutwindow.cpp \ + gui/itemshortcutwindow.h \ gui/item_amount.cpp \ gui/item_amount.h \ gui/linkhandler.h \ @@ -95,6 +105,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/setup.h \ gui/setup_joystick.cpp \ gui/setup_joystick.h \ + gui/setup_keyboard.cpp \ + gui/setup_keyboard.h \ gui/setuptab.h \ gui/setup_video.cpp \ gui/setup_video.h \ @@ -118,22 +130,17 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/trade.h \ gui/unregisterdialog.cpp \ gui/unregisterdialog.h \ + gui/updatewindow.h \ + gui/updatewindow.cpp \ + gui/vbox.h \ + gui/vbox.cpp \ gui/viewport.cpp \ gui/viewport.h \ gui/window.cpp \ gui/window.h \ gui/windowcontainer.cpp \ gui/windowcontainer.h \ - gui/inttextbox.h \ - gui/inttextbox.cpp \ - gui/box.h \ - gui/box.cpp \ - gui/vbox.h \ - gui/vbox.cpp \ - gui/hbox.h \ - gui/hbox.cpp \ - gui/updatewindow.h \ - gui/updatewindow.cpp \ + gui/windowlistener.h \ net/beinghandler.h \ net/beinghandler.cpp \ net/buysellhandler.h \ @@ -193,9 +200,6 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ resources/ambientoverlay.h \ resources/animation.cpp \ resources/animation.h \ - resources/equipmentdb.cpp \ - resources/equipmentdb.h \ - resources/equipmentinfo.h \ resources/image.cpp \ resources/image.h \ resources/imageloader.cpp \ @@ -235,6 +239,7 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ utils/strprintf.h \ utils/strprintf.cpp \ utils/tostring.h \ + utils/trim.h \ utils/xml.cpp \ utils/xml.h \ animatedsprite.cpp \ @@ -271,8 +276,12 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ inventory.h \ item.cpp \ item.h \ + itemshortcut.cpp \ + itemshortcut.h \ joystick.cpp \ joystick.h \ + keyboardconfig.cpp \ + keyboardconfig.h \ localplayer.cpp \ localplayer.h \ lockedarray.h \ @@ -304,7 +313,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ sprite.h \ textparticle.cpp \ textparticle.h \ - tileset.h + tileset.h \ + vector.h # set the include path found by configure INCLUDES = \ diff --git a/src/animationparticle.cpp b/src/animationparticle.cpp index 30c33da7..c79a5bc4 100644 --- a/src/animationparticle.cpp +++ b/src/animationparticle.cpp @@ -26,7 +26,7 @@ #include "simpleanimation.h" AnimationParticle::AnimationParticle(Map *map, Animation *animation): - ImageParticle(map, 0), + ImageParticle(map, NULL), mAnimation(new SimpleAnimation(animation)) { } @@ -40,6 +40,7 @@ AnimationParticle::AnimationParticle(Map *map, xmlNodePtr animationNode): AnimationParticle::~AnimationParticle() { delete mAnimation; + mImage = NULL; } bool AnimationParticle::update() diff --git a/src/being.cpp b/src/being.cpp index bdb27384..81bed667 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -36,12 +36,10 @@ #include "resources/resourcemanager.h" #include "resources/imageset.h" +#include "resources/iteminfo.h" #include "gui/gui.h" -#include "resources/resourcemanager.h" -#include "resources/imageset.h" - #include "utils/dtor.h" #include "utils/tostring.h" @@ -58,11 +56,11 @@ Being::Being(Uint16 id, Uint16 job, Map *map): mEquipment(new Equipment()), mId(id), mSex(2), - mWeapon(0), mWalkSpeed(150), mSpeedModifier(1024), mSpriteDirection(DIRECTION_DOWN), mDirection(DOWN), mMap(NULL), + mEquippedWeapon(NULL), mHairStyle(0), mHairColor(0), mSpeechTime(0), mPx(0), mPy(0), @@ -302,7 +300,7 @@ Being::setSpeech(const std::string &text, Uint32 time) void Being::takeDamage(int amount) { - gcn::Font* font; + gcn::Font *font; std::string damage = amount ? toString(amount) : "miss"; // Selecting the right color @@ -312,8 +310,9 @@ Being::takeDamage(int amount) } else { - // hit particle effect - controlParticle(particleEngine->addEffect("graphics/particles/hit.particle.xml", 0, 0)); + // Hit particle effect + controlParticle(particleEngine->addEffect( + "graphics/particles/hit.particle.xml", 0, 0)); if (getType() == MONSTER) { @@ -325,7 +324,7 @@ Being::takeDamage(int amount) } } - // show damage number + // Show damage number particleEngine->addTextSplashEffect(damage, 255, 255, 255, font, mPx + 16, mPy + 16); } @@ -340,7 +339,7 @@ void Being::setMap(Map *map) { // Remove sprite from potential previous map - if (mMap != NULL) + if (mMap) { mMap->removeSprite(mSpriteIterator); } @@ -348,12 +347,12 @@ Being::setMap(Map *map) mMap = map; // Add sprite to potential new map - if (mMap != NULL) + if (mMap) { mSpriteIterator = mMap->addSprite(this); } - //clear particle effect list because child particles became invalid + // Clear particle effect list because child particles became invalid mChildParticleEffects.clear(); } @@ -362,7 +361,8 @@ Being::controlParticle(Particle *particle) { if (particle) { - particle->disableAutoDelete(); //the effect may not die without the beings permission or we segvault + // The effect may not die without the beings permission or we segfault + particle->disableAutoDelete(); mChildParticleEffects.push_back(particle); } } @@ -380,20 +380,12 @@ Being::setAction(Action action) currentAction = ACTION_SIT; break; case ATTACK: - switch (getWeapon()) + if (mEquippedWeapon) { - case 3: - currentAction = ACTION_ATTACK; - break; - case 2: - currentAction = ACTION_ATTACK_BOW; - break; - case 1: - currentAction = ACTION_ATTACK_STAB; - break; - case 0: - currentAction = ACTION_ATTACK; - break; + currentAction = mEquippedWeapon->getAttackType(); + } + else { + currentAction = ACTION_ATTACK; } for (int i = 0; i < VECTOREND_SPRITE; i++) { @@ -533,11 +525,9 @@ Being::logic() } } - //Update particle effects - for ( std::list::iterator i = mChildParticleEffects.begin(); - i != mChildParticleEffects.end(); - - ) + // Update particle effects + for (std::list::iterator i = mChildParticleEffects.begin(); + i != mChildParticleEffects.end();) { (*i)->setPosition((float)mPx + 16.0f, (float)mPy + 32.0f); if (!(*i)->isAlive()) @@ -599,46 +589,6 @@ Being::getType() const return UNKNOWN; } -void -Being::setWeaponById(Uint16 weapon) -{ - //TODO: Use an external file to map weapon IDs to weapon types - switch (weapon) - { - case 529: // iron arrows - case 1199: // arrows - break; - - case 623: //scythe - setWeapon(3); - break; - - case 1200: // bow - case 530: // short bow - case 545: // forest bow - setWeapon(2); - break; - - case 521: // sharp knife - /* UNCOMMENT TO TEST SHARP KNIFE AS SCYTHE - * setWeapon(3) - * break; - */ - case 522: // dagger - case 536: // short sword - case 1201: // knife - setWeapon(1); - break; - - case 0: // unequip - setWeapon(0); - break; - - default: - logger->log("Not a weapon: %d", weapon); - } -} - int Being::getOffset(int step) const { // Check whether we're walking in the requested direction diff --git a/src/being.h b/src/being.h index afb3cb8b..fadf9656 100644 --- a/src/being.h +++ b/src/being.h @@ -38,6 +38,7 @@ class AnimatedSprite; class Equipment; +class ItemInfo; class Item; class Map; class Graphics; @@ -161,8 +162,7 @@ class Being : public Sprite void setSpeech(const std::string &text, Uint32 time); /** - * Puts a damage bubble above this being for the specified amount of - * time. + * Puts a damage bubble above this being. * * @param amount The amount of damage. */ @@ -266,27 +266,6 @@ class Being : public Sprite */ virtual Type getType() const; - /** - * Gets the weapon picture id. - */ - Uint16 getWeapon() const { return mWeapon; } - - /** - * Sets the weapon picture id. - * - * @param weapon the picture id - */ - virtual void - setWeapon(Uint16 weapon) { mWeapon = weapon; } - - /** - * Sets the weapon picture id with the weapon id. - * - * @param weapon the weapon id - */ - void - setWeaponById(Uint16 weapon); - /** * Gets the walk speed. */ @@ -380,30 +359,26 @@ class Being : public Sprite getHeight() const; /** - * Returns the required size of a target cursor for this being + * Returns the required size of a target cursor for this being. */ - virtual Being::TargetCursorSize - getTargetCursorSize() const + virtual Being::TargetCursorSize getTargetCursorSize() const { return TC_MEDIUM; } std::auto_ptr mEquipment; /** - * Take control of a particle + * Take control of a particle. */ - void - controlParticle(Particle *particle); + void controlParticle(Particle *particle); protected: /** * Sets the new path for this being. */ - void - setPath(const Path &path, int mod = 1024); + void setPath(const Path &path, int mod = 1024); Uint16 mId; /**< Unique being id */ Uint8 mSex; /**< Character's gender */ - Uint16 mWeapon; /**< Weapon picture id */ Uint16 mWalkSpeed; /**< Walking speed */ Uint16 mSpeedModifier; /**< Modifier to keep course on sync (1024 = normal speed) */ Uint8 mSpriteDirection; /**< Facing direction */ @@ -411,6 +386,9 @@ class Being : public Sprite Map *mMap; /**< Map on which this being resides */ SpriteIterator mSpriteIterator; + /** Engine-related infos about weapon. */ + const ItemInfo* mEquippedWeapon; + Path mPath; std::string mSpeech; Uint16 mHairStyle, mHairColor; diff --git a/src/game.cpp b/src/game.cpp index 495f9a8d..a40bfa28 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -37,7 +37,9 @@ #include "engine.h" #include "flooritemmanager.h" #include "graphics.h" +#include "itemshortcut.h" #include "joystick.h" +#include "keyboardconfig.h" #include "localplayer.h" #include "log.h" #include "npc.h" @@ -53,6 +55,7 @@ #include "gui/gui.h" #include "gui/help.h" #include "gui/inventorywindow.h" +#include "gui/itemshortcutwindow.h" #include "gui/menuwindow.h" #include "gui/minimap.h" #include "gui/ministatus.h" @@ -116,6 +119,7 @@ TradeWindow *tradeWindow; //BuddyWindow *buddyWindow; HelpWindow *helpWindow; DebugWindow *debugWindow; +ItemShortcutWindow *itemShortcutWindow; BeingManager *beingManager = NULL; FloorItemManager *floorItemManager = NULL; @@ -181,6 +185,7 @@ void createGuiWindows() //buddyWindow = new BuddyWindow(); helpWindow = new HelpWindow(); debugWindow = new DebugWindow(); + itemShortcutWindow = new ItemShortcutWindow(); // Initialize window positions //chargeDialog->setPosition( @@ -193,6 +198,7 @@ void createGuiWindows() chatWindow->setVisible(true); miniStatusWindow->setVisible(true); menuWindow->setVisible(true); + itemShortcutWindow->setVisible(true); } /** @@ -220,6 +226,7 @@ void destroyGuiWindows() //delete buddyWindow; delete helpWindow; delete debugWindow; + delete itemShortcutWindow; } Game::Game(): @@ -420,6 +427,14 @@ void Game::handleInput() { gcn::Window *requestedWindow = NULL; + if (setupWindow->isVisible() && + keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE) + { + keyboard.setNewKey((int) event.key.keysym.sym); + keyboard.callbackNewKey(); + keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE); + return; + } switch (event.key.keysym.sym) { case SDLK_F1: @@ -473,65 +488,7 @@ void Game::handleInput() used = true; } break; - - // Hide certain windows - case SDLK_h: - if (!chatWindow->isFocused()) - { - statusWindow->setVisible(false); - inventoryWindow->setVisible(false); - skillDialog->setVisible(false); - setupWindow->setVisible(false); - equipmentWindow->setVisible(false); - helpWindow->setVisible(false); - debugWindow->setVisible(false); - } - break; - - // Picking up items on the floor - case SDLK_g: - case SDLK_z: - if (!chatWindow->isFocused()) - { - Uint16 x = player_node->mX / 32, y = player_node->mY / 32; - FloorItem *item = floorItemManager->findByCoordinates(x, y); - - // If none below the player, try the tile in front of - // the player - if (!item) - { - // Temporary until tile-based picking is removed. - switch (player_node->getSpriteDirection()) - { - case DIRECTION_UP : --y; break; - case DIRECTION_DOWN : ++y; break; - case DIRECTION_LEFT : --x; break; - case DIRECTION_RIGHT: ++x; break; - default: break; - } - - item = floorItemManager->findByCoordinates(x, y); - } - - if (item) - player_node->pickUp(item); - - used = true; - } - break; - - // attacking - // TODO: Reimplement attacking with joystick buttons - // (old code allowed permanent attacking and not 1 attack - // with each button push) - // I would like to do this but i don't own a joystick. - case SDLK_LCTRL: - case SDLK_RCTRL: - player_node->attack(); - used = true; - break; - - // Quitting confirmation dialog + // Quitting confirmation dialog case SDLK_ESCAPE: if (!quitDialog) { @@ -547,6 +504,74 @@ void Game::handleInput() break; } + if (keyboard.isEnabled() && !chatWindow->isFocused()) + { + const int tKey = keyboard.getKeyIndex(event.key.keysym.sym); + // Checks if any item shortcut is pressed. + for (int i = KeyboardConfig::KEY_SHORTCUT_0; + i <= KeyboardConfig::KEY_SHORTCUT_9; + i++) + { + if (tKey == i) { + itemShortcut->useItem( + i - KeyboardConfig::KEY_SHORTCUT_0); + break; + } + } + switch (tKey) { + case KeyboardConfig::KEY_PICKUP: + { + Uint16 x = player_node->mX / 32; + Uint16 y = player_node->mY / 32; + FloorItem *item = + floorItemManager->findByCoordinates(x, y); + + // If none below the player, try the tile in front + // of the player + if (!item) + { + // Temporary until tile-based picking is + // removed. + switch (player_node->getSpriteDirection()) + { + case DIRECTION_UP : --y; break; + case DIRECTION_DOWN : ++y; break; + case DIRECTION_LEFT : --x; break; + case DIRECTION_RIGHT: ++x; break; + default: break; + } + + item = + floorItemManager->findByCoordinates(x, y); + } + + if (item) + player_node->pickUp(item); + + used = true; + } + break; + case KeyboardConfig::KEY_SIT: + // Player sit action + player_node->toggleSit(); + used = true; + break; + case KeyboardConfig::KEY_HIDE_WINDOWS: + // Hide certain windows + if (!chatWindow->isFocused()) + { + statusWindow->setVisible(false); + inventoryWindow->setVisible(false); + skillDialog->setVisible(false); + setupWindow->setVisible(false); + equipmentWindow->setVisible(false); + helpWindow->setVisible(false); + debugWindow->setVisible(false); + } + break; + } + } + if (requestedWindow) { requestedWindow->setVisible(!requestedWindow->isVisible()); @@ -563,19 +588,14 @@ void Game::handleInput() { switch (event.key.keysym.sym) { - case SDLK_s: - // Player sit action - player_node->toggleSit(); - used = true; - break; - case SDLK_p: // Screenshot (picture, hence the p) { SDL_Surface *screenshot = graphics->getScreenshot(); if (!saveScreenshot(screenshot)) { - logger->log("Error: could not save Screenshot."); + logger->log( + "Error: could not save Screenshot."); } SDL_FreeSurface(screenshot); } @@ -606,6 +626,8 @@ void Game::handleInput() case SDLK_8: emotion = 8; break; case SDLK_9: emotion = 9; break; case SDLK_0: emotion = 10; break; + case SDLK_MINUS: emotion = 11; break; + case SDLK_EQUALS: emotion = 12; break; default: emotion = 0; break; } @@ -638,41 +660,41 @@ void Game::handleInput() } } // End while - + // If the user is configuring the keys then don't respond. + if (!keyboard.isEnabled()) + { + return; + } // Moving player around if (player_node->mAction != Being::DEAD && current_npc == 0 && !chatWindow->isFocused()) { // Get the state of the keyboard keys - Uint8* keys; - keys = SDL_GetKeyState(NULL); + keyboard.refreshActiveKeys(); Uint16 x = player_node->mX / 32, y = player_node->mY / 32; unsigned char direction = 0; // Translate pressed keys to movement and direction - if (keys[SDLK_UP] || keys[SDLK_KP8] || - keys[SDLK_KP7] || keys[SDLK_KP9] || + if ( keyboard.isKeyActive(keyboard.KEY_MOVE_UP) || joystick && joystick->isUp()) { direction |= Being::UP; } - else if (keys[SDLK_DOWN] || keys[SDLK_KP2] || - keys[SDLK_KP1] || keys[SDLK_KP3] || + else if ( keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN) || joystick && joystick->isDown()) { direction |= Being::DOWN; } - if (keys[SDLK_LEFT] || keys[SDLK_KP4] || - keys[SDLK_KP1] || keys[SDLK_KP7] || + + if ( keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT) || joystick && joystick->isLeft()) { direction |= Being::LEFT; } - else if (keys[SDLK_RIGHT] || keys[SDLK_KP6] || - keys[SDLK_KP3] || keys[SDLK_KP9] || + else if ( keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT) || joystick && joystick->isRight()) { direction |= Being::RIGHT; @@ -681,7 +703,8 @@ void Game::handleInput() player_node->setWalkingDir(direction); // Target the nearest monster if 'a' pressed - if (keys[SDLK_a]) + if ( keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ) + //if (keys[SDLK_a]) { Being *target = beingManager->findNearestLivingBeing(x, y, 20, Being::MONSTER); diff --git a/src/gui/button.cpp b/src/gui/button.cpp index 4e236c33..0379ebc0 100644 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -60,10 +60,25 @@ static ButtonData const data[BUTTON_COUNT] = { ImageRect Button::button[BUTTON_COUNT]; +Button::Button(): + mIsLogged(false) +{ + init(); +} + Button::Button(const std::string& caption, const std::string &actionEventId, gcn::ActionListener *listener): gcn::Button(caption), mIsLogged(false) +{ + init(); + setActionEventId(actionEventId); + if (listener) { + addActionListener(listener); + } +} + +void Button::init() { setBorderSize(0); @@ -91,12 +106,7 @@ Button::Button(const std::string& caption, const std::string &actionEventId, btn[mode]->decRef(); } } - mInstances++; - setActionEventId(actionEventId); - if (listener) { - addActionListener(listener); - } } Button::~Button() diff --git a/src/gui/button.h b/src/gui/button.h index eb73e311..d12173b2 100644 --- a/src/gui/button.h +++ b/src/gui/button.h @@ -38,7 +38,13 @@ class ImageRect; class Button : public gcn::Button { public: /** - * Constructor, sets the caption of the button to the given string. + * Default constructor. + */ + Button(); + + /** + * Constructor, sets the caption of the button to the given string and + * adds the given action listener. */ Button(const std::string& caption, const std::string &actionEventId, gcn::ActionListener *listener); @@ -60,6 +66,8 @@ class Button : public gcn::Button { { mIsLogged = enable; } private: + void init(); + static ImageRect button[4]; /**< Button state graphics */ static int mInstances; /**< Number of button instances */ bool mIsLogged; /**< Makes the button appear pressed all the time */ diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index 6cfe5e18..bbf2102e 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -28,6 +28,7 @@ #include "button.h" #include "scrollarea.h" #include "shop.h" +#include "shoplistbox.h" #include "slider.h" #include "../npc.h" @@ -35,11 +36,15 @@ #include "../resources/itemdb.h" #include "../utils/tostring.h" - BuyDialog::BuyDialog(): Window("Buy"), mMoney(0), mAmountItems(0), mMaxItems(0) { + setResizable(true); + setMinWidth(260); + setMinHeight(230); + setDefaultSize(0, 0, 260, 230); + mShopItems = new ShopItems; mShopItemList = new ShopListBox(mShopItems, mShopItems); @@ -54,32 +59,15 @@ BuyDialog::BuyDialog(): mItemDescLabel = new gcn::Label("Description:"); mItemEffectLabel = new gcn::Label("Effect:"); - setContentSize(260, 210); - mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mScrollArea->setDimension(gcn::Rectangle(5, 5, 250, 110)); - mShopItemList->setDimension(gcn::Rectangle(5, 5, 238, 110)); - - mSlider->setDimension(gcn::Rectangle(5, 120, 200, 10)); - mSlider->setEnabled(false); - - mQuantityLabel->setPosition(215, 120); - mMoneyLabel->setPosition(5, 130); - - mIncreaseButton->setPosition(40, 186); mIncreaseButton->setSize(20, 20); - mIncreaseButton->setEnabled(false); - - mDecreaseButton->setPosition(10, 186); mDecreaseButton->setSize(20, 20); - mDecreaseButton->setEnabled(false); + mQuantityLabel->setWidth(60); - mBuyButton->setPosition(180, 186); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mIncreaseButton->setEnabled(false); + mDecreaseButton->setEnabled(false); mBuyButton->setEnabled(false); - - mQuitButton->setPosition(212, 186); - - mItemEffectLabel->setDimension(gcn::Rectangle(5, 150, 240, 14)); - mItemDescLabel->setDimension(gcn::Rectangle(5, 169, 240, 14)); + mSlider->setEnabled(false); mShopItemList->setActionEventId("item"); mSlider->setActionEventId("slider"); @@ -98,6 +86,8 @@ BuyDialog::BuyDialog(): add(mItemDescLabel); add(mItemEffectLabel); + addWindowListener(this); + loadWindowState("Buy"); setLocationRelativeTo(getParent()); } @@ -118,13 +108,12 @@ void BuyDialog::reset() { mShopItems->clear(); mShopItemList->adjustSize(); - mMoney = 0; - mSlider->setValue(0.0); - // Reset Previous Selected Items to prevent failing asserts + // Reset previous selected items to prevent failing asserts mShopItemList->setSelected(-1); + mSlider->setValue(0); - updateButtonsAndLabels(); + setMoney(0); } void BuyDialog::addItem(int id, int amount, int price) @@ -141,6 +130,7 @@ void BuyDialog::action(const gcn::ActionEvent &event) { setVisible(false); current_npc = 0; + return; } // The following actions require a valid selection @@ -152,21 +142,19 @@ void BuyDialog::action(const gcn::ActionEvent &event) if (event.getId() == "slider") { - mAmountItems = (int)(mSlider->getValue() * mMaxItems); + mAmountItems = (int) mSlider->getValue(); updateButtonsAndLabels(); } else if (event.getId() == "+" && mAmountItems < mMaxItems) { mAmountItems++; - - mSlider->setValue((double) mAmountItems / (double) mMaxItems); + mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } - else if (event.getId() == "-" && mAmountItems > 0) + else if (event.getId() == "-" && mAmountItems > 1) { mAmountItems--; - - mSlider->setValue((double) mAmountItems / (double) mMaxItems); + mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } // TODO: Actually we'd have a bug elsewhere if this check for the number @@ -178,25 +166,69 @@ void BuyDialog::action(const gcn::ActionEvent &event) Net::GameServer::Player::tradeWithNPC (mShopItems->at(selectedItem).id, mAmountItems); - // Update money and adjust the max number of items that can be bought - mMoney -= mAmountItems * mShopItems->at(selectedItem).price; - mMaxItems -= mAmountItems; - // Reset selection - mAmountItems = 0; - mSlider->setValue(0.0); + mAmountItems = 1; + mSlider->setValue(1); + mSlider->gcn::Slider::setScale(1, mMaxItems); - updateButtonsAndLabels(); + // Update money and adjust the max number of items that can be bought + mMaxItems -= mAmountItems; + setMoney(mMoney - mAmountItems * mShopItems->at(selectedItem).price); } } void BuyDialog::selectionChanged(const SelectionEvent &event) { + // Reset amount of items and update labels - mAmountItems = 0; - mSlider->setValue(0.0); + mAmountItems = 1; + mSlider->setValue(1); updateButtonsAndLabels(); + mSlider->gcn::Slider::setScale(1, mMaxItems); +} + +void BuyDialog::windowResized(const WindowEvent &event) +{ + gcn::Rectangle area = getChildrenArea(); + int width = area.width; + int height = area.height; + + mDecreaseButton->setPosition(8, height - 8 - mDecreaseButton->getHeight()); + mIncreaseButton->setPosition( + mDecreaseButton->getX() + mDecreaseButton->getWidth() + 5, + mDecreaseButton->getY()); + + mQuitButton->setPosition( + width - 8 - mQuitButton->getWidth(), + height - 8 - mQuitButton->getHeight()); + mBuyButton->setPosition( + mQuitButton->getX() - 5 - mBuyButton->getWidth(), + mQuitButton->getY()); + + mItemDescLabel->setDimension(gcn::Rectangle(8, + mBuyButton->getY() - 5 - mItemDescLabel->getHeight(), + width - 16, + mItemDescLabel->getHeight())); + mItemEffectLabel->setDimension(gcn::Rectangle(8, + mItemDescLabel->getY() - 5 - mItemEffectLabel->getHeight(), + width - 16, + mItemEffectLabel->getHeight())); + mMoneyLabel->setDimension(gcn::Rectangle(8, + mItemEffectLabel->getY() - 5 - mMoneyLabel->getHeight(), + width - 16, + mMoneyLabel->getHeight())); + + mQuantityLabel->setPosition( + width - mQuantityLabel->getWidth() - 8, + mMoneyLabel->getY() - 5 - mQuantityLabel->getHeight()); + mSlider->setDimension(gcn::Rectangle(8, + mQuantityLabel->getY(), + mQuantityLabel->getX() - 8 - 8, + 10)); + + mScrollArea->setDimension(gcn::Rectangle(8, 8, width - 16, + mSlider->getY() - 5 - 8)); } void @@ -232,14 +264,13 @@ BuyDialog::updateButtonsAndLabels() // Enable or disable buttons and slider mIncreaseButton->setEnabled(mAmountItems < mMaxItems); - mDecreaseButton->setEnabled(mAmountItems > 0); + mDecreaseButton->setEnabled(mAmountItems > 1); mBuyButton->setEnabled(mAmountItems > 0); - mSlider->setEnabled(mMaxItems > 0); + mSlider->setEnabled(mMaxItems > 1); // Update quantity and money labels - mQuantityLabel->setCaption(toString(mAmountItems)); - mQuantityLabel->adjustSize(); + mQuantityLabel->setCaption( + toString(mAmountItems) + " / " + toString(mMaxItems)); mMoneyLabel->setCaption("Price: " + toString(price) + " GP / " + toString(mMoney - price) + " GP" ); - mMoneyLabel->adjustSize(); } diff --git a/src/gui/buy.h b/src/gui/buy.h index 875deef9..63d25583 100644 --- a/src/gui/buy.h +++ b/src/gui/buy.h @@ -28,11 +28,11 @@ #include "window.h" #include "selectionlistener.h" -#include "shoplistbox.h" #include "../guichanfwd.h" class ShopItems; +class ShopListBox; class ListBox; /** @@ -40,7 +40,8 @@ class ListBox; * * \ingroup Interface */ -class BuyDialog : public Window, public gcn::ActionListener, SelectionListener +class BuyDialog : public Window, public gcn::ActionListener, SelectionListener, + WindowListener { public: /** @@ -98,6 +99,11 @@ class BuyDialog : public Window, public gcn::ActionListener, SelectionListener void updateButtonsAndLabels(); + /** + * Called whenever the window is resized. + */ + void windowResized(const WindowEvent &event); + private: gcn::Button *mBuyButton; gcn::Button *mQuitButton; diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index d752cdb3..e8381bef 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -48,6 +48,7 @@ #include "../utils/gettext.h" #include "../utils/strprintf.h" #include "../utils/tostring.h" +#include "../utils/trim.h" // Defined in main.cpp, used here for setting the char create dialog extern CharServerHandler charServerHandler; @@ -255,11 +256,6 @@ bool CharSelectDialog::selectByName(const std::string &name) return false; } -std::string CharSelectDialog::getName() -{ - return mNameLabel->getCaption(); -} - CharCreateDialog::CharCreateDialog(Window *parent, int slot): Window(_("Create Character"), true, parent), mSlot(slot) { @@ -410,10 +406,12 @@ CharCreateDialog::action(const gcn::ActionEvent &event) } } -const std::string& +std::string CharCreateDialog::getName() { - return mNameField->getText(); + std::string name = mNameField->getText(); + trim(name); + return name; } void CharCreateDialog::UpdateSliders() diff --git a/src/gui/char_select.h b/src/gui/char_select.h index 9d9184ea..5d0b42fa 100644 --- a/src/gui/char_select.h +++ b/src/gui/char_select.h @@ -60,11 +60,6 @@ class CharSelectDialog : public Window, public gcn::ActionListener bool selectByName(const std::string &name); - /** - * Returns name of selected player - */ - std::string getName(); - private: LockedArray *mCharInfo; @@ -114,22 +109,28 @@ class CharCreateDialog : public Window, public gcn::ActionListener */ ~CharCreateDialog(); - void - action(const gcn::ActionEvent &event); - - const std::string& - getName(); + void action(const gcn::ActionEvent &event); /** * Unlocks the dialog, enabling the create character button again. */ - void - unlock(); + void unlock(); private: int getDistributedPoints(); + void UpdateSliders(); + /** + * Returns the name of the character to create. + */ + std::string getName(); + + /** + * Communicate character creation to the server. + */ + void attemptCharCreate(); + gcn::TextField *mNameField; gcn::Label *mNameLabel; gcn::Button *mNextHairColorButton; @@ -154,12 +155,6 @@ class CharCreateDialog : public Window, public gcn::ActionListener static const int mMaxPoints = 70; int mUsedPoints; - - - /** - * Communicate character creation to the server. - */ - void attemptCharCreate(); }; #endif diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index ba7c7f02..4ed8bb97 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -44,6 +44,7 @@ #include "../net/gameserver/player.h" #include "../utils/dtor.h" +#include "../utils/trim.h" ChatWindow::ChatWindow(): Window(), @@ -125,7 +126,7 @@ void ChatWindow::chatLog(std::string line, int own, std::string channelName) { // Delete overhead from the end of the list - while ((int)mChatlog.size() > mItemsKeep) { + while ((int) mChatlog.size() > mItemsKeep) { mChatlog.pop_back(); } @@ -142,12 +143,15 @@ ChatWindow::chatLog(std::string line, int own, std::string channelName) own = BY_SERVER; } - int pos = line.find(" : "); - if (pos > 0) { + std::string::size_type pos = line.find(" : "); + if (pos != std::string::npos) { tmp.nick = line.substr(0, pos); line.erase(0, pos + 3); } + // Trim whitespace + trim(line); + std::string lineColor = "##0"; // Equiv. to BrowserBox::BLACK switch (own) { case BY_GM: diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index 11ad37c2..884cdf7e 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -42,6 +42,7 @@ DebugWindow::DebugWindow(): Window("Debug") { setResizable(true); + setCloseButton(true); setDefaultSize(0, 0, 400, 100); loadWindowState("Debug"); @@ -60,15 +61,11 @@ DebugWindow::DebugWindow(): mParticleCountLabel = new gcn::Label("[Particle count: 0]"); mParticleCountLabel->setPosition(100, 60); - Button *closeButton = new Button("Close", "close", this); - closeButton->setPosition(5, 60); - add(mFPSLabel); add(mMusicFileLabel); add(mMapFileLabel); add(mTileMouseLabel); add(mParticleCountLabel); - add(closeButton); } void @@ -106,12 +103,3 @@ DebugWindow::logic() +"]"); mParticleCountLabel->adjustSize(); } - -void -DebugWindow::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "close") - { - setVisible(false); - } -} diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h index d082b2ca..9b6f2017 100644 --- a/src/gui/debugwindow.h +++ b/src/gui/debugwindow.h @@ -33,11 +33,11 @@ #include "../guichanfwd.h" /** - * The chat window. + * The debug window. * * \ingroup Interface */ -class DebugWindow : public Window, public gcn::ActionListener +class DebugWindow : public Window { public: /** @@ -50,11 +50,6 @@ class DebugWindow : public Window, public gcn::ActionListener */ void logic(); - /** - * Performs action. - */ - void action(const gcn::ActionEvent &event); - private: gcn::Label *mMusicFileLabel, *mMapFileLabel; gcn::Label *mTileMouseLabel, *mFPSLabel; diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 5e835985..c86a27fc 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -59,6 +59,7 @@ EquipmentWindow::EquipmentWindow(Equipment *equipment): mBackground(NULL), mSelected(-1) { + setCloseButton(true); setDefaultSize(5, 195, 216, 260); loadWindowState("Equipment"); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index dc51054c..97dd4d44 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -42,7 +42,7 @@ #include "../graphics.h" #include "../log.h" -#include "../resources/image.h" +#include "../resources/imageset.h" #include "../resources/resourcemanager.h" #include "../resources/imageloader.h" @@ -77,8 +77,9 @@ class GuiConfigListener : public ConfigListener }; Gui::Gui(Graphics *graphics): - mMouseCursor(NULL), - mCustomCursor(false) + mCustomCursor(false), + mMouseCursors(NULL), + mCursorType(CURSOR_POINTER) { logger->log("Initializing GUI..."); // Set graphics @@ -106,7 +107,7 @@ Gui::Gui(Graphics *graphics): // Set global font try { - mGuiFont = new TrueTypeFont("data/fonts/dejavusans.ttf", 12); + mGuiFont = new TrueTypeFont("data/fonts/dejavusans.ttf", 11); } catch (gcn::Exception e) { @@ -139,7 +140,7 @@ Gui::Gui(Graphics *graphics): hitBlueFont = new gcn::ImageFont("graphics/gui/hits_blue.png", "0123456789"); hitYellowFont = new gcn::ImageFont("graphics/gui/hits_yellow.png", - "mis"); + "0123456789misxp "); } catch (gcn::Exception e) { @@ -169,8 +170,8 @@ Gui::~Gui() delete hitBlueFont; delete hitYellowFont; - if (mMouseCursor) { - mMouseCursor->decRef(); + if (mMouseCursors) { + mMouseCursors->decRef(); } delete mGuiFont; @@ -181,12 +182,6 @@ Gui::~Gui() delete guiInput; } -void -Gui::logic() -{ - gcn::Gui::logic(); -} - void Gui::draw() { @@ -196,11 +191,13 @@ Gui::draw() int mouseX, mouseY; Uint8 button = SDL_GetMouseState(&mouseX, &mouseY); - if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS || button & SDL_BUTTON(1)) - && mCustomCursor) + if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS || button & SDL_BUTTON(1)) && + mCustomCursor) { - static_cast(mGraphics)-> - drawImage(mMouseCursor, mouseX - 5, mouseY - 2); + static_cast(mGraphics)->drawImage( + mMouseCursors->get(mCursorType), + mouseX - 15, + mouseY - 17); } mGraphics->popClipArea(); @@ -220,9 +217,11 @@ Gui::setUseCustomCursor(bool customCursor) // Load the mouse cursor ResourceManager *resman = ResourceManager::getInstance(); - mMouseCursor = resman->getImage("graphics/gui/mouse.png"); - if (!mMouseCursor) { - logger->error("Unable to load mouse cursor."); + mMouseCursors = + resman->getImageSet("graphics/gui/mouse.png", 40, 40); + + if (!mMouseCursors) { + logger->error("Unable to load mouse cursors."); } } else @@ -231,9 +230,9 @@ Gui::setUseCustomCursor(bool customCursor) SDL_ShowCursor(SDL_ENABLE); // Unload the mouse cursor - if (mMouseCursor) { - mMouseCursor->decRef(); - mMouseCursor = NULL; + if (mMouseCursors) { + mMouseCursors->decRef(); + mMouseCursors = NULL; } } } diff --git a/src/gui/gui.h b/src/gui/gui.h index 5f2cc810..1e4b9348 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -30,7 +30,7 @@ class GuiConfigListener; class Graphics; -class Image; +class ImageSet; class Viewport; /** @@ -59,36 +59,49 @@ class Gui : public gcn::Gui */ ~Gui(); - /** - * Works around Guichan bug - */ - void - logic(); - /** * Draws the whole Gui by calling draw functions down in the * Gui hierarchy. It also draws the mouse pointer. */ - void - draw(); + void draw(); /** - * Return game font + * Return game font. */ - gcn::Font* - getFont() { return mGuiFont; } + gcn::Font* getFont() const + { return mGuiFont; } /** * Sets whether a custom cursor should be rendered. */ - void - setUseCustomCursor(bool customCursor); + void setUseCustomCursor(bool customCursor); + + /** + * Sets which cursor should be used. + */ + void setCursorType(int index) + { mCursorType = index; } + + /** + * Cursors are in graphic order from left to right. + * CURSOR_POINTER should be left untouched. + * CURSOR_TOTAL should always be last. + */ + enum { + CURSOR_POINTER = 0, + CURSOR_RESIZE_ACROSS, + CURSOR_RESIZE_DOWN, + CURSOR_RESIZE_DOWN_LEFT, + CURSOR_RESIZE_DOWN_RIGHT, + CURSOR_TOTAL + }; private: GuiConfigListener *mConfigListener; gcn::Font *mGuiFont; /**< The global GUI font */ - Image *mMouseCursor; /**< Mouse cursor image */ bool mCustomCursor; /**< Show custom cursor */ + ImageSet *mMouseCursors; /**< Mouse cursor images */ + int mCursorType; }; extern Gui *gui; /**< The GUI system */ diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 085ab188..1e62b130 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -51,6 +51,7 @@ InventoryWindow::InventoryWindow(): mSplit(false) { setResizable(true); + setCloseButton(true); setMinWidth(240); setMinHeight(172); // If you adjust these defaults, don't forget to adjust the trade window's. @@ -69,7 +70,6 @@ InventoryWindow::InventoryWindow(): mItems->addSelectionListener(this); mInvenScroll = new ScrollArea(mItems); - mInvenScroll->setPosition(8, 8); mItemNameLabel = new gcn::Label(strprintf(_("Name: %s"), "")); mItemDescriptionLabel = new gcn::Label( @@ -100,8 +100,8 @@ InventoryWindow::InventoryWindow(): mSplitButton->setWidth(48); } + addWindowListener(this); loadWindowState("Inventory"); - updateContentSize(); } InventoryWindow::~InventoryWindow() @@ -130,7 +130,6 @@ void InventoryWindow::logic() mWeightLabel->setCaption( strprintf(_("Total Weight: %d - Maximum Weight: %d"), player_node->getTotalWeight(), player_node->getMaxWeight())); - mWeightLabel->adjustSize(); } void InventoryWindow::action(const gcn::ActionEvent &event) @@ -215,7 +214,7 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) } } -void InventoryWindow::updateContentSize() +void InventoryWindow::windowResized(const WindowEvent &event) { const gcn::Rectangle area = getChildrenArea(); @@ -260,8 +259,7 @@ Item* InventoryWindow::getItem() return mItems->getItem(); } -void -InventoryWindow::keyPressed(gcn::KeyEvent &event) +void InventoryWindow::keyPressed(gcn::KeyEvent &event) { switch (event.getKey().getValue()) { @@ -271,8 +269,7 @@ InventoryWindow::keyPressed(gcn::KeyEvent &event) } } -void -InventoryWindow::keyReleased(gcn::KeyEvent &event) +void InventoryWindow::keyReleased(gcn::KeyEvent &event) { switch (event.getKey().getValue()) { diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index 37ef0406..a9fdadf2 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -29,8 +29,9 @@ #include -#include "window.h" #include "selectionlistener.h" +#include "window.h" +#include "windowlistener.h" #include "../guichanfwd.h" @@ -45,7 +46,8 @@ class ItemContainer; class InventoryWindow : public Window, public gcn::ActionListener, public gcn::KeyListener, - public SelectionListener + public SelectionListener, + public WindowListener { public: /** @@ -92,7 +94,10 @@ class InventoryWindow : public Window, */ void selectionChanged(const SelectionEvent &event); - void updateContentSize(); /**< Updates widgets size/position. */ + /** + * Called whenever the window is resized. + */ + void windowResized(const WindowEvent &event); private: void updateButtons(); /**< Updates button states. */ diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index b032bd49..bddf7cee 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -30,6 +30,7 @@ #include "../graphics.h" #include "../inventory.h" #include "../item.h" +#include "../itemshortcut.h" #include "../localplayer.h" #include "../resources/image.h" @@ -38,6 +39,9 @@ #include "../utils/tostring.h" +// TODO: Add support for adding items to the item shortcut window (global +// itemShortcut). + static const int BOX_WIDTH = 36; static const int BOX_HEIGHT = 44; diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp new file mode 100644 index 00000000..1943ef93 --- /dev/null +++ b/src/gui/itemshortcutcontainer.cpp @@ -0,0 +1,224 @@ +/* + * The Mana World + * Copyright 2007 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 + * + */ + +#include "itemshortcutcontainer.h" + +#include "../graphics.h" +#include "../item.h" +#include "../itemshortcut.h" +#include "../keyboardconfig.h" + +#include "../resources/image.h" +#include "../resources/resourcemanager.h" + +#include "../utils/tostring.h" + +ItemShortcutContainer::ItemShortcutContainer(): + mGridWidth(1), + mGridHeight(1), + mItemClicked(false), + mItemMoved(NULL) +{ + addMouseListener(this); + + ResourceManager *resman = ResourceManager::getInstance(); + + mBackgroundImg = resman->getImage("graphics/gui/item_shortcut_bgr.png"); + mMaxItems = itemShortcut->getItemCount(); + + mBoxHeight = 42; + mBoxWidth = 36; +} + +ItemShortcutContainer::~ItemShortcutContainer() +{ + mBackgroundImg->decRef(); +} + +void +ItemShortcutContainer::logic() +{ + gcn::Widget::logic(); + + int i = itemShortcut->getItemCount(); + + if (i != mMaxItems) + { + mMaxItems = i; + setWidth(getWidth()); + } +} + +void +ItemShortcutContainer::draw(gcn::Graphics *graphics) +{ + Graphics *g = static_cast(graphics); + + for (int i = 0; i < mMaxItems; i++) + { + const int itemX = (i % mGridWidth) * mBoxWidth; + const int itemY = (i / mGridWidth) * mBoxHeight; + + g->drawImage(mBackgroundImg, itemX, itemY); + + // Draw item keyboard shortcut. + const char *key = SDL_GetKeyName( + (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_0+i)); + g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT); + + Item *item = itemShortcut->getItem(i); + if (item) { + // Draw item icon. + Image* image = item->getInfo().getImage(); + if (image) { + g->drawImage(image, itemX, itemY); + g->drawText( + toString(item->getQuantity()), + itemX + mBoxWidth / 2, + itemY + mBoxHeight - 14, + gcn::Graphics::CENTER); + } + } + } + if (mItemMoved) + { + // Draw the item image being dragged by the cursor. + Image* image = mItemMoved->getInfo().getImage(); + if (image) + { + const int tPosX = mCursorPosX - (image->getWidth() / 2); + const int tPosY = mCursorPosY - (image->getHeight() / 2); + + g->drawImage(image, tPosX, tPosY); + g->drawText( + toString(mItemMoved->getQuantity()), + tPosX + mBoxWidth / 2, + tPosY + mBoxHeight - 14, + gcn::Graphics::CENTER); + } + } +} + +void +ItemShortcutContainer::setWidth(int width) +{ + gcn::Widget::setWidth(width); + + mGridWidth = getWidth() / mBoxWidth; + if (mGridWidth < 1) { + mGridWidth = 1; + } + + setHeight((mMaxItems / mGridWidth + + (mMaxItems % mGridWidth > 0 ? 1 : 0)) * mBoxHeight); + + mGridHeight = getHeight() / mBoxHeight; + if (mGridHeight < 1) { + mGridHeight = 1; + } +} + +void +ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event) +{ + if (event.getButton() == gcn::MouseEvent::LEFT) { + if (!mItemMoved && mItemClicked) { + const int index = getIndexFromGrid(event.getX(), event.getY()); + if (index == -1) { + return; + } + Item *item = itemShortcut->getItem(index); + if (item) + { + mItemMoved = item; + itemShortcut->removeItem(index); + } + } + if (mItemMoved) { + mCursorPosX = event.getX(); + mCursorPosY = event.getY(); + } + } +} + +void +ItemShortcutContainer::mousePressed(gcn::MouseEvent &event) +{ + const int index = getIndexFromGrid(event.getX(), event.getY()); + if (index == -1) { + return; + } + + // Stores the selected item if theirs one. + if (itemShortcut->isItemSelected()) { + itemShortcut->setItem(index); + itemShortcut->setItemSelected(NULL); + } + else if (itemShortcut->getItem(index)) { + mItemClicked = true; + } +} + +void +ItemShortcutContainer::mouseReleased(gcn::MouseEvent &event) +{ + if (event.getButton() == gcn::MouseEvent::LEFT) + { + if (itemShortcut->isItemSelected()) + { + itemShortcut->setItemSelected(NULL); + } + const int index = getIndexFromGrid(event.getX(), event.getY()); + if (index == -1) { + mItemMoved = NULL; + return; + } + if (mItemMoved) { + itemShortcut->setItems(index, mItemMoved); + mItemMoved = NULL; + } + else if (itemShortcut->getItem(index) && mItemClicked) + { + itemShortcut->useItem(index); + } + if (mItemClicked) { + mItemClicked = false; + } + } +} + +int +ItemShortcutContainer::getIndexFromGrid(int pointX, int pointY) const +{ + const gcn::Rectangle tRect = gcn::Rectangle( + 0, 0, mGridWidth * mBoxWidth, mGridHeight * mBoxHeight); + if (!tRect.isPointInRect(pointX, pointY)) { + return -1; + } + const int index = ((pointY / mBoxHeight) * mGridWidth) + + pointX / mBoxWidth; + if (index >= mMaxItems) + { + return -1; + } + return index; +} diff --git a/src/gui/itemshortcutcontainer.h b/src/gui/itemshortcutcontainer.h new file mode 100644 index 00000000..4b154cbb --- /dev/null +++ b/src/gui/itemshortcutcontainer.h @@ -0,0 +1,115 @@ +/* + * The Mana World + * Copyright 2007 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 + * + */ + +#ifndef _TMW_ITEMSHORTCUTCONTAINER_H__ +#define _TMW_ITEMSHORTCUTCONTAINER_H__ + +#include +#include + +#include + +class Image; +class Item; + +/** + * An item shortcut container. Used to quickly use items. + * + * \ingroup GUI + */ +class ItemShortcutContainer : public gcn::Widget, public gcn::MouseListener +{ + public: + /** + * Constructor. Initializes the graphic. + */ + ItemShortcutContainer(); + + /** + * Destructor. + */ + virtual ~ItemShortcutContainer(); + + /** + * Handles the logic of the ItemContainer + */ + void logic(); + + /** + * Draws the items. + */ + void draw(gcn::Graphics *graphics); + + /** + * Sets the width of the container. This is used to determine the new + * height of the container. + */ + void setWidth(int width); + + /** + * Handles mouse when dragged. + */ + void mouseDragged(gcn::MouseEvent &event); + + /** + * Handles mouse when pressed. + */ + void mousePressed(gcn::MouseEvent &event); + + /** + * Handles mouse release. + */ + void mouseReleased(gcn::MouseEvent &event); + + + int getMaxItems() + { return mMaxItems; } + + int getBoxWidth() + { return mBoxWidth; } + + int getBoxHeight() + { return mBoxHeight; } + + private: + /** + * Gets the index from the grid provided the point is in an item box. + * + * @param pointX X coordinate of the point. + * @param pointY Y coordinate of the point. + * @return index on success, -1 on failure. + */ + int getIndexFromGrid(int pointX, int pointY) const; + + Image *mBackgroundImg; + + int mMaxItems; + int mBoxWidth; + int mBoxHeight; + int mCursorPosX, mCursorPosY; + int mGridWidth, mGridHeight; + bool mItemClicked; + Item *mItemMoved; + +}; + +#endif diff --git a/src/gui/itemshortcutwindow.cpp b/src/gui/itemshortcutwindow.cpp new file mode 100644 index 00000000..dd97a7db --- /dev/null +++ b/src/gui/itemshortcutwindow.cpp @@ -0,0 +1,74 @@ +/* + * The Mana World + * Copyright 2007 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 + * + */ + +#include "itemshortcutwindow.h" + +#include "itemshortcutcontainer.h" +#include "scrollarea.h" + +static const int SCROLL_PADDING = 0; + +ItemShortcutWindow::ItemShortcutWindow() +{ + // no title presented, title bar is padding so window can be moved. + gcn::Window::setTitleBarHeight(gcn::Window::getPadding()); + setShowTitle(false); + setResizable(true); + setDefaultSize(758, 174, 42, 426); + + mItems = new ItemShortcutContainer(); + + int border = SCROLL_PADDING * 2 + getPadding() * 2; + setMinWidth(mItems->getBoxWidth() + border); + setMinHeight(mItems->getBoxHeight() + border); + setMaxWidth(mItems->getBoxWidth() * mItems->getMaxItems() + border); + setMaxHeight(mItems->getBoxHeight() * mItems->getMaxItems() + border); + + mInvenScroll = new ScrollArea(mItems); + mInvenScroll->setPosition(SCROLL_PADDING, SCROLL_PADDING); + mInvenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + add(mInvenScroll); + + addWindowListener(this); + loadWindowState("ItemShortcut"); +} + +ItemShortcutWindow::~ItemShortcutWindow() +{ + delete mItems; + delete mInvenScroll; +} + +void ItemShortcutWindow::logic() +{ + Window::logic(); +} + +void ItemShortcutWindow::windowResized(const WindowEvent &event) +{ + const gcn::Rectangle area = getChildrenArea(); + + mInvenScroll->setSize( + area.width - SCROLL_PADDING, + area.height - SCROLL_PADDING); +} diff --git a/src/gui/itemshortcutwindow.h b/src/gui/itemshortcutwindow.h new file mode 100644 index 00000000..83bc348d --- /dev/null +++ b/src/gui/itemshortcutwindow.h @@ -0,0 +1,69 @@ +/* + * The Mana World + * Copyright 2007 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 + * + */ + +#ifndef _TMW_ITEMSHORTCUTWINDOW_H +#define _TMW_ITEMSHORTCUTWINDOW_H + +#include "window.h" +#include "windowlistener.h" + +#include "../guichanfwd.h" + +class ItemShortcutContainer; + +/** + * Inventory dialog. + * + * \ingroup Interface + */ +class ItemShortcutWindow : public Window, WindowListener +{ + public: + /** + * Constructor. + */ + ItemShortcutWindow(); + + /** + * Destructor. + */ + ~ItemShortcutWindow(); + + /** + * Logic (updates buttons and weight information). + */ + void logic(); + + /** + * Called whenever the window is resized. + */ + void windowResized(const WindowEvent &event); + + private: + ItemShortcutContainer *mItems; + + gcn::ScrollArea *mInvenScroll; +}; + +extern ItemShortcutWindow *itemShortcutWindow; + +#endif diff --git a/src/gui/menuwindow.cpp b/src/gui/menuwindow.cpp index bfa2f1f2..8d4d184d 100644 --- a/src/gui/menuwindow.cpp +++ b/src/gui/menuwindow.cpp @@ -37,6 +37,7 @@ extern Window *inventoryWindow; extern Window *equipmentWindow; extern Window *skillDialog; extern Window *statusWindow; +extern Window *itemShortcutWindow; namespace { struct MenuWindowListener : public gcn::ActionListener @@ -62,6 +63,7 @@ MenuWindow::MenuWindow(): N_("Equipment"), N_("Inventory"), N_("Skills"), + N_("Shortcut"), N_("Setup"), 0 }; @@ -109,14 +111,20 @@ void MenuWindowListener::action(const gcn::ActionEvent &event) { window = skillDialog; } + else if (event.getId() == "Shortcut") + { + window = itemShortcutWindow; + } else if (event.getId() == "Setup") { window = setupWindow; } - if (window) { + if (window) + { window->setVisible(!window->isVisible()); - if (window->isVisible()) { + if (window->isVisible()) + { window->requestMoveToTop(); } } diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 48bbd3d0..aeb6637d 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -200,12 +200,6 @@ void PopupMenu::handleLink(const std::string& link) setVisible(false); - /* - * This is need cause of a bug in guichan that leave - * the focus on the popup menu even if is not visible. - */ - _getFocusHandler()->focusNone(); - mBeing = NULL; mFloorItem = NULL; mItem = NULL; diff --git a/src/gui/selectionlistener.h b/src/gui/selectionlistener.h index b39672b5..917a4871 100644 --- a/src/gui/selectionlistener.h +++ b/src/gui/selectionlistener.h @@ -25,33 +25,23 @@ #define _TMW_SELECTIONLISTENER_H__ #include +#include /** * An event that characterizes a change in the current selection. * * \ingroup GUI */ -class SelectionEvent +class SelectionEvent : public gcn::Event { public: /** * Constructor. */ SelectionEvent(gcn::Widget *source): - mSource(source) + gcn::Event(source) { } - - /** - * The widget from which the event originated. - */ - gcn::Widget* getSource() const - { - return mSource; - } - - private: - gcn::Widget *mSource; }; /** diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index b601d70c..5f1011c1 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -44,58 +44,44 @@ SellDialog::SellDialog(): Window("Sell"), mMaxItems(0), mAmountItems(0) { + setResizable(true); + setMinWidth(260); + setMinHeight(230); + setDefaultSize(0, 0, 260, 230); + mShopItems = new ShopItems(); mShopItemList = new ShopListBox(mShopItems, mShopItems); - ScrollArea *scrollArea = new ScrollArea(mShopItemList); + mScrollArea = new ScrollArea(mShopItemList); mSlider = new Slider(1.0); mQuantityLabel = new gcn::Label("0"); mMoneyLabel = new gcn::Label("Money: 0 GP / Total: 0 GP"); - mItemDescLabel = new gcn::Label("Description:"); - mItemEffectLabel = new gcn::Label("Effect:"); mIncreaseButton = new Button("+", "+", this); mDecreaseButton = new Button("-", "-", this); mSellButton = new Button("Sell", "sell", this); - Button *quitButton = new Button("Quit", "quit", this); - mSellButton->setEnabled(false); - - setContentSize(260, 210); - scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - scrollArea->setDimension(gcn::Rectangle(5, 5, 250, 110)); - mShopItemList->setDimension(gcn::Rectangle(5, 5, 238, 110)); - - mSlider->setDimension(gcn::Rectangle(5, 120, 200, 10)); - mSlider->setEnabled(false); - - mQuantityLabel->setPosition(215, 120); + mQuitButton = new Button("Quit", "quit", this); + mItemDescLabel = new gcn::Label("Description:"); + mItemEffectLabel = new gcn::Label("Effect:"); - mIncreaseButton->setPosition(40, 186); mIncreaseButton->setSize(20, 20); - mIncreaseButton->setEnabled(false); - - mDecreaseButton->setPosition(10, 186); mDecreaseButton->setSize(20, 20); - mDecreaseButton->setEnabled(false); + mQuantityLabel->setWidth(60); - mMoneyLabel->setPosition(5, 130); - mItemEffectLabel->setDimension(gcn::Rectangle(5, 150, 240, 14)); - mItemDescLabel->setDimension(gcn::Rectangle(5, 169, 240, 14)); - - mSellButton->setPosition(175, 186); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mIncreaseButton->setEnabled(false); + mDecreaseButton->setEnabled(false); mSellButton->setEnabled(false); + mSlider->setEnabled(false); - quitButton->setPosition(208, 186); - + mShopItemList->setPriceCheck(false); mShopItemList->setActionEventId("item"); mSlider->setActionEventId("slider"); - mShopItemList->setPriceCheck(false); - mShopItemList->addActionListener(this); mShopItemList->addSelectionListener(this); mSlider->addActionListener(this); - add(scrollArea); + add(mScrollArea); add(mSlider); add(mQuantityLabel); add(mMoneyLabel); @@ -104,8 +90,10 @@ SellDialog::SellDialog(): add(mIncreaseButton); add(mDecreaseButton); add(mSellButton); - add(quitButton); + add(mQuitButton); + addWindowListener(this); + loadWindowState("Sell"); setLocationRelativeTo(getParent()); } @@ -117,7 +105,7 @@ SellDialog::~SellDialog() void SellDialog::reset() { mShopItems->clear(); - mSlider->setValue(0.0); + mSlider->setValue(0); // Reset previous selected item to prevent failing asserts mShopItemList->setSelected(-1); @@ -135,16 +123,11 @@ void SellDialog::action(const gcn::ActionEvent &event) { int selectedItem = mShopItemList->getSelected(); - if (event.getId() == "item") - { - mAmountItems = 0; - mSlider->setValue(0); - updateButtonsAndLabels(); - } - else if (event.getId() == "quit") + if (event.getId() == "quit") { setVisible(false); current_npc = 0; + return; } // The following actions require a valid item selection @@ -156,21 +139,19 @@ void SellDialog::action(const gcn::ActionEvent &event) if (event.getId() == "slider") { - mAmountItems = (int) (mSlider->getValue() * mMaxItems); + mAmountItems = (int) mSlider->getValue(); updateButtonsAndLabels(); } else if (event.getId() == "+" && mAmountItems < mMaxItems) { mAmountItems++; - - mSlider->setValue((double) mAmountItems /(double) mMaxItems); + mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } - else if (event.getId() == "-" && mAmountItems > 0) + else if (event.getId() == "-" && mAmountItems > 1) { mAmountItems--; - - mSlider->setValue((double) mAmountItems / (double) mMaxItems); + mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } else if (event.getId() == "sell" && mAmountItems > 0 @@ -182,8 +163,7 @@ void SellDialog::action(const gcn::ActionEvent &event) mMaxItems -= mAmountItems; mShopItems->getShop()->at(selectedItem).quantity = mMaxItems; mPlayerMoney += (mAmountItems * mShopItems->at(selectedItem).price); - mAmountItems = 0; - mSlider->setValue(0); + mAmountItems = 1; if (!mMaxItems) { @@ -194,6 +174,7 @@ void SellDialog::action(const gcn::ActionEvent &event) } else { + mSlider->gcn::Slider::setScale(1, mMaxItems); // Update only when there are items left, the entry doesn't exist // otherwise and can't be updated updateButtonsAndLabels(); @@ -204,10 +185,54 @@ void SellDialog::action(const gcn::ActionEvent &event) void SellDialog::selectionChanged(const SelectionEvent &event) { // Reset amount of items and update labels - mAmountItems = 0; + mAmountItems = 1; mSlider->setValue(0); updateButtonsAndLabels(); + mSlider->gcn::Slider::setScale(1, mMaxItems); +} + +void SellDialog::windowResized(const WindowEvent &event) +{ + gcn::Rectangle area = getChildrenArea(); + int width = area.width; + int height = area.height; + + mDecreaseButton->setPosition(8, height - 8 - mDecreaseButton->getHeight()); + mIncreaseButton->setPosition( + mDecreaseButton->getX() + mDecreaseButton->getWidth() + 5, + mDecreaseButton->getY()); + + mQuitButton->setPosition( + width - 8 - mQuitButton->getWidth(), + height - 8 - mQuitButton->getHeight()); + mSellButton->setPosition( + mQuitButton->getX() - 5 - mSellButton->getWidth(), + mQuitButton->getY()); + + mItemDescLabel->setDimension(gcn::Rectangle(8, + mSellButton->getY() - 5 - mItemDescLabel->getHeight(), + width - 16, + mItemDescLabel->getHeight())); + mItemEffectLabel->setDimension(gcn::Rectangle(8, + mItemDescLabel->getY() - 5 - mItemEffectLabel->getHeight(), + width - 16, + mItemEffectLabel->getHeight())); + mMoneyLabel->setDimension(gcn::Rectangle(8, + mItemEffectLabel->getY() - 5 - mMoneyLabel->getHeight(), + width - 16, + mMoneyLabel->getHeight())); + + mQuantityLabel->setPosition( + width - mQuantityLabel->getWidth() - 8, + mMoneyLabel->getY() - 5 - mQuantityLabel->getHeight()); + mSlider->setDimension(gcn::Rectangle(8, + mQuantityLabel->getY(), + mQuantityLabel->getX() - 8 - 8, + 10)); + + mScrollArea->setDimension(gcn::Rectangle(8, 8, width - 16, + mSlider->getY() - 5 - 8)); } void SellDialog::setMoney(int amount) @@ -246,15 +271,13 @@ SellDialog::updateButtonsAndLabels() // Update Buttons and slider mSellButton->setEnabled(mAmountItems > 0); - mDecreaseButton->setEnabled(mAmountItems > 0); + mDecreaseButton->setEnabled(mAmountItems > 1); mIncreaseButton->setEnabled(mAmountItems < mMaxItems); - mSlider->setEnabled(selectedItem > -1); + mSlider->setEnabled(mMaxItems > 1); // Update the quantity and money labels mQuantityLabel->setCaption( toString(mAmountItems) + " / " + toString(mMaxItems)); - mQuantityLabel->adjustSize(); mMoneyLabel->setCaption("Money: " + toString(income) + " GP / Total: " + toString(mPlayerMoney + income) + " GP"); - mMoneyLabel->adjustSize(); } diff --git a/src/gui/sell.h b/src/gui/sell.h index fc42fd1c..d1e2ddd2 100644 --- a/src/gui/sell.h +++ b/src/gui/sell.h @@ -28,6 +28,7 @@ #include "window.h" #include "selectionlistener.h" +#include "windowlistener.h" #include "../guichanfwd.h" @@ -40,7 +41,8 @@ class ShopListBox; * * \ingroup Interface */ -class SellDialog : public Window, gcn::ActionListener, SelectionListener +class SellDialog : public Window, gcn::ActionListener, SelectionListener, + WindowListener { public: /** @@ -77,22 +79,28 @@ class SellDialog : public Window, gcn::ActionListener, SelectionListener */ void selectionChanged(const SelectionEvent &event); + /** + * Called whenever the window is resized. + */ + void windowResized(const WindowEvent &event); + /** * Gives Player's Money amount */ void setMoney(int amount); + private: /** * Updates the state of buttons and labels. */ - void - updateButtonsAndLabels(); + void updateButtonsAndLabels(); - private: gcn::Button *mSellButton; + gcn::Button *mQuitButton; gcn::Button *mIncreaseButton; gcn::Button *mDecreaseButton; ShopListBox *mShopItemList; + gcn::ScrollArea *mScrollArea; gcn::Label *mMoneyLabel; gcn::Label *mItemDescLabel; gcn::Label *mItemEffectLabel; diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp index 3ea19059..6a13232a 100644 --- a/src/gui/setup.cpp +++ b/src/gui/setup.cpp @@ -27,6 +27,7 @@ #include "setup_audio.h" #include "setup_joystick.h" #include "setup_video.h" +#include "setup_keyboard.h" #include "tabbedcontainer.h" #include "../utils/dtor.h" @@ -43,7 +44,8 @@ extern Window *skillDialog; Setup::Setup(): Window(_("Setup")) { - int width = 230; + setCloseButton(true); + int width = 250; int height = 245; setContentSize(width, height); @@ -59,7 +61,7 @@ Setup::Setup(): } TabbedContainer *panel = new TabbedContainer(); - panel->setDimension(gcn::Rectangle(5, 5, 220, 205)); + panel->setDimension(gcn::Rectangle(5, 5, 250, 205)); panel->setOpaque(false); SetupTab *tab; @@ -76,6 +78,10 @@ Setup::Setup(): panel->addTab(tab, _("Joystick")); mTabs.push_back(tab); + tab = new Setup_Keyboard(); + panel->addTab(tab, "Keyboard"); + mTabs.push_back(tab); + add(panel); setLocationRelativeTo(getParent()); diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp new file mode 100644 index 00000000..e88080b5 --- /dev/null +++ b/src/gui/setup_keyboard.cpp @@ -0,0 +1,187 @@ +/* + * The Mana World + * Copyright 2007 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$ + */ + +#include "setup_keyboard.h" + +#include +#include + +#include "button.h" +#include "listbox.h" +#include "ok_dialog.h" +#include "scrollarea.h" + +#include "../configuration.h" +#include "../keyboardconfig.h" + +#include "../utils/tostring.h" + +#include + +/** + * The list model for key function list. + * + * \ingroup Interface + */ +class KeyListModel : public gcn::ListModel +{ + public: + /** + * Returns the number of elements in container. + */ + int getNumberOfElements() { return keyboard.KEY_TOTAL; } + + /** + * Returns element from container. + */ + std::string getElementAt(int i) { return mKeyFunctions[i]; } + + /** + * Sets element from container. + */ + void setElementAt(int i, std::string caption) + { + mKeyFunctions[i] = caption; + } + + private: + std::string mKeyFunctions[KeyboardConfig::KEY_TOTAL]; +}; + +Setup_Keyboard::Setup_Keyboard(): + mKeyListModel(new KeyListModel()), + mKeyList(new ListBox(mKeyListModel)), + mKeySetting(false) +{ + keyboard.setSetupKeyboard(this); + setOpaque(false); + + refreshKeys(); + + mKeyList->setDimension(gcn::Rectangle(0, 0, 185, 140)); + mKeyList->addActionListener(this); + mKeyList->setSelected(-1); + + ScrollArea *scrollArea = new ScrollArea(mKeyList); + scrollArea->setDimension(gcn::Rectangle(10, 10, 200, 140)); + add(scrollArea); + + mAssignKeyButton = new Button("Assign", "assign", this); + mAssignKeyButton->setPosition(165, 155); + mAssignKeyButton->addActionListener(this); + mAssignKeyButton->setEnabled(false); + add(mAssignKeyButton); + + mMakeDefaultButton = new Button("Default", "makeDefault", this); + mMakeDefaultButton->setPosition(10, 155); + mMakeDefaultButton->addActionListener(this); + add(mMakeDefaultButton); +} + +Setup_Keyboard::~Setup_Keyboard() +{ + delete mKeyList; + delete mKeyListModel; + + delete mAssignKeyButton; + delete mMakeDefaultButton; +} + +void Setup_Keyboard::apply() +{ + keyUnresolved(); + + if (keyboard.hasConflicts()) + { + new OkDialog("Key Conflict(s) Detected.", + "Resolve them, or gameplay may result in strange behaviour."); + } + keyboard.setEnabled(true); + keyboard.store(); +} + +void Setup_Keyboard::cancel() +{ + keyUnresolved(); + + keyboard.retrieve(); + keyboard.setEnabled(true); + + refreshKeys(); +} + +void Setup_Keyboard::action(const gcn::ActionEvent &event) +{ + if (event.getSource() == mKeyList) + { + if (!mKeySetting) { + mAssignKeyButton->setEnabled(true); + } + } + else if (event.getId() == "assign") + { + mKeySetting = true; + mAssignKeyButton->setEnabled(false); + keyboard.setEnabled(false); + int i(mKeyList->getSelected()); + keyboard.setNewKeyIndex(i); + mKeyListModel->setElementAt(i, keyboard.getKeyCaption(i) + ": ?"); + } + else if (event.getId() == "makeDefault") + { + keyboard.makeDefault(); + refreshKeys(); + } +} + +void Setup_Keyboard::refreshAssignedKey(int index) +{ + std::string caption; + char *temp = SDL_GetKeyName( + (SDLKey) keyboard.getKeyValue(index)); + caption = keyboard.getKeyCaption(index) + ": " + toString(temp); + mKeyListModel->setElementAt(index, caption); +} + +void Setup_Keyboard::newKeyCallback(int index) +{ + mKeySetting = false; + refreshAssignedKey(index); + mAssignKeyButton->setEnabled(true); +} + +void Setup_Keyboard::refreshKeys() +{ + for(int i = 0; i < keyboard.KEY_TOTAL; i++) + { + refreshAssignedKey(i); + } +} + +void Setup_Keyboard::keyUnresolved() +{ + if (mKeySetting) { + newKeyCallback(keyboard.getNewKeyIndex()); + keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE); + } +} diff --git a/src/gui/setup_keyboard.h b/src/gui/setup_keyboard.h new file mode 100644 index 00000000..b72e8746 --- /dev/null +++ b/src/gui/setup_keyboard.h @@ -0,0 +1,84 @@ +/* + * The Mana World + * Copyright 2007 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$ + */ + +#ifndef _TMW_GUI_SETUP_KEYBOARD_H +#define _TMW_GUI_SETUP_KEYBOARD_H + +#include "setuptab.h" +#include "button.h" +#include "../guichanfwd.h" + +#include + + +#include + +class Setup_Keyboard : public SetupTab, public gcn::ActionListener +{ + public: + /** + * Constructor + */ + Setup_Keyboard(); + + /** + * Destructor + */ + ~Setup_Keyboard(); + + void apply(); + void cancel(); + + void action(const gcn::ActionEvent &event); + + /** + * Get an update on the assigned key. + */ + void refreshAssignedKey(int index); + + /** + * The callback function when a new key has been pressed. + */ + void newKeyCallback(int index); + + /** + * Shorthand method to update all the keys. + */ + void refreshKeys(); + + /** + * If a key function is unresolved, then this reverts it. + */ + void keyUnresolved(); + + private: + class KeyListModel *mKeyListModel; + gcn::ListBox *mKeyList; + + gcn::Button *mAssignKeyButton; + gcn::Button *mMakeDefaultButton; + + bool mKeySetting; /**< flag to check if key being set. */ +}; + +#endif diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp index 0e2ea6d3..ae787ab7 100644 --- a/src/gui/shoplistbox.cpp +++ b/src/gui/shoplistbox.cpp @@ -129,24 +129,8 @@ void ShopListBox::mousePressed(gcn::MouseEvent &event) { if (event.getButton() == gcn::MouseEvent::LEFT) { - bool enoughMoney = false; - int y = event.getY(); - - if (mShopItems && mPriceCheck) - { - if (mPlayerMoney >= mShopItems->at(y / mRowHeight).price) - enoughMoney = true; - } - else // Old Behaviour - { - enoughMoney = true; - } - - if (enoughMoney) - { - setSelected(y / mRowHeight); - generateAction(); - } + setSelected(event.getY() / mRowHeight); + generateAction(); } } diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp index 884b3744..d5cfe76a 100644 --- a/src/gui/skill.cpp +++ b/src/gui/skill.cpp @@ -63,22 +63,18 @@ const char *skill_db[] = { SkillDialog::SkillDialog(): Window("Skills") { + setCloseButton(true); setDefaultSize(windowContainer->getWidth() - 255, 25, 240, 240); mSkillListBox = new ListBox(this); ScrollArea *skillScrollArea = new ScrollArea(mSkillListBox); - mCloseButton = new Button("Close", "close", this); mSkillListBox->setActionEventId("skill"); skillScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); skillScrollArea->setDimension(gcn::Rectangle(5, 5, 230, 180)); - mCloseButton->setPosition( - skillScrollArea->getX() + skillScrollArea->getWidth() - mCloseButton->getWidth(), - 210); add(skillScrollArea); - add(mCloseButton); mSkillListBox->addActionListener(this); diff --git a/src/gui/skill.h b/src/gui/skill.h index b8794e35..f1a14d50 100644 --- a/src/gui/skill.h +++ b/src/gui/skill.h @@ -71,7 +71,6 @@ class SkillDialog : public Window, public gcn::ActionListener, private: gcn::ListBox *mSkillListBox; - gcn::Button *mCloseButton; std::vector mSkillList; }; diff --git a/src/gui/status.cpp b/src/gui/status.cpp index 7da3b905..323a6b16 100644 --- a/src/gui/status.cpp +++ b/src/gui/status.cpp @@ -39,6 +39,7 @@ StatusWindow::StatusWindow(LocalPlayer *player): mPlayer(player) { setResizable(true); + setCloseButton(true); setDefaultSize((windowContainer->getWidth() - 365) / 2, (windowContainer->getHeight() - 255) / 2, 365, 280); loadWindowState("Status"); @@ -219,7 +220,7 @@ void StatusWindow::update() mHpBar->setColor(0, 171, 34); // Green } - mHpBar->setProgress((float)hp / maxHp); + mHpBar->setProgress((float) hp / maxHp); // Stats Part // ---------- @@ -235,7 +236,8 @@ void StatusWindow::update() int statusPoints = mPlayer->getAttributeIncreasePoints(); // Update labels - for (int i = 0; i < 7; i++) { + for (int i = 0; i < 7; i++) + { mStatsLabel[i]->setCaption(attrNames[i]); mStatsDisplayLabel[i]->setCaption( strprintf("%d / %d", diff --git a/src/gui/status.h b/src/gui/status.h index 40d25a2a..62cd8805 100644 --- a/src/gui/status.h +++ b/src/gui/status.h @@ -41,7 +41,8 @@ class ProgressBar; * * \ingroup Interface */ -class StatusWindow : public Window, public gcn::ActionListener { +class StatusWindow : public Window, public gcn::ActionListener +{ public: /** * Constructor. diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index ed75e5b3..5d81bb9c 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -46,6 +46,8 @@ #include "../resources/resourcemanager.h" +extern std::string homeDir; + /** * Calculates the Alder-32 checksum for the given file. */ @@ -119,7 +121,7 @@ UpdaterWindow::UpdaterWindow(): mUpdateHost = config.getValue("updatehost", "http://updates.themanaworld.org"); - mBasePath = config.getValue("homeDir", "."); + mBasePath = homeDir; // Try to download the updates list download(); diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 2af1d960..4c6b04a2 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -55,8 +55,7 @@ Viewport::Viewport(): mCameraX(0), mCameraY(0), mShowDebugPath(false), - mPlayerFollowMouse(false), - mPopupActive(false) + mPlayerFollowMouse(false) { setOpaque(false); addMouseListener(this); @@ -372,21 +371,20 @@ Viewport::mousePressed(gcn::MouseEvent &event) if ((being = beingManager->findBeing(tilex, tiley)) && being->getType() != Being::LOCALPLAYER) { - showPopup(event.getX(), event.getY(), being); + mPopupMenu->showPopup(event.getX(), event.getY(), being); return; } else if((floorItem = floorItemManager->findByCoordinates(tilex, tiley))) { - showPopup(event.getX(), event.getY(), floorItem); + mPopupMenu->showPopup(event.getX(), event.getY(), floorItem); return; } } // If a popup is active, just remove it - if (mPopupActive) + if (mPopupMenu->isVisible()) { mPopupMenu->setVisible(false); - mPopupActive = false; return; } @@ -450,21 +448,6 @@ void Viewport::showPopup(int x, int y, Item *item) { mPopupMenu->showPopup(x, y, item); - mPopupActive = true; -} - -void -Viewport::showPopup(int x, int y, FloorItem *floorItem) -{ - mPopupMenu->showPopup(x, y, floorItem); - mPopupActive = true; -} - -void -Viewport::showPopup(int x, int y, Being *being) -{ - mPopupMenu->showPopup(x, y, being); - mPopupActive = true; } void diff --git a/src/gui/viewport.h b/src/gui/viewport.h index 22d0f249..eeb31bae 100644 --- a/src/gui/viewport.h +++ b/src/gui/viewport.h @@ -129,18 +129,6 @@ class Viewport : public WindowContainer, public gcn::MouseListener, getCameraY() { return mCameraY; } private: - /** - * Shows a popup for a floor item. - * TODO Find some way to get rid of FloorItem here - */ - void showPopup(int x, int y, FloorItem *floorItem); - - /** - * Shows a popup for a being. - * TODO Find some way to get rid of Being here - */ - void showPopup(int x, int y, Being *being); - /** * Helper function for loading target cursors */ @@ -187,7 +175,6 @@ class Viewport : public WindowContainer, public gcn::MouseListener, int mWalkTime; PopupMenu *mPopupMenu; /**< Popup menu. */ - bool mPopupActive; }; #endif diff --git a/src/gui/window.cpp b/src/gui/window.cpp index 84f4466c..17447009 100644 --- a/src/gui/window.cpp +++ b/src/gui/window.cpp @@ -26,6 +26,7 @@ #include #include +#include "gui.h" #include "gccontainer.h" #include "windowcontainer.h" @@ -42,7 +43,9 @@ ConfigListener *Window::windowConfigListener = 0; WindowContainer *Window::windowContainer = 0; int Window::instances = 0; +int Window::mouseResize = 0; ImageRect Window::border; +Image *Window::closeImage = NULL; class WindowConfigListener : public ConfigListener { @@ -60,7 +63,7 @@ Window::Window(const std::string& caption, bool modal, Window *parent): mParent(parent), mModal(modal), mResizable(false), - mMouseResize(0), + mCloseButton(false), mSticky(false), mMinWinWidth(100), mMinWinHeight(40), @@ -88,6 +91,8 @@ Window::Window(const std::string& caption, bool modal, Window *parent): border.grid[7] = dBorders->getSubImage(4, 15, 3, 4); border.grid[8] = dBorders->getSubImage(7, 15, 4, 4); dBorders->decRef(); + closeImage = resman->getImage("graphics/gui/close_button.png"); + windowConfigListener = new WindowConfigListener(); // Send GUI alpha changed for initialization windowConfigListener->optionChanged("guialpha"); @@ -110,6 +115,7 @@ Window::Window(const std::string& caption, bool modal, Window *parent): if (mModal) { + gui->setCursorType(Gui::CURSOR_POINTER); requestModalFocus(); } @@ -153,6 +159,7 @@ Window::~Window() delete border.grid[6]; delete border.grid[7]; delete border.grid[8]; + closeImage->decRef(); } delete mChrome; @@ -173,11 +180,19 @@ void Window::draw(gcn::Graphics *graphics) // Draw title if (getTitleBarHeight()) { - graphics->setColor(gcn::Color(0, 0, 0)); - graphics->setFont(getFont()); - graphics->drawText(getCaption(), 7, 5, gcn::Graphics::LEFT); + g->setColor(gcn::Color(0, 0, 0)); + g->setFont(getFont()); + g->drawText(getCaption(), 7, 5, gcn::Graphics::LEFT); } + // Draw Close Button + if (mCloseButton) + { + g->drawImage(closeImage, + getWidth() - closeImage->getWidth() - getPadding(), + getPadding() + ); + } drawChildren(graphics); } @@ -207,6 +222,8 @@ void Window::setWidth(int width) { mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x); } + + fireWindowEvent(WindowEvent(this, WindowEvent::WINDOW_RESIZED)); } void Window::setHeight(int height) @@ -217,6 +234,8 @@ void Window::setHeight(int height) { mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y); } + + fireWindowEvent(WindowEvent(this, WindowEvent::WINDOW_RESIZED)); } void Window::setDimension(const gcn::Rectangle &dimension) @@ -228,6 +247,27 @@ void Window::setDimension(const gcn::Rectangle &dimension) mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x); mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y); } + + fireWindowEvent(WindowEvent(this, WindowEvent::WINDOW_RESIZED)); + fireWindowEvent(WindowEvent(this, WindowEvent::WINDOW_MOVED)); +} + +void Window::setPosition(int x, int y) +{ + gcn::Window::setPosition(x, y); + fireWindowEvent(WindowEvent(this, WindowEvent::WINDOW_MOVED)); +} + +void Window::setX(int x) +{ + gcn::Window::setX(x); + fireWindowEvent(WindowEvent(this, WindowEvent::WINDOW_MOVED)); +} + +void Window::setY(int y) +{ + gcn::Window::setY(y); + fireWindowEvent(WindowEvent(this, WindowEvent::WINDOW_MOVED)); } void Window::setLocationRelativeTo(gcn::Widget *widget) @@ -280,6 +320,11 @@ void Window::setResizable(bool r) } } +void Window::setCloseButton(bool flag) +{ + mCloseButton = flag; +} + bool Window::isResizable() { return mResizable; @@ -327,27 +372,73 @@ void Window::mousePressed(gcn::MouseEvent &event) // Let Guichan move window to top and figure out title bar drag gcn::Window::mousePressed(event); - const int x = event.getX(); - const int y = event.getY(); - mMouseResize = 0; + if (event.getButton() == gcn::MouseEvent::LEFT) + { + const int x = event.getX(); + const int y = event.getY(); + + // Handle close button + if (mCloseButton) + { + gcn::Rectangle closeButtonRect( + getWidth() - closeImage->getWidth() - getPadding(), + getPadding(), + closeImage->getWidth(), + closeImage->getHeight()); + + if (closeButtonRect.isPointInRect(x, y)) + { + setVisible(false); + } + } + + // Handle window resizing + mouseResize = getResizeHandles(event); + } +} + +void Window::mouseReleased(gcn::MouseEvent &event) +{ + if (mResizable && mouseResize) + { + mouseResize = 0; + gui->setCursorType(Gui::CURSOR_POINTER); + } + + // This should be the responsibility of Guichan (and is from 0.8.0 on) + mIsMoving = false; +} - // Activate resizing handles as appropriate - if (event.getSource() == this && isResizable() && - event.getButton() == gcn::MouseEvent::LEFT && - !getChildrenArea().isPointInRect(x, y)) +void Window::mouseExited(gcn::MouseEvent &event) +{ + if (mResizable && !mouseResize) { - mMouseResize |= (x > getWidth() - resizeBorderWidth) ? RIGHT : - (x < resizeBorderWidth) ? LEFT : 0; - mMouseResize |= (y > getHeight() - resizeBorderWidth) ? BOTTOM : - (y < resizeBorderWidth) ? TOP : 0; + gui->setCursorType(Gui::CURSOR_POINTER); } - else if (event.getSource() == mGrip && - event.getButton() == gcn::MouseEvent::LEFT) +} + +void Window::mouseMoved(gcn::MouseEvent &event) +{ + int resizeHandles = getResizeHandles(event); + + // Changes the custom mouse cursor based on it's current position. + switch (resizeHandles) { - mDragOffsetX = x; - mDragOffsetY = y; - mMouseResize |= BOTTOM | RIGHT; - mIsMoving = false; + case BOTTOM | RIGHT: + gui->setCursorType(Gui::CURSOR_RESIZE_DOWN_RIGHT); + break; + case BOTTOM | LEFT: + gui->setCursorType(Gui::CURSOR_RESIZE_DOWN_LEFT); + break; + case BOTTOM: + gui->setCursorType(Gui::CURSOR_RESIZE_DOWN); + break; + case RIGHT: + case LEFT: + gui->setCursorType(Gui::CURSOR_RESIZE_ACROSS); + break; + default: + gui->setCursorType(Gui::CURSOR_POINTER); } } @@ -366,31 +457,31 @@ void Window::mouseDragged(gcn::MouseEvent &event) setPosition(newX, newY); } - if (mMouseResize && !mIsMoving) + if (mouseResize && !mIsMoving) { const int dx = event.getX() - mDragOffsetX; const int dy = event.getY() - mDragOffsetY; gcn::Rectangle newDim = getDimension(); - if (mMouseResize & (TOP | BOTTOM)) + if (mouseResize & (TOP | BOTTOM)) { - int newHeight = newDim.height + ((mMouseResize & TOP) ? -dy : dy); + int newHeight = newDim.height + ((mouseResize & TOP) ? -dy : dy); newDim.height = std::min(mMaxWinHeight, std::max(mMinWinHeight, newHeight)); - if (mMouseResize & TOP) + if (mouseResize & TOP) { newDim.y -= newDim.height - getHeight(); } } - if (mMouseResize & (LEFT | RIGHT)) + if (mouseResize & (LEFT | RIGHT)) { - int newWidth = newDim.width + ((mMouseResize & LEFT) ? -dx : dx); + int newWidth = newDim.width + ((mouseResize & LEFT) ? -dx : dx); newDim.width = std::min(mMaxWinWidth, std::max(mMinWinWidth, newWidth)); - if (mMouseResize & LEFT) + if (mouseResize & LEFT) { newDim.x -= newDim.width - getWidth(); } @@ -417,11 +508,11 @@ void Window::mouseDragged(gcn::MouseEvent &event) } // Update mouse offset when dragging bottom or right border - if (mMouseResize & BOTTOM) + if (mouseResize & BOTTOM) { mDragOffsetY += newDim.height - getHeight(); } - if (mMouseResize & RIGHT) + if (mouseResize & RIGHT) { mDragOffsetX += newDim.width - getWidth(); } @@ -469,3 +560,50 @@ void Window::resetToDefaultSize() setContentSize(mDefaultWidth, mDefaultHeight); updateContentSize(); } + +int Window::getResizeHandles(gcn::MouseEvent &event) +{ + int resizeHandles = 0; + const int y = event.getY(); + + if (mResizable && y > (int) mTitleBarHeight) + { + const int x = event.getX(); + + if (!getChildrenArea().isPointInRect(x, y) && + event.getSource() == this) + { + resizeHandles |= (x > getWidth() - resizeBorderWidth) ? RIGHT : + (x < resizeBorderWidth) ? LEFT : 0; + resizeHandles |= (y > getHeight() - resizeBorderWidth) ? BOTTOM : + (y < resizeBorderWidth) ? TOP : 0; + } + + if (event.getSource() == mGrip) + { + mDragOffsetX = x; + mDragOffsetY = y; + resizeHandles |= BOTTOM | RIGHT; + } + } + + return resizeHandles; +} + +void Window::fireWindowEvent(const WindowEvent &event) +{ + WindowListeners::iterator i_end = mListeners.end(); + WindowListeners::iterator i = mListeners.begin(); + + switch (event.getType()) + { + case WindowEvent::WINDOW_MOVED: + for (; i != i_end; ++i) + { (*i)->windowMoved(event); } + break; + case WindowEvent::WINDOW_RESIZED: + for (; i != i_end; ++i) + { (*i)->windowResized(event); } + break; + } +} diff --git a/src/gui/window.h b/src/gui/window.h index 1ba23fb2..ab266422 100644 --- a/src/gui/window.h +++ b/src/gui/window.h @@ -28,11 +28,14 @@ #include "../guichanfwd.h" +#include "windowlistener.h" + class ConfigListener; class GCContainer; class ImageRect; class ResizeGrip; class WindowContainer; +class Image; /** * A window. This window can be dragged around and has a title bar. Windows are @@ -119,16 +122,36 @@ class Window : public gcn::Window */ void setDimension(const gcn::Rectangle &dimension); + /** + * Sets the position of this window. + */ + void setPosition(int x, int y); + + /** + * Sets the window x coordinate. + */ + void setX(int x); + + /** + * Sets the window y coordinate. + */ + void setY(int y); + /** * Sets the location relative to the given widget. */ void setLocationRelativeTo(gcn::Widget *widget); /** - * Sets whether of not the window can be resized. + * Sets whether or not the window can be resized. */ void setResizable(bool resize); + /** + * Sets whether or not the window has a close button. + */ + void setCloseButton(bool flag); + /** * Returns whether the window can be resized. */ @@ -155,9 +178,14 @@ class Window : public gcn::Window void setMaxHeight(unsigned int height); /** - * Sets whether the window is sticky. - * A sticky window will not have its visibility set to false - * on a general setVisible(false) call. + * Sets flag to show a title or not. + */ + void setShowTitle(bool flag) + { mShowTitle = flag; } + + /** + * Sets whether the window is sticky. A sticky window will not have + * its visibility set to false on a general setVisible(false) call. */ void setSticky(bool sticky); @@ -167,10 +195,9 @@ class Window : public gcn::Window bool isSticky(); /** - * Overloads window setVisible by guichan to allow sticky window - * Handling + * Overloads window setVisible by Guichan to allow sticky window + * handling. */ - void setVisible(bool visible); /** @@ -198,6 +225,24 @@ class Window : public gcn::Window */ void mouseDragged(gcn::MouseEvent &event); + /** + * Implements custom cursor image changing context, based on mouse + * relative position. + */ + void mouseMoved(gcn::MouseEvent &event); + + /** + * When the mouse button has been let go, this ensures that the mouse + * custom cursor is restored back to it's standard image. + */ + void mouseReleased(gcn::MouseEvent &event); + + /** + * When the mouse leaves the window this ensures that the custom cursor + * is restored back to it's standard image. + */ + void mouseExited(gcn::MouseEvent &event); + /** * Read the x, y, and width and height for resizables in the config * based on the given string. @@ -216,11 +261,25 @@ class Window : public gcn::Window int defaultWidth, int defaultHeight); /** - * Reset the win pos and size to default. - * Don't forget to set defaults first. + * Reset the win pos and size to default. Don't forget to set defaults + * first. */ void resetToDefaultSize(); + /** + * Adds a listener to the list that's notified when the window is + * moved or resized. + */ + void addWindowListener(WindowListener *listener) + { mListeners.push_back(listener); } + + /** + * Removes a listener from the list that's notified when the window is + * moved or resized. + */ + void removeWindowListener(WindowListener *listener) + { mListeners.remove(listener); } + enum ResizeHandles { TOP = 0x01, @@ -233,13 +292,23 @@ class Window : public gcn::Window static WindowContainer *windowContainer; private: + /** + * Determines if the mouse is in a resize area and returns appropriate + * resize handles. Also initializes drag offset in case the resize + * grip is used. + * + * @see ResizeHandles + */ + int getResizeHandles(gcn::MouseEvent &event); + GCContainer *mChrome; /**< Contained container */ ResizeGrip *mGrip; /**< Resize grip */ Window *mParent; /**< The parent window */ std::string mConfigName; /**< Name used for saving window-related data */ + bool mShowTitle; /**< Window has a title bar */ bool mModal; /**< Window is modal */ bool mResizable; /**< Window can be resized */ - int mMouseResize; /**< Window is being resized */ + bool mCloseButton; /**< Window has a close button */ bool mSticky; /**< Window resists minimization */ int mMinWinWidth; /**< Minimum window width */ int mMinWinHeight; /**< Minimum window height */ @@ -255,8 +324,10 @@ class Window : public gcn::Window */ static ConfigListener *windowConfigListener; + static int mouseResize; /**< Active resize handles */ static int instances; /**< Number of Window instances */ static ImageRect border; /**< The window border and background */ + static Image *closeImage; /**< Close Button Image */ /** * The width of the resize border. Is independent of the actual window @@ -264,6 +335,14 @@ class Window : public gcn::Window * where two borders are moved at the same time. */ static const int resizeBorderWidth = 10; + + private: + /** + * Sends out a window event to the list of selection listeners. + */ + void fireWindowEvent(const WindowEvent &event); + + WindowListeners mListeners; }; #endif diff --git a/src/gui/windowlistener.h b/src/gui/windowlistener.h new file mode 100644 index 00000000..08aab71d --- /dev/null +++ b/src/gui/windowlistener.h @@ -0,0 +1,86 @@ +/* + * 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$ + */ + +#ifndef _TMW_WINDOW_LISTENER_H_ +#define _TMW_WINDOW_LISTENER_H_ + +#include +#include + +/** + * An event that characterizes a window move or resize. + * + * \ingroup GUI + */ +class WindowEvent : public gcn::Event +{ + public: + /** + * Constructor. + */ + WindowEvent(gcn::Window *source, int type): + gcn::Event(source) + { + mType = type; + } + + /** + * Returns the event type. + */ + int getType() const + { return mType; } + + enum WindowEventType + { + WINDOW_MOVED, + WINDOW_RESIZED + }; +}; + +/** + * The listener that's notified when a window is moved or resized. + * + * \ingroup GUI + */ +class WindowListener +{ + public: + /** + * Virtual destructor. + */ + virtual ~WindowListener() {} + + /** + * Called whenever the window is moved. + */ + virtual void windowMoved(const WindowEvent &event) {} + + /** + * Called whenever the window is resized. + */ + virtual void windowResized(const WindowEvent &event) {} +}; + +typedef std::list WindowListeners; + +#endif diff --git a/src/imageparticle.cpp b/src/imageparticle.cpp index 35cc21ad..17581a2a 100644 --- a/src/imageparticle.cpp +++ b/src/imageparticle.cpp @@ -31,12 +31,12 @@ ImageParticle::ImageParticle(Map *map, Image *image): Particle(map), mImage(image) { - mImage->incRef(); + if (mImage) mImage->incRef(); } ImageParticle::~ImageParticle() { - mImage->decRef(); + if (mImage) mImage->decRef(); } void ImageParticle::draw(Graphics *graphics, int offsetX, int offsetY) const @@ -44,8 +44,8 @@ void ImageParticle::draw(Graphics *graphics, int offsetX, int offsetY) const if (!mAlive) return; - int screenX = (int) mPosX + offsetX - mImage->getWidth() / 2; - int screenY = (int) mPosY - (int) mPosZ + offsetY - mImage->getHeight()/2; + int screenX = (int) mPos.x + offsetX - mImage->getWidth() / 2; + int screenY = (int) mPos.y - (int)mPos.z + offsetY - mImage->getHeight()/2; // Check if on screen if (screenX + mImage->getWidth() < 0 || diff --git a/src/itemshortcut.cpp b/src/itemshortcut.cpp new file mode 100644 index 00000000..8a514c7e --- /dev/null +++ b/src/itemshortcut.cpp @@ -0,0 +1,87 @@ +/* + * The Mana World + * Copyright 2007 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 + * + */ + +#include "itemshortcut.h" + +#include "localplayer.h" +#include "configuration.h" + +#include "utils/tostring.h" + +ItemShortcut::ItemShortcut *itemShortcut; + +ItemShortcut::ItemShortcut(): + mItemSelected(NULL) +{ + for (int i = 0; i < SHORTCUT_ITEMS; i++) + { + mItems[i] = NULL; + } +} + +ItemShortcut::~ItemShortcut() +{ + save(); +} + +void ItemShortcut::load() +{ + for (int i = 0; i < SHORTCUT_ITEMS; i++) + { + int itemId = (int) config.getValue("itemShortcut" + toString(i), -1); + + if (itemId != -1) + { + ItemPtr item = player_node->searchForItem(itemId); + if (item) + { + mItems[i] = item; + } + } + } +} + +void ItemShortcut::save() +{ + for (int i = 0; i < SHORTCUT_ITEMS; i++) + { + if (mItems[i]) + { + config.setValue("shortcut" + toString(i), mItems[i]->getId()); + } + else + { + config.setValue("shortcut" + toString(i), -1); + } + } +} + +void ItemShortcut::useItem(int index) +{ + if (mItems[index]) + { + if (mItems[index]->getQuantity()) { + // TODO: Fix this (index vs. pointer mismatch) + //player_node->useItem(mItems[index]); + } + } +} diff --git a/src/itemshortcut.h b/src/itemshortcut.h new file mode 100644 index 00000000..d211c7f3 --- /dev/null +++ b/src/itemshortcut.h @@ -0,0 +1,130 @@ +/* + * The Mana World + * Copyright 2007 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 + * + */ + +#ifndef _TMW_ITEMSHORTCUT_H__ +#define _TMW_ITEMSHORTCUT_H__ + +#include "item.h" + +#define SHORTCUT_ITEMS 10 + +/** + * The item pointer + */ +typedef Item* ItemPtr; + +class ItemShortcut +{ + public: + /** + * Constructor. + */ + ItemShortcut(); + + /** + * Destructor. + */ + ~ItemShortcut(); + + /** + * Load the configuration information. + */ + void load(); + + /** + * Returns the shortcut item specified by the index. + * + * @param index Index of the shortcut item. + */ + ItemPtr getItem(int index) const + { return mItems[index]; } + + /** + * Returns the amount of shortcut items. + */ + int getItemCount() const + { return SHORTCUT_ITEMS; } + + /** + * Returns the item that is currently selected. + */ + ItemPtr getItemSelected() const + { return mItemSelected; } + + /** + * Adds the selected item to the items specified by the index. + * + * @param index Index of the items. + */ + void setItem(int index) + { mItems[index] = mItemSelected; } + + /** + * Adds an item to the items store specified by the index. + * + * @param index Index of the items. + * @param item Item to store. + */ + void setItems(int index, Item *item) + { mItems[index] = item; } + + /** + * Set the item that is selected. + * + * @param item The item that is to be assigned. + */ + void setItemSelected(ItemPtr item) + { mItemSelected = item; } + + /** + * A flag to check if the item is selected. + */ + bool isItemSelected() + { return (mItemSelected) ? true : false; } + + /** + * Remove a item from the shortcut. + */ + void removeItem(int index) + { mItems[index] = NULL; } + + /** + * Try to use the item specified by the index. + * + * @param index Index of the item shortcut. + */ + void useItem(int index); + + private: + /** + * Save the configuration information. + */ + void save(); + + ItemPtr mItems[SHORTCUT_ITEMS]; /**< the items stored */ + ItemPtr mItemSelected; /**< the item held by cursor */ + +}; + +extern ItemShortcut *itemShortcut; + +#endif diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp new file mode 100644 index 00000000..271961c8 --- /dev/null +++ b/src/keyboardconfig.cpp @@ -0,0 +1,144 @@ +/* + * The Mana World + * Copyright 2007 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$ + */ + +#include "keyboardconfig.h" +#include "configuration.h" +#include "log.h" + +#include + +#include "gui/setup_keyboard.h" + +struct KeyData +{ + const char *configField; + int defaultValue; + const char *caption; +}; + +// keyData must be in same order as enum keyAction. +static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { + {"keyMoveUp", SDLK_UP, "Move Up"}, + {"keyMoveDown", SDLK_DOWN, "Move Down"}, + {"keyMoveLeft", SDLK_LEFT, "Move Left"}, + {"keyMoveRight", SDLK_RIGHT, "Move Right"}, + {"keyAttack", SDLK_LCTRL, "Attack"}, + {"keyTarget", SDLK_LSHIFT, "Target"}, + {"keyTargetClosest", SDLK_a, "Target Closest"}, + {"keyPickup", SDLK_z, "Pickup"}, + {"keyHideWindows", SDLK_h, "Hide Windows"}, + {"keyBeingSit", SDLK_s, "Sit"}, + {"keyShortcut0", SDLK_0, "Item Shortcut 0"}, + {"keyShortcut1", SDLK_1, "Item Shortcut 1"}, + {"keyShortcut2", SDLK_2, "Item Shortcut 2"}, + {"keyShortcut3", SDLK_3, "Item Shortcut 3"}, + {"keyShortcut4", SDLK_4, "Item Shortcut 4"}, + {"keyShortcut5", SDLK_5, "Item Shortcut 5"}, + {"keyShortcut6", SDLK_6, "Item Shortcut 6"}, + {"keyShortcut7", SDLK_7, "Item Shortcut 7"}, + {"keyShortcut8", SDLK_8, "Item Shortcut 8"}, + {"keyShortcut9", SDLK_9, "Item Shortcut 9"} +}; + +void KeyboardConfig::init() +{ + for (int i = 0; i < KEY_TOTAL; i++) + { + mKey[i].configField = keyData[i].configField; + mKey[i].defaultValue = keyData[i].defaultValue; + mKey[i].caption = keyData[i].caption; + mKey[i].value = KEY_NO_VALUE; + } + mNewKeyIndex = KEY_NO_VALUE; + mEnabled = true; + + retrieve(); +} + +void KeyboardConfig::retrieve() +{ + for (int i = 0; i < KEY_TOTAL; i++) + { + mKey[i].value = (int) config.getValue( + mKey[i].configField, mKey[i].defaultValue); + } +} + +void KeyboardConfig::store() +{ + for (int i = 0; i < KEY_TOTAL; i++) + { + config.setValue(mKey[i].configField, mKey[i].value); + } +} + +void KeyboardConfig::makeDefault() +{ + for (int i = 0; i < KEY_TOTAL; i++) + { + mKey[i].value = mKey[i].defaultValue; + } +} + +bool KeyboardConfig::hasConflicts() +{ + int i, j; + for (i = 0; i < KEY_TOTAL; i++) + { + for (j = 0; j < KEY_TOTAL; j++) + { + if (i != j && mKey[i].value == mKey[j].value) + { + return true; + } + } + } + return false; +} + +void KeyboardConfig::callbackNewKey() +{ + mSetupKey->newKeyCallback(mNewKeyIndex); +} + +int KeyboardConfig::getKeyIndex(int keyValue) const +{ + for (int i = 0; i < KEY_TOTAL; i++) + { + if(keyValue == mKey[i].value) + { + return i; + } + } + return KEY_NO_VALUE; +} + +bool KeyboardConfig::isKeyActive(int index) +{ + return mActiveKeys[ mKey[index].value]; +} + +void KeyboardConfig::refreshActiveKeys() +{ + mActiveKeys = SDL_GetKeyState(NULL); +} diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h new file mode 100644 index 00000000..46394fa5 --- /dev/null +++ b/src/keyboardconfig.h @@ -0,0 +1,185 @@ +/* + * The Mana World + * Copyright 2007 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$ + */ + +#ifndef _TMW_KEYBOARDCONFIG_H +#define _TMW_KEYBOARDCONFIG_H + +#include + +#include "gui/setup_keyboard.h" + +#include + +/** + * Each key represents a key function. Such as 'Move up', 'Attack' etc. + */ +struct KeyFunction +{ + const char* configField; /** Field index that is in the config file. */ + int defaultValue; /** The default key value used. */ + std::string caption; /** The caption value for the key function. */ + int value; /** The actual value that is used. */ +}; + +class KeyboardConfig +{ + public: + /** + * Initializes the keyboard config explicitly. + */ + void init(); + + /** + * Retrieve the key values from config file. + */ + void retrieve(); + + /** + * Store the key values to config file. + */ + void store(); + + /** + * Make the keys their default values. + */ + void makeDefault(); + + /** + * Determines if any key assignments are the same as each other. + */ + bool hasConflicts(); + + /** + * Calls a function back so the key re-assignment(s) can be seen. + */ + void callbackNewKey(); + + /** + * Obtain the value stored in memory. + */ + int getKeyValue(int index) const + { return mKey[index].value; } + + /** + * Get the index of the new key to be assigned. + */ + int getNewKeyIndex() const + { return mNewKeyIndex; } + + /** + * Get the enable flag, which will stop the user from doing actions. + */ + bool isEnabled() const + { return mEnabled; } + + /** + * Get the key caption, providing more meaning to the user. + */ + const std::string &getKeyCaption(int index) const + { return mKey[index].caption; } + + /** + * Get the key function index by providing the keys value. + */ + int getKeyIndex(int keyValue) const; + + /** + * Set the enable flag, which will stop the user from doing actions. + */ + void setEnabled(bool flag) + { mEnabled = flag; } + + /** + * Set the index of the new key to be assigned. + */ + void setNewKeyIndex(int value) + { mNewKeyIndex = value; } + + /** + * Set the value of the new key. + */ + void setNewKey(int value) + { mKey[mNewKeyIndex].value = value; } + + /** + * Set a reference to the key setup window. + */ + void setSetupKeyboard(Setup_Keyboard *setupKey) + { mSetupKey = setupKey; } + + /** + * Checks if the key is active, by providing the key function index. + */ + bool isKeyActive(int index); + + /** + * Takes a snapshot of all the active keys. + */ + void refreshActiveKeys(); + + /** + * All the key functions. + * KEY_NO_VALUE is used in initialization, and should be unchanged. + * KEY_TOTAL should always be last (used as a conditional in loops). + * The key assignment view gets arranged according to the order of + * these values. + */ + enum KeyAction { + KEY_NO_VALUE = -1, + KEY_MOVE_UP, + KEY_MOVE_DOWN, + KEY_MOVE_LEFT, + KEY_MOVE_RIGHT, + KEY_ATTACK, + KEY_TARGET, + KEY_TARGET_CLOSEST, + KEY_PICKUP, + KEY_HIDE_WINDOWS, + KEY_SIT, + KEY_SHORTCUT_0, + KEY_SHORTCUT_1, + KEY_SHORTCUT_2, + KEY_SHORTCUT_3, + KEY_SHORTCUT_4, + KEY_SHORTCUT_5, + KEY_SHORTCUT_6, + KEY_SHORTCUT_7, + KEY_SHORTCUT_8, + KEY_SHORTCUT_9, + KEY_TOTAL + }; + + private: + int mNewKeyIndex; /**< Index of new key to be assigned */ + bool mEnabled; /**< Flag to respond to key input */ + + Setup_Keyboard *mSetupKey; /**< Reference to setup window */ + + KeyFunction mKey[KEY_TOTAL]; /**< Pointer to all the key data */ + + Uint8 *mActiveKeys; /**< Stores a list of all the keys */ +}; + +extern KeyboardConfig keyboard; + +#endif diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 95e7a478..f4ad7587 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -29,11 +29,19 @@ #include "inventory.h" #include "item.h" #include "main.h" +#include "particle.h" #include "sound.h" #include "log.h" #include "net/gameserver/player.h" +#include "gui/gui.h" + +#include "net/messageout.h" +#include "net/protocol.h" + +#include "utils/tostring.h" + LocalPlayer *player_node = NULL; LocalPlayer::LocalPlayer(): @@ -46,6 +54,7 @@ LocalPlayer::LocalPlayer(): mLevel(1), mMoney(0), mTotalWeight(1), mMaxWeight(1), mHP(1), mMaxHP(1), + mXp(0), mTarget(NULL), mPickUpTarget(NULL), mTrading(false), mLastAction(-1), mWalkingDir(0), @@ -112,6 +121,17 @@ LocalPlayer::moveInvItem(Item *item, int newIndex) item->getInvIndex(), newIndex, item->getQuantity()); } +Item* LocalPlayer::searchForItem(int itemId) +{ + for (int i = 0; i < INVENTORY_SIZE; i++) + { + if (itemId == mInventory->getItem(i)->getId()) { + return mInventory->getItem(i); + } + } + return NULL; +} + void LocalPlayer::equipItem(Item *item) { Net::GameServer::Player::equip(item->getInvIndex()); @@ -302,10 +322,14 @@ void LocalPlayer::attack() setAction(ATTACK); - if (getWeapon() == 2) - sound.playSfx("sfx/bow_shoot_1.ogg"); - else + if (mEquippedWeapon) + { + std::string soundFile = mEquippedWeapon->getSound(EQUIP_EVENT_STRIKE); + if (soundFile != "") sound.playSfx(soundFile); + } + else { sound.playSfx("sfx/fist-swish.ogg"); + } Net::GameServer::Player::attack(getSpriteDirection()); } @@ -329,3 +353,16 @@ void LocalPlayer::raiseAttribute(size_t attr) mAttributeBase.at(attr)++; // TODO: Inform the server about our desire to raise the attribute } + +void LocalPlayer::setXp(int xp) +{ + if (mMap && xp > mXp) + { + const std::string text = toString(xp - mXp) + " xp"; + + // Show XP number + particleEngine->addTextRiseFadeOutEffect(text, hitYellowFont, + mPx + 16, mPy - 16); + } + mXp = xp; +} diff --git a/src/localplayer.h b/src/localplayer.h index 4f38fdad..ff7bf0b7 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -151,6 +151,14 @@ class LocalPlayer : public Player */ void moveInvItem(Item *item, int newIndex); + /** + * Searches for the specified item by it's identification. + * + * @param itemId The id of the item to be searched. + * @return Item found on success, NULL on failure. + */ + Item* searchForItem(int itemId); + /** * Equips an item. */ @@ -237,6 +245,19 @@ class LocalPlayer : public Player int getHP() const { return mHP; } + /** + * Sets the amount of XP. Shows XP gaining effect if the player is on + * a map. + */ + void setXp(int xp); + + /** + * Returns the amount of experience points. + */ + int getXp() const { return mXp; } + + Uint32 mCharId; + int getMaxHP() const { return mMaxHP; } @@ -298,6 +319,7 @@ class LocalPlayer : public Player int mMaxWeight; int mHP; int mMaxHP; + int mXp; /**< Experience points. */ Being *mTarget; FloorItem *mPickUpTarget; diff --git a/src/main.cpp b/src/main.cpp index 1f4eafde..30fb7c1c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,8 +48,10 @@ #endif #include "configuration.h" +#include "keyboardconfig.h" #include "game.h" #include "graphics.h" +#include "itemshortcut.h" #include "lockedarray.h" #include "localplayer.h" #include "log.h" @@ -84,7 +86,6 @@ #include "net/gameserver/gameserver.h" -#include "resources/equipmentdb.h" #include "resources/image.h" #include "resources/itemdb.h" #include "resources/monsterdb.h" @@ -108,6 +109,7 @@ Music *bgm; Configuration config; /**< XML file configuration reader */ Logger *logger; /**< Log object */ +KeyboardConfig keyboard; Net::Connection *accountServerConnection = 0; Net::Connection *gameServerConnection = 0; @@ -189,7 +191,6 @@ void initConfiguration(const Options &options) config.setValue("fpslimit", 0); config.setValue("updatehost", "http://updates.themanaworld.org"); config.setValue("customcursor", 1); - config.setValue("homeDir", homeDir); // Checking if the configuration file exists... otherwise create it with // default options. @@ -319,6 +320,9 @@ void initEngine() // Initialize for drawing graphics->_beginDraw(); + // Initialize the item shortcuts. + itemShortcut = new ItemShortcut(); + gui = new Gui(graphics); state = STATE_CHOOSE_SERVER; /**< Initial game state */ @@ -337,12 +341,19 @@ void initEngine() errorMessage = err; logger->log("Warning: %s", err); } + + // Initialize keyboard + keyboard.init(); } /** Clear the engine */ void exit_engine() { + // Before config.write() since it writes the shortcuts to the config + delete itemShortcut; + config.write(); + delete gui; delete graphics; @@ -353,7 +364,6 @@ void exit_engine() sound.close(); // Unload XML databases - EquipmentDB::unload(); ItemDB::unload(); MonsterDB::unload(); @@ -457,7 +467,6 @@ void loadUpdates() const std::string updatesFile = "updates/resources2.txt"; ResourceManager *resman = ResourceManager::getInstance(); std::vector lines = resman->loadTextFile(updatesFile); - std::string homeDir = config.getValue("homeDir", ""); for (unsigned int i = 0; i < lines.size(); ++i) { @@ -895,7 +904,6 @@ int main(int argc, char *argv[]) false); // Load XML databases - EquipmentDB::load(); ItemDB::load(); MonsterDB::load(); state = STATE_LOGIN; @@ -1039,7 +1047,6 @@ int main(int argc, char *argv[]) } } } - } catch (...) { diff --git a/src/monster.cpp b/src/monster.cpp index 768bf16a..2522a3e1 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -57,7 +57,7 @@ Monster::setAction(Action action) break; case DEAD: currentAction = ACTION_DEAD; - sound.playSfx(getInfo().getSound(EVENT_DIE)); + sound.playSfx(getInfo().getSound(MONSTER_EVENT_DIE)); break; case ATTACK: currentAction = ACTION_ATTACK; @@ -87,10 +87,10 @@ Monster::handleAttack() const MonsterInfo &mi = getInfo(); - // TODO: It's not possible to determine hit or miss here, so this stuff probably needs - // to be moved somewhere else. We may lose synchronization between attack animation and - // the sound, unless we adapt the protocol... - sound.playSfx(mi.getSound(EVENT_HIT)); + // TODO: It's not possible to determine hit or miss here, so this stuff + // probably needs to be moved somewhere else. We may lose synchronization + // between attack animation and the sound, unless we adapt the protocol... + sound.playSfx(mi.getSound(MONSTER_EVENT_HIT)); } Being::TargetCursorSize diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp index 87972212..b88d443e 100644 --- a/src/net/beinghandler.cpp +++ b/src/net/beinghandler.cpp @@ -114,7 +114,7 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing = beingManager->findBeing(id); - if (dstBeing == NULL) + if (!dstBeing) { // Being with id >= 110000000 and job 0 are better // known as ghosts, so don't create those. @@ -138,30 +138,32 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing->setWalkSpeed(speed); dstBeing->mJob = job; - dstBeing->setHairStyle(msg.readShort()); - dstBeing->setWeapon(msg.readShort()); + dstBeing->setHairStyle(msg->readShort()); + dstBeing->setVisibleEquipment( + Being::WEAPON_SPRITE, msg->readShort()); dstBeing->setVisibleEquipment( - Being::BOTTOMCLOTHES_SPRITE, msg.readShort()); + Being::BOTTOMCLOTHES_SPRITE, msg->readShort()); if (msg.getId() == SMSG_BEING_MOVE) { msg.readLong(); // server tick } - msg.readShort(); // shield - dstBeing->setVisibleEquipment(Being::HAIT_SPRITE, msg.readShort()); - dstBeing->setVisibleEquipment( - Being::TOPCLOTHES_SPRITE, msg.readShort()); - dstBeing->setHairColor(msg.readShort()); - msg.readShort(); // unknown - msg.readShort(); // head dir - msg.readShort(); // guild - msg.readShort(); // unknown - msg.readShort(); // unknown - msg.readShort(); // manner - msg.readShort(); // karma - msg.readByte(); // unknown - dstBeing->setSex(1 - msg.readByte()); // sex + msg->readShort(); // shield + headTop = msg->readShort(); + headMid = msg->readShort(); + dstBeing->setVisibleEquipment(Being::HAT_SPRITE, headTop); + dstBeing->setVisibleEquipment(Being::TOPCLOTHES_SPRITE, headMid); + dstBeing->setHairColor(msg->readShort()); + msg->readShort(); // unknown + msg->readShort(); // head dir + msg->readShort(); // guild + msg->readShort(); // unknown + msg->readShort(); // unknown + msg->readShort(); // manner + msg->readShort(); // karma + msg->readByte(); // unknown + dstBeing->setSex(1 - msg->readByte()); // sex if (msg.getId() == SMSG_BEING_MOVE) { @@ -256,10 +258,12 @@ void BeingHandler::handleMessage(MessageIn &msg) } Particle *levelupFX; if (msg->readLong() == 0) { // type - levelupFX = particleEngine->addEffect("graphics/particles/levelup.particle.xml", 0, 0); + levelupFX = particleEngine->addEffect( + "graphics/particles/levelup.particle.xml", 0, 0); } else { - levelupFX = particleEngine->addEffect("graphics/particles/skillup.particle.xml", 0, 0); + levelupFX = particleEngine->addEffect( + "graphics/particles/skillup.particle.xml", 0, 0); } beingManager->findBeing(id)->controlParticle(levelupFX); break; @@ -289,28 +293,26 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing->setHairStyle(id); break; case 2: - dstBeing->setWeapon(id); + dstBeing->setVisibleEquipment(Being::WEAPON_SPRITE, id); break; case 3: // Change lower headgear for eAthena, pants for us dstBeing->setVisibleEquipment( - Being::BOTTOMCLOTHES_SPRITE, - id); + Being::BOTTOMCLOTHES_SPRITE, id); break; case 4: // Change upper headgear for eAthena, hat for us dstBeing->setVisibleEquipment( - Being::HAT_SPRITE, - id); + Being::HAT_SPRITE, id); break; case 5: // Change middle headgear for eathena, armor for us dstBeing->setVisibleEquipment( - Being::TOPCLOTHES_SPRITE, - id); + Being::TOPCLOTHES_SPRITE, id); break; case 6: dstBeing->setHairColor(id); break; default: - logger->log("c3: %i\n", id); // unsupported + logger->log("SMSG_BEING_CHANGE_LOOKS: unsupported type: " + "%d, id: %d", type, id); break; } } @@ -336,17 +338,18 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing = beingManager->findBeing(id); - if (dstBeing == NULL) + if (!dstBeing) { dstBeing = beingManager->createBeing(id, job); } dstBeing->setWalkSpeed(speed); dstBeing->mJob = job; - dstBeing->setHairStyle(msg.readShort()); - dstBeing->setWeaponById(msg.readShort()); // item id 1 - msg.readShort(); // item id 2 - headBottom = msg.readShort(); + dstBeing->setHairStyle(msg->readShort()); + dstBeing->setVisibleEquipment( + Being::WEAPON_SPRITE, msg->readShort()); + msg->readShort(); // item id 2 + headBottom = msg->readShort(); if (msg.getId() == SMSG_PLAYER_MOVE) { @@ -407,9 +410,9 @@ void BeingHandler::handleMessage(MessageIn &msg) case 0x0119: // Change in players look - logger->log("0x0119 %li %i %i %x %i\n", msg.readLong(), - msg.readShort(), msg.readShort(), msg.readShort(), - msg.readByte()); + logger->log("0x0119 %i %i %i %x %i", msg->readLong(), + msg->readShort(), msg->readShort(), msg->readShort(), + msg->readByte()); break; */ } @@ -428,11 +431,9 @@ static void handleLooks(Being *being, MessageIn &msg) if (mask & (1 << 7)) { // The equipment has to be cleared first. - being->setWeaponById(0); for (int i = 0; i < nb_slots; ++i) { - if (slots[i] != Being::WEAPON_SPRITE) - being->setVisibleEquipment(slots[i], 0); + being->setVisibleEquipment(slots[i], 0); } } @@ -441,10 +442,7 @@ static void handleLooks(Being *being, MessageIn &msg) { if (!(mask & (1 << i))) continue; int id = msg.readShort(); - if (slots[i] != Being::WEAPON_SPRITE) - being->setVisibleEquipment(slots[i], id); - else - being->setWeaponById(id); + being->setVisibleEquipment(slots[i], id); } } diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index 3efe3174..afdc2ab5 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -37,6 +37,7 @@ #include "../gui/chat.h" #include "../utils/tostring.h" +#include "../utils/trim.h" extern Being *player_node; @@ -167,6 +168,7 @@ void ChatHandler::handleMessage(MessageIn &msg) chatMsg = msg.readString(chatMsgLength); chatWindow->chatLog(chatMsg, BY_OTHER); chatMsg.erase(0, chatMsg.find(" : ", 0) + 3); + trim(chatMsg); being->setSpeech(chatMsg, SPEECH_TIME); break; diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp index 354dd685..de74e8f5 100644 --- a/src/net/inventoryhandler.cpp +++ b/src/net/inventoryhandler.cpp @@ -31,6 +31,7 @@ #include "../equipment.h" #include "../inventory.h" #include "../item.h" +#include "../itemshortcut.h" #include "../localplayer.h" #include "../gui/chat.h" @@ -77,6 +78,7 @@ void InventoryHandler::handleMessage(MessageIn &msg) it->setQuantity(amount); } }; + itemShortcut->load(); break; } } diff --git a/src/net/playerhandler.cpp b/src/net/playerhandler.cpp index b94b5128..afaeca69 100644 --- a/src/net/playerhandler.cpp +++ b/src/net/playerhandler.cpp @@ -133,7 +133,8 @@ void PlayerHandler::handleMessage(MessageIn &msg) } else { - logger->log("Warning: server wants to update unknown attribute %d to %d", stat, value); + logger->log("Warning: server wants to update unknown " + "attribute %d to %d", stat, value); } } } break; diff --git a/src/particle.cpp b/src/particle.cpp index 805da102..148bbf6f 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -52,14 +52,12 @@ const float Particle::PARTICLE_SKY = 800.0f; Particle::Particle(Map *map): mAlive(true), - mPosX(0.0f), mPosY(0.0f), mPosZ(0.0f), mLifetimeLeft(-1), mLifetimePast(0), mFadeOut(0), mFadeIn(0), mAutoDelete(true), mMap(map), - mVectorX(0.0f), mVectorY(0.0f), mVectorZ(0.0f), mGravity(0.0f), mRandomnes(0), mBounce(0.0f), @@ -109,7 +107,7 @@ Particle::update() p++ ) { - (*p)->moveBy(mPosX, mPosY, mPosZ); + (*p)->moveBy(mPos.x, mPos.y, mPos.z); mChildParticles.push_back (*p); } } @@ -117,31 +115,28 @@ Particle::update() if (mMomentum != 1.0f) { - mVectorX *= mMomentum; - mVectorY *= mMomentum; - mVectorZ *= mMomentum; + mVelocity *= mMomentum; } if (mTarget && mAcceleration != 0.0f) { - float distX = (mPosX - mTarget->getPosX()) * SIN45; - float distY = mPosY - mTarget->getPosY(); - float distZ = mPosZ - mTarget->getPosZ(); + Vector dist = mPos - mTarget->getPosition(); + dist.x *= SIN45; float invHypotenuse; - switch(Particle::fastPhysics) + switch (Particle::fastPhysics) { case 1: invHypotenuse = fastInvSqrt( - distX * distX + distY * distY + distZ * distZ); + dist.x * dist.x + dist.y * dist.y + dist.z * dist.z); break; case 2: invHypotenuse = 2.0f / - fabs(distX) + fabs(distY) + fabs(distZ); + fabs(dist.x) + fabs(dist.y) + fabs(dist.z); break; default: invHypotenuse = 1.0f / sqrt( - distX * distX + distY * distY + distZ * distZ); + dist.x * dist.x + dist.y * dist.y + dist.z * dist.z); break; } @@ -152,25 +147,23 @@ Particle::update() mAlive = false; } float accFactor = invHypotenuse * mAcceleration; - mVectorX -= distX * accFactor; - mVectorY -= distY * accFactor; - mVectorZ -= distZ * accFactor; + mVelocity -= dist * accFactor; } } if (mRandomnes > 0) { - mVectorX += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f; - mVectorY += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f; - mVectorZ += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f; + mVelocity.x += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f; + mVelocity.y += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f; + mVelocity.z += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f; } - mVectorZ -= mGravity; + mVelocity.z -= mGravity; // Update position - mPosX += mVectorX; - mPosY += mVectorY * SIN45; - mPosZ += mVectorZ * SIN45; + mPos.x += mVelocity.x; + mPos.y += mVelocity.y * SIN45; + mPos.z += mVelocity.z * SIN45; // Update other stuff if (mLifetimeLeft > 0) @@ -179,14 +172,13 @@ Particle::update() } mLifetimePast++; - if (mPosZ > PARTICLE_SKY || mPosZ < 0.0f) + if (mPos.z > PARTICLE_SKY || mPos.z < 0.0f) { if (mBounce > 0.0f) { - mPosZ *= -mBounce; - mVectorX *= mBounce; - mVectorY *= mBounce; - mVectorZ *= -mBounce; + mPos.z *= -mBounce; + mVelocity *= mBounce; + mVelocity.z = -mVelocity.z; } else { mAlive = false; @@ -195,10 +187,8 @@ Particle::update() } // Update child particles - for ( ParticleIterator p = mChildParticles.begin(); - p != mChildParticles.end(); - - ) + for (ParticleIterator p = mChildParticles.begin(); + p != mChildParticles.end();) { if ((*p)->update()) { @@ -217,14 +207,9 @@ Particle::update() return true; } - -void Particle::draw(Graphics *graphics, int offsetX, int offsetY) const -{ -} - - Particle* -Particle::addEffect(std::string particleEffectFile, int pixelX, int pixelY) +Particle::addEffect(const std::string &particleEffectFile, + int pixelX, int pixelY) { Particle *newParticle = NULL; @@ -289,9 +274,9 @@ Particle::addEffect(std::string particleEffectFile, int pixelX, int pixelY) int offsetY = XML::getProperty(effectChildNode, "position-y", 0); int offsetZ = XML::getProperty(effectChildNode, "position-z", 0); - int particleX = (int)mPosX + pixelX + offsetX; - int particleY = (int)mPosY + pixelY + offsetY; - int particleZ = (int)mPosZ + offsetZ; + int particleX = (int) mPos.x + pixelX + offsetX; + int particleY = (int) mPos.y + pixelY + offsetY; + int particleZ = (int) mPos.z + offsetZ; int lifetime = XML::getProperty(effectChildNode, "lifetime", -1); @@ -317,17 +302,16 @@ Particle::addEffect(std::string particleEffectFile, int pixelX, int pixelY) Particle* -Particle::addTextSplashEffect(std::string text, +Particle::addTextSplashEffect(const std::string &text, int colorR, int colorG, int colorB, gcn::Font *font, int x, int y) { Particle *newParticle = new TextParticle(mMap, text, colorR, colorG, colorB, font); newParticle->setPosition(x, y, 0); - newParticle->setVector ( ((rand()%100) - 50) / 200.0f, // X vector - ((rand()%100) - 50) / 200.0f, // Y vector - ((rand()%100) / 200.0f) + 4.0f // Z vector - ); + newParticle->setVelocity(((rand() % 100) - 50) / 200.0f, // X + ((rand() % 100) - 50) / 200.0f, // Y + ((rand() % 100) / 200.0f) + 4.0f); // Z newParticle->setGravity(0.1f); newParticle->setBounce(0.5f); newParticle->setLifetime(200); @@ -338,14 +322,28 @@ Particle::addTextSplashEffect(std::string text, return newParticle; } +Particle* +Particle::addTextRiseFadeOutEffect(const std::string &text, gcn::Font *font, + int x, int y) +{ + Particle *newParticle = new TextParticle(mMap, text, 255, 255, 255, font); + newParticle->setPosition(x, y, 0); + newParticle->setVelocity(0.0f, 0.0f, 0.5f); + newParticle->setGravity(0.0015f); + newParticle->setLifetime(300); + newParticle->setFadeOut(50); + newParticle->setFadeIn(200); + + mChildParticles.push_back(newParticle); + + return newParticle; +} void Particle::setMap(Map *map) { mMap = map; if (mMap) setSpriteIterator(mMap->addSprite(this)); - - // TODO: Create map emitters based on emitter data in map data } diff --git a/src/particle.h b/src/particle.h index 9e9223c7..dd7c5ee2 100644 --- a/src/particle.h +++ b/src/particle.h @@ -31,7 +31,7 @@ #include "guichanfwd.h" #include "sprite.h" - +#include "vector.h" class Map; class Particle; @@ -67,43 +67,37 @@ class Particle : public Sprite ~Particle(); /** - * Deletes all child particles and emitters + * Deletes all child particles and emitters. */ void clear(); /** * Gives a particle the properties of an engine root particle and loads - * the particle-related config settings + * the particle-related config settings. */ void setupEngine(); /** * Updates particle position, returns false when the particle should - * be deleted + * be deleted. */ virtual bool update(); /** - * Draws the particle image + * Draws the particle image. */ virtual void - draw(Graphics *graphics, int offsetX, int offsetY) const; + draw(Graphics *graphics, int offsetX, int offsetY) const {} /** - * Necessary for sorting with the other sprites + * Necessary for sorting with the other sprites. */ virtual int getPixelY() const - { - return (int)(mPosY + mPosZ) - 64; - }; - - /* - Basic Particle properties: - */ + { return (int) (mPos.y + mPos.z) - 64; } /** * Sets the map the particle is on. @@ -115,15 +109,24 @@ class Particle : public Sprite * particleEffectFile. */ Particle* - addEffect(std::string particleEffectFile, int pixelX, int pixelY); + addEffect(const std::string &particleEffectFile, + int pixelX, int pixelY); /** * Creates a standalone text particle. */ Particle* - addTextSplashEffect(std::string text, int colorR, int colorG, int colorB, + addTextSplashEffect(const std::string &text, + int colorR, int colorG, int colorB, gcn::Font *font, int x, int y); + /** + * Creates a standalone text particle. + */ + Particle* + addTextRiseFadeOutEffect(const std::string &text, gcn::Font *font, + int x, int y); + /** * Adds an emitter to the particle. */ @@ -132,34 +135,31 @@ class Particle : public Sprite { mChildEmitters.push_back(emitter); } /** - * Sets the position in 3 dimensional space in pixels relative to map + * Sets the position in 3 dimensional space in pixels relative to map. */ void setPosition(float x, float y, float z) - { mPosX = x; mPosY = y; mPosZ = z; } + { mPos.x = x; mPos.y = y; mPos.z = z; } /** - * Sets the position in 2 dimensional space in pixels relative to map + * Sets the position in 2 dimensional space in pixels relative to map. */ void setPosition(float x, float y) - { mPosX = x; mPosY = y; } - - float getPosX() const - { return mPosX; } + { mPos.x = x; mPos.y = y; } - float getPosY() const - { return mPosY; } - - float getPosZ() const - { return mPosZ; } + /** + * Returns the particle position. + */ + const Vector& getPosition() const + { return mPos; } /** * Changes the particle position relative */ void moveBy(float x, float y, float z) - { mPosX += x; mPosY += y; mPosZ += z; } + { mPos.x += x; mPos.y += y; mPos.z += z; } /** * Sets the time in game ticks until the particle is destroyed. @@ -170,48 +170,48 @@ class Particle : public Sprite /** * Sets the age of the pixel in game ticks where the particle has - * faded in completely + * faded in completely. */ void - setFadeOut (int fadeOut) + setFadeOut(int fadeOut) { mFadeOut = fadeOut; } /** * Sets the remaining particle lifetime where the particle starts to - * fade out + * fade out. */ void - setFadeIn (int fadeIn) + setFadeIn(int fadeIn) { mFadeIn = fadeIn; } /** * Sets the sprite iterator of the particle on the current map to make - * it easier to remove the particle from the map when it is destroyed + * it easier to remove the particle from the map when it is destroyed. */ void setSpriteIterator(std::list::iterator spriteIterator) { mSpriteIterator = spriteIterator; } /** - * Gets the sprite iterator of the particle on the current map + * Gets the sprite iterator of the particle on the current map. */ std::list::iterator getSpriteIterator() const { return mSpriteIterator; } /** - * Sets the current velocity in 3 dimensional space + * Sets the current velocity in 3 dimensional space. */ void - setVector(float x, float y, float z) - { mVectorX = x; mVectorY = y; mVectorZ = z; } + setVelocity(float x, float y, float z) + { mVelocity.x = x; mVelocity.y = y; mVelocity.z = z; } /** - * Sets the downward acceleration + * Sets the downward acceleration. */ void - setGravity(float g) - { mGravity = g; } + setGravity(float gravity) + { mGravity = gravity; } /** * Sets the ammount of random vector changes @@ -237,8 +237,8 @@ class Particle : public Sprite /** * Sets the distance in pixel the particle can come near the target - * particle before it is destroyed. Does only make sense after a - * target particle has been set using setDestination. + * particle before it is destroyed. Does only make sense after a target + * particle has been set using setDestination. */ void setDieDistance(float dist) { mInvDieDistance = 1.0f / dist; } @@ -247,7 +247,7 @@ class Particle : public Sprite { return mAlive; } /** - * Manually marks the particle for deletion + * Manually marks the particle for deletion. */ void kill() { mAlive = false; mAutoDelete = true; } @@ -261,7 +261,7 @@ class Particle : public Sprite protected: bool mAlive; /**< Is the particle supposed to be drawn and updated?*/ - float mPosX, mPosY, mPosZ; /**< Position in 3 dimensonal space - pixel based relative to map */ + Vector mPos; /**< Position in pixels relative to map. */ int mLifetimeLeft; /**< Lifetime left in game ticks*/ int mLifetimePast; /**< Age of the particle in game ticks*/ int mFadeOut; /**< Lifetime in game ticks left where fading out begins*/ @@ -269,17 +269,19 @@ class Particle : public Sprite private: // generic properties - bool mAutoDelete; /**< May the particle request its deletion by the parent particle?*/ - Map *mMap; /**< Map the particle is on*/ + bool mAutoDelete; /**< May the particle request its deletion by the parent particle? */ + Map *mMap; /**< Map the particle is on. */ std::list::iterator mSpriteIterator; /**< iterator of the particle on the current map */ - Emitters mChildEmitters; /**< List of child emitters*/ - Particles mChildParticles; /**< List of particles controlled by this particle*/ - //dynamic particle - float mVectorX, mVectorY, mVectorZ; /**< Speed in 3 dimensional space in pixels per game-tick */ - float mGravity; /**< Downward acceleration in pixels per game-tick²*/ - int mRandomnes; /**< Ammount of random vector change*/ - float mBounce; /**< How much the particle bounces off when hitting the ground*/ - //follow-point particles + Emitters mChildEmitters; /**< List of child emitters. */ + Particles mChildParticles; /**< List of particles controlled by this particle */ + + // dynamic particle + Vector mVelocity; /**< Speed in pixels per game-tick. */ + float mGravity; /**< Downward acceleration in pixels per game-tick. */ + int mRandomnes; /**< Ammount of random vector change */ + float mBounce; /**< How much the particle bounces off when hitting the ground */ + + // follow-point particles Particle *mTarget; /**< The particle that attracts this particle*/ float mAcceleration; /**< Acceleration towards the target particle in pixels per game-tick²*/ float mInvDieDistance; /**< Distance in pixels from the target particle that causes the destruction of the particle*/ diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp index 60a98cc5..035882b6 100644 --- a/src/particleemitter.cpp +++ b/src/particleemitter.cpp @@ -248,10 +248,9 @@ ParticleEmitter::readMinMax(xmlNodePtr propertyNode, T def) { MinMax retval; - def = (T)XML::getFloatProperty(propertyNode, "value", (double)def); - retval.set ( (T)XML::getFloatProperty(propertyNode, "min", (double)def), - (T)XML::getFloatProperty(propertyNode, "max", (double)def) - ); + def = (T) XML::getFloatProperty(propertyNode, "value", (double) def); + retval.set((T) XML::getFloatProperty(propertyNode, "min", (double) def), + (T) XML::getFloatProperty(propertyNode, "max", (double) def)); return retval; } @@ -284,19 +283,17 @@ ParticleEmitter::createParticles() newParticle->setPosition( - mParticlePosX.value(), - mParticlePosY.value(), - mParticlePosZ.value() - ); + mParticlePosX.value(), + mParticlePosY.value(), + mParticlePosZ.value()); float angleH = mParticleAngleHorizontal.value(); float angleV = mParticleAngleVertical.value(); float power = mParticlePower.value(); - newParticle->setVector( - cos(angleH) * cos(angleV) * power, - sin(angleH) * cos(angleV) * power, - sin(angleV) * power - ); + newParticle->setVelocity( + cos(angleH) * cos(angleV) * power, + sin(angleH) * cos(angleV) * power, + sin(angleV) * power); newParticle->setRandomnes(mParticleRandomnes.value()); newParticle->setGravity(mParticleGravity.value()); @@ -312,10 +309,9 @@ ParticleEmitter::createParticles() newParticle->setFadeOut(mParticleFadeOut.value()); newParticle->setFadeIn(mParticleFadeIn.value()); - for ( std::list::iterator i = mParticleChildEmitters.begin(); - i != mParticleChildEmitters.end(); - i++ - ) + for (std::list::iterator i = mParticleChildEmitters.begin(); + i != mParticleChildEmitters.end(); + i++) { newParticle->addEmitter(new ParticleEmitter(*i)); } diff --git a/src/player.cpp b/src/player.cpp index d3c27aa0..b63dcd5b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -28,7 +28,8 @@ #include "graphics.h" #include "log.h" -#include "resources/equipmentdb.h" +#include "resources/itemdb.h" +#include "resources/iteminfo.h" #include "utils/tostring.h" @@ -37,7 +38,6 @@ Player::Player(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { - setWeapon(0); } Being::Type @@ -93,8 +93,8 @@ Player::setSex(Uint8 sex) if (i != HAIR_SPRITE && mEquipmentSpriteIDs.at(i) != 0) { AnimatedSprite *newEqSprite = new AnimatedSprite( - "graphics/sprites/" + EquipmentDB::get( - mEquipmentSpriteIDs.at(i))->getSprite(sex)); + "graphics/sprites/" + ItemDB::get( + mEquipmentSpriteIDs.at(i)).getSprite(sex)); delete mSprites[i]; mSprites[i] = newEqSprite; } @@ -102,39 +102,6 @@ Player::setSex(Uint8 sex) } } -void -Player::setWeapon(Uint16 weapon) -{ - if (weapon != mWeapon) - { - AnimatedSprite *newWeaponSprite = NULL; - - switch (weapon) - { - case 0: - newWeaponSprite = - new AnimatedSprite("graphics/sprites/weapon-fist.xml"); - break; - case 1: - newWeaponSprite = - new AnimatedSprite("graphics/sprites/weapon-dagger.xml"); - break; - case 2: - newWeaponSprite = - new AnimatedSprite("graphics/sprites/weapon-bow.xml"); - break; - case 3: - newWeaponSprite = - new AnimatedSprite("graphics/sprites/weapon-scythe.xml"); - break; - } - - delete mSprites[WEAPON_SPRITE]; - mSprites[WEAPON_SPRITE] = newWeaponSprite; - } - Being::setWeapon(weapon); -} - void Player::setHairColor(Uint16 color) { @@ -189,11 +156,11 @@ Player::setVisibleEquipment(Uint8 slot, int id) if (mSex == 0) { equipmentSprite = new AnimatedSprite( - "graphics/sprites/" + EquipmentDB::get(id)->getSprite(0)); + "graphics/sprites/" + ItemDB::get(id).getSprite(0)); } else { equipmentSprite = new AnimatedSprite( - "graphics/sprites/" + EquipmentDB::get(id)->getSprite(1)); + "graphics/sprites/" + ItemDB::get(id).getSprite(1)); } equipmentSprite->setDirection(getSpriteDirection()); @@ -201,6 +168,11 @@ Player::setVisibleEquipment(Uint8 slot, int id) delete mSprites[slot]; mSprites[slot] = equipmentSprite; + if (slot == WEAPON_SPRITE) + { + mEquippedWeapon = &ItemDB::get(id); + } + setAction(mAction); } diff --git a/src/player.h b/src/player.h index 8aa84992..2c06bfba 100644 --- a/src/player.h +++ b/src/player.h @@ -59,9 +59,6 @@ class Player : public Being virtual void setVisibleEquipment(Uint8 slot, int id); - - virtual void - setWeapon(Uint16 weapon); }; #endif diff --git a/src/resources/equipmentdb.cpp b/src/resources/equipmentdb.cpp deleted file mode 100644 index 38ac6415..00000000 --- a/src/resources/equipmentdb.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * The Mana World - * Copyright 2006 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$ - */ - -#include "equipmentdb.h" - -#include "resourcemanager.h" - -#include "../log.h" - -#include "../utils/dtor.h" -#include "../utils/xml.h" - -namespace -{ - EquipmentDB::EquipmentInfos mEquipmentInfos; - EquipmentInfo mUnknown; - bool mLoaded = false; -} - -void -EquipmentDB::load() -{ - if (mLoaded) - return; - - logger->log("Initializing equipment database..."); - mUnknown.setSprite("error.xml", 0); - mUnknown.setSprite("error.xml", 1); - - ResourceManager *resman = ResourceManager::getInstance(); - int size; - char *data = (char*)resman->loadFile("equipment.xml", size); - - if (!data) - { - logger->error("Equipment Database: Could not find equipment.xml!"); - } - - xmlDocPtr doc = xmlParseMemory(data, size); - free(data); - - if (!doc) - { - logger->error("Equipment Database: Error while parsing equipment database (equipment.xml)!"); - } - - xmlNodePtr rootNode = xmlDocGetRootElement(doc); - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "equipments")) - { - logger->error("Equipment Database: equipment.xml is not a valid database file!"); - } - - //iterate s - for_each_xml_child_node(equipmentNode, rootNode) - { - if (!xmlStrEqual(equipmentNode->name, BAD_CAST "equipment")) - { - continue; - } - - EquipmentInfo *currentInfo = new EquipmentInfo(); - - currentInfo->setSlot (XML::getProperty(equipmentNode, "slot", 0)); - - //iterate s - for_each_xml_child_node(spriteNode, equipmentNode) - { - if (!xmlStrEqual(spriteNode->name, BAD_CAST "sprite")) - { - continue; - } - - std::string gender = XML::getProperty(spriteNode, "gender", "unisex"); - std::string filename = (const char*) spriteNode->xmlChildrenNode->content; - - if (gender == "male" || gender == "unisex") - { - currentInfo->setSprite(filename, 0); - } - - if (gender == "female" || gender == "unisex") - { - currentInfo->setSprite(filename, 1); - } - } - - setEquipment( XML::getProperty(equipmentNode, "id", 0), - currentInfo); - } - - mLoaded = true; -} - -void -EquipmentDB::unload() -{ - // kill EquipmentInfos - for_each ( mEquipmentInfos.begin(), mEquipmentInfos.end(), - make_dtor(mEquipmentInfos)); - mEquipmentInfos.clear(); - - mLoaded = false; -} - -EquipmentInfo* -EquipmentDB::get(int id) -{ - if (!mLoaded) { - logger->error("Error: Equipment database used before initialization!"); - } - - EquipmentInfoIterator i = mEquipmentInfos.find(id); - - if (i == mEquipmentInfos.end() ) - { - logger->log("EquipmentDB: Error, unknown equipment ID# %d", id); - return &mUnknown; - } - else - { - return i->second; - } -} - -void -EquipmentDB::setEquipment(int id, EquipmentInfo* equipmentInfo) -{ - if (mEquipmentInfos.find(id) != mEquipmentInfos.end()) { - logger->log("Warning: Equipment Piece with ID %d defined multiple times", - id); - delete equipmentInfo; - } - else { - mEquipmentInfos[id] = equipmentInfo; - }; -} diff --git a/src/resources/equipmentdb.h b/src/resources/equipmentdb.h deleted file mode 100644 index 1c1db7d1..00000000 --- a/src/resources/equipmentdb.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * The Mana World - * Copyright 2006 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$ - */ - -#ifndef _TMW_EQUIPMENT_DB_H -#define _TMW_EQUIPMENT_DB_H - -#include - -#include "equipmentinfo.h" - -/** - * Equipment information database. - */ -namespace EquipmentDB -{ - /** - * Loads the equipment info from Items.xml - */ - void load(); - - /** - * Frees equipment data - */ - void unload(); - - void setEquipment(int id, EquipmentInfo* equipmentInfo); - - EquipmentInfo* get(int id); - - // Equipment database types - typedef std::map EquipmentInfos; - typedef EquipmentInfos::iterator EquipmentInfoIterator; -} - -#endif diff --git a/src/resources/equipmentinfo.h b/src/resources/equipmentinfo.h deleted file mode 100644 index 75ed1b8a..00000000 --- a/src/resources/equipmentinfo.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * The Mana World - * Copyright 2006 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: - */ - -#ifndef _TMW_EQUIPMENTINFO_H_ -#define _TMW_EQUIPMENTINFO_H_ - -#include -#include - -class EquipmentInfo -{ - public: - EquipmentInfo(): - mSlot (0) - { - }; - - void - setSlot (int slot) { mSlot = slot; }; - - const std::string& - getSprite(int gender) {return animationFiles[gender]; }; - - void - setSprite(std::string animationFile, int gender) {animationFiles[gender] = animationFile; }; - - private: - int mSlot; //not used at the moment but maybe useful on our own server - std::map animationFiles; -}; - -#endif diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index 7b16339c..18952ae9 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -18,9 +18,11 @@ * 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: + * $Id$ */ +#include + #include "itemdb.h" #include @@ -36,10 +38,13 @@ namespace { ItemDB::ItemInfos mItemInfos; - ItemInfo mUnknown; + ItemInfo *mUnknown; bool mLoaded = false; } +// Forward declarations +static void loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node); +static void loadSoundRef(ItemInfo *itemInfo, xmlNodePtr node); void ItemDB::load() { @@ -47,11 +52,16 @@ void ItemDB::load() return; logger->log("Initializing item database..."); - mUnknown.setName("Unknown item"); + + mUnknown = new ItemInfo(); + mUnknown->setName("Unknown item"); + mUnknown->setImage(""); + mUnknown->setSprite("error.xml", 0); + mUnknown->setSprite("error.xml", 1); ResourceManager *resman = ResourceManager::getInstance(); int size; - char *data = (char*)resman->loadFile("items.xml", size); + char *data = (char*) resman->loadFile("items.xml", size); if (!data) { logger->error("ItemDB: Could not find items.xml!"); @@ -73,48 +83,66 @@ void ItemDB::load() for_each_xml_child_node(node, rootNode) { - if (!xmlStrEqual(node->name, BAD_CAST "item")) { + if (!xmlStrEqual(node->name, BAD_CAST "item")) continue; - } int id = XML::getProperty(node, "id", 0); - int art = XML::getProperty(node, "art", 0); + + if (id == 0) + { + logger->log("ItemDB: Invalid or missing item ID in items.xml!"); + continue; + } + else if (mItemInfos.find(id) != mItemInfos.end()) + { + logger->log("ItemDB: Redefinition of item ID %d", id); + } + int type = XML::getProperty(node, "type", 0); int weight = XML::getProperty(node, "weight", 0); + int view = XML::getProperty(node, "view", 0); int slot = XML::getProperty(node, "slot", 0); std::string name = XML::getProperty(node, "name", ""); std::string image = XML::getProperty(node, "image", ""); std::string description = XML::getProperty(node, "description", ""); std::string effect = XML::getProperty(node, "effect", ""); + std::string attackType = XML::getProperty(node, "attacktype", ""); - if (id && name != "") + if (id) { ItemInfo *itemInfo = new ItemInfo(); itemInfo->setImage(image); - itemInfo->setArt(art); - itemInfo->setName(name); + itemInfo->setName((name == "") ? "Unnamed" : name); itemInfo->setDescription(description); itemInfo->setEffect(effect); itemInfo->setType(type); + itemInfo->setView(view); itemInfo->setWeight(weight); itemInfo->setSlot(slot); - mItemInfos[id] = itemInfo; - } + itemInfo->setAttackType(attackType); + + for_each_xml_child_node(itemChild, node) + { + if (xmlStrEqual(itemChild->name, BAD_CAST "sprite")) + { + loadSpriteRef(itemInfo, itemChild); + } + else if (xmlStrEqual(itemChild->name, BAD_CAST "sound")) + { + loadSoundRef(itemInfo, itemChild); + } + } - if (id == 0) - { - logger->log("ItemDB: An item has no ID in items.xml!"); + mItemInfos[id] = itemInfo; } #define CHECK_PARAM(param, error_value) \ if (param == error_value) \ - logger->log("ItemDB: Missing" #param " parameter for item %i! %s", \ - id, name.c_str()) + logger->log("ItemDB: Missing " #param " attribute for item %i!",id) CHECK_PARAM(name, ""); CHECK_PARAM(image, ""); - // CHECK_PARAM(art, 0); // CHECK_PARAM(description, ""); // CHECK_PARAM(effect, ""); // CHECK_PARAM(type, 0); @@ -131,19 +159,65 @@ void ItemDB::load() void ItemDB::unload() { - for (ItemInfoIterator i = mItemInfos.begin(); i != mItemInfos.end(); i++) - { - delete i->second; - } - mItemInfos.clear(); + logger->log("Unloading item database..."); + + delete mUnknown; + mUnknown = NULL; + for_each(mItemInfos.begin(), mItemInfos.end(), make_dtor(mItemInfos)); + mItemInfos.clear(); mLoaded = false; } -const ItemInfo& -ItemDB::get(int id) +const ItemInfo& ItemDB::get(int id) { + assert(mLoaded); + ItemInfoIterator i = mItemInfos.find(id); - return (i != mItemInfos.end()) ? *(i->second) : mUnknown; + if (i == mItemInfos.end()) + { + logger->log("ItemDB: Error, unknown item ID# %d", id); + return *mUnknown; + } + else + { + return *(i->second); + } +} + +void loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node) +{ + std::string gender = XML::getProperty(node, "gender", "unisex"); + std::string filename = (const char*) node->xmlChildrenNode->content; + + if (gender == "male" || gender == "unisex") + { + itemInfo->setSprite(filename, 0); + } + + if (gender == "female" || gender == "unisex") + { + itemInfo->setSprite(filename, 1); + } +} + +void loadSoundRef(ItemInfo *itemInfo, xmlNodePtr node) +{ + std::string event = XML::getProperty(node, "event", ""); + std::string filename = (const char*) node->xmlChildrenNode->content; + + if (event == "hit") + { + itemInfo->addSound(EQUIP_EVENT_HIT, filename); + } + else if (event == "strike") + { + itemInfo->addSound(EQUIP_EVENT_STRIKE, filename); + } + else + { + logger->log("ItemDB: Ignoring unknown sound event '%s'", + event.c_str()); + } } diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp index 3a41c657..b5b25ac0 100644 --- a/src/resources/iteminfo.cpp +++ b/src/resources/iteminfo.cpp @@ -25,11 +25,11 @@ #include "resourcemanager.h" #include "image.h" - +#include "itemdb.h" ItemInfo::~ItemInfo() { - if (mImage != NULL) + if (mImage) { mImage->decRef(); } @@ -38,19 +38,87 @@ ItemInfo::~ItemInfo() void ItemInfo::setImage(const std::string &image) { + if (mImage) + { + mImage->decRef(); + } + + ResourceManager *resman = ResourceManager::getInstance(); mImageName = "graphics/items/" + image; + mImage = ResourceManager::getInstance()->getImage(mImageName); - if (mImageName != "") + if (!mImage) { - if (mImage != NULL) - { - mImage->decRef(); - } + mImage = resman->getImage("graphics/gui/unknown-item.png"); + } +} - mImage = ResourceManager::getInstance()->getImage(mImageName); +const std::string& +ItemInfo::getSprite(int gender) const +{ + if (mView) + { + // Forward the request to the item defining how to view this item + return ItemDB::get(mView).getSprite(gender); } else { - mImage = NULL; + static const std::string empty = ""; + std::map::const_iterator i = + mAnimationFiles.find(gender); + + return (i != mAnimationFiles.end()) ? i->second : empty; + } +} + +void +ItemInfo::setAttackType(const std::string &attackType) +{ + if (attackType == "swing") + { + mAttackType = ACTION_ATTACK_SWING; + } + else if (attackType == "stab") + { + mAttackType = ACTION_ATTACK_STAB; + } + else if (attackType == "bow") + { + mAttackType = ACTION_ATTACK_BOW; } + else if (attackType == "throw") + { + mAttackType = ACTION_ATTACK_THROW; + } + else if (attackType == "none") + { + mAttackType = ACTION_DEFAULT; + } + else + { + mAttackType = ACTION_ATTACK; + } +} + +void +ItemInfo::addSound(EquipmentSoundEvent event, const std::string &filename) +{ + if (mSounds.find(event) == mSounds.end()) + { + mSounds[event] = new std::vector; + } + + mSounds[event]->push_back("sfx/" + filename); +} + + +const std::string& +ItemInfo::getSound(EquipmentSoundEvent event) const +{ + static const std::string empty = ""; + std::map*>::const_iterator i; + i = mSounds.find(event); + + return (i == mSounds.end()) ? empty : + i->second->at(rand() % i->second->size()); } diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index e4f851bb..4fd1638e 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -24,12 +24,23 @@ #ifndef _TMW_ITEMINFO_H_ #define _TMW_ITEMINFO_H_ +#include #include +#include + +#include "spritedef.h" class Image; +enum EquipmentSoundEvent +{ + EQUIP_EVENT_STRIKE, + EQUIP_EVENT_HIT +}; + /** - * Defines a class for storing item infos. + * Defines a class for storing item infos. This includes information used when + * the item is equipped. */ class ItemInfo { @@ -40,10 +51,11 @@ class ItemInfo ItemInfo(): mImageName(""), mImage(NULL), - mArt(0), mType(0), mWeight(0), - mSlot(0) + mView(0), + mSlot(0), + mAttackType(ACTION_DEFAULT) { } @@ -52,73 +64,89 @@ class ItemInfo */ ~ItemInfo(); - void - setArt(short art) { mArt = art; } + void setName(const std::string &name) + { mName = name; } - short - getArt() const { return mArt; } + const std::string& getName() const + { return mName; } - void - setName(const std::string &name) { mName = name; } + void setImage(const std::string &image); - const std::string& - getName() const { return mName; } + Image* getImage() const + { return mImage; } - void - setImage(const std::string &image); + void setDescription(const std::string &description) + { mDescription = description; } - Image* - getImage() const { return mImage; } + const std::string& getDescription() const + { return mDescription; } - void - setDescription(const std::string &description) - { - mDescription = description; - } + void setEffect(const std::string &effect) + { mEffect = effect; } const std::string& - getDescription() const { return mDescription; } + getEffect() const { return mEffect; } - void - setEffect(const std::string &effect) { mEffect = effect; } + void setType(short type) + { mType = type; } - const std::string& - getEffect() const { return mEffect; } + short getType() const + { return mType; } + + void setWeight(short weight) + { mWeight = weight; } + + short getWeight() const + { return mWeight; } + + void setView(int view) + { mView = view; } + + void setSlot(char slot) + { mSlot = slot; } - void - setType(short type) { mType = type; } + char getSlot() const + { return mSlot; } - short - getType() const { return mType; } + void setSprite(const std::string &animationFile, int gender) + { mAnimationFiles[gender] = animationFile; } - void - setWeight(short weight) { mWeight = weight; } + const std::string& getSprite(int gender) const; - short - getWeight() const { return mWeight; } + void setAttackType(const std::string &attackType); - void - setSlot(char slot) { mSlot = slot; } + const SpriteAction getAttackType() const + { return mAttackType; } - char - getSlot() const { return mSlot; } + void addSound(EquipmentSoundEvent event, const std::string &filename); + + const std::string& getSound(EquipmentSoundEvent event) const; protected: - std::string mImageName; + std::string mImageName; /**< The filename of the icon image. */ /* 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; + Image *mImage; /**< The loaded icon image. */ std::string mName; - std::string mDescription; - std::string mEffect; - short mType; - short mWeight; - char mSlot; + std::string mDescription; /**< Short description. */ + std::string mEffect; /**< Description of effects. */ + short mType; /**< Item type (never used). */ + short mWeight; /**< Weight in grams. */ + int mView; /**< Item ID of how this item looks. */ + + // Equipment related members + char mSlot; /**< Equipment slot. */ + SpriteAction mAttackType; /**< Attack type, in case of weapon. */ + + /** Maps gender to sprite filenames. */ + std::map mAnimationFiles; + + /** Stores the names of sounds to be played at certain event. */ + std::map* > mSounds; }; #endif diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp index 260d5aa9..940ded36 100644 --- a/src/resources/mapreader.cpp +++ b/src/resources/mapreader.cpp @@ -156,7 +156,7 @@ MapReader::readMap(const std::string &filename) if (buffer == NULL) { - logger->log("Map file not found (%s)\n", filename.c_str()); + logger->log("Map file not found (%s)", filename.c_str()); return NULL; } diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp index 339ed6ba..f4864eea 100644 --- a/src/resources/monsterdb.cpp +++ b/src/resources/monsterdb.cpp @@ -120,19 +120,19 @@ MonsterDB::load() if (event == "hit") { - currentInfo->addSound(EVENT_HIT, filename); + currentInfo->addSound(MONSTER_EVENT_HIT, filename); } else if (event == "miss") { - currentInfo->addSound(EVENT_MISS, filename); + currentInfo->addSound(MONSTER_EVENT_MISS, filename); } else if (event == "hurt") { - currentInfo->addSound(EVENT_HURT, filename); + currentInfo->addSound(MONSTER_EVENT_HURT, filename); } else if (event == "die") { - currentInfo->addSound(EVENT_DIE, filename); + currentInfo->addSound(MONSTER_EVENT_DIE, filename); } else { diff --git a/src/resources/monsterinfo.cpp b/src/resources/monsterinfo.cpp index 2a59419e..2e896237 100644 --- a/src/resources/monsterinfo.cpp +++ b/src/resources/monsterinfo.cpp @@ -33,15 +33,15 @@ MonsterInfo::MonsterInfo(): MonsterInfo::~MonsterInfo() { - //kill vectors in mSoundEffects - for_each ( mSounds.begin(), mSounds.end(), - make_dtor(mSounds)); + // kill vectors in mSoundEffects + for_each (mSounds.begin(), mSounds.end(), + make_dtor(mSounds)); mSounds.clear(); } void -MonsterInfo::addSound (SoundEvent event, std::string filename) +MonsterInfo::addSound(MonsterSoundEvent event, std::string filename) { if (mSounds.find(event) == mSounds.end()) { @@ -53,9 +53,9 @@ MonsterInfo::addSound (SoundEvent event, std::string filename) std::string -MonsterInfo::getSound (SoundEvent event) const +MonsterInfo::getSound(MonsterSoundEvent event) const { - std::map* >::const_iterator i; + std::map* >::const_iterator i; i = mSounds.find(event); diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h index aa7db9f0..c9fbd4c9 100644 --- a/src/resources/monsterinfo.h +++ b/src/resources/monsterinfo.h @@ -31,12 +31,12 @@ #include "../being.h" -enum SoundEvent +enum MonsterSoundEvent { - EVENT_HIT, - EVENT_MISS, - EVENT_HURT, - EVENT_DIE + MONSTER_EVENT_HIT, + MONSTER_EVENT_MISS, + MONSTER_EVENT_HURT, + MONSTER_EVENT_DIE }; /** @@ -69,7 +69,7 @@ class MonsterInfo { mTargetCursorSize = targetCursorSize; } void - addSound(SoundEvent event, std::string filename); + addSound(MonsterSoundEvent event, std::string filename); const std::string& getName () const { return mName; }; @@ -81,13 +81,13 @@ class MonsterInfo getTargetCursorSize() const { return mTargetCursorSize; } std::string - getSound (SoundEvent event) const; + getSound(MonsterSoundEvent event) const; private: std::string mName; std::string mSprite; Being::TargetCursorSize mTargetCursorSize; - std::map* > mSounds; + std::map* > mSounds; }; #endif diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h index 6d335b02..55d7f459 100644 --- a/src/resources/spritedef.h +++ b/src/resources/spritedef.h @@ -24,11 +24,11 @@ #ifndef _TMW_SPRITEDEF_H #define _TMW_SPRITEDEF_H -#include "resource.h" - #include #include +#include "resource.h" + #include class Action; diff --git a/src/textparticle.cpp b/src/textparticle.cpp index dd01d2fe..4bc859cd 100644 --- a/src/textparticle.cpp +++ b/src/textparticle.cpp @@ -26,7 +26,8 @@ #include "graphics.h" TextParticle::TextParticle(Map *map, const std::string &text, - int colorR, int colorG, int colorB, gcn::Font *font): + int colorR, int colorG, int colorB, + gcn::Font *font): Particle(map), mText(text), mTextFont(font), @@ -41,8 +42,8 @@ void TextParticle::draw(Graphics *graphics, int offsetX, int offsetY) const if (!mAlive) return; - int screenX = (int)mPosX + offsetX; - int screenY = (int)mPosY - int(mPosZ) + offsetY; + int screenX = (int) mPos.x + offsetX; + int screenY = (int) mPos.y - (int) mPos.z + offsetY; int alpha = 255; @@ -50,7 +51,7 @@ void TextParticle::draw(Graphics *graphics, int offsetX, int offsetY) const { alpha *= mLifetimeLeft; alpha /= mFadeOut; - }; + } if (mLifetimePast < mFadeIn) { @@ -59,6 +60,6 @@ void TextParticle::draw(Graphics *graphics, int offsetX, int offsetY) const } graphics->setFont(mTextFont); - graphics->setColor(gcn::Color (mColorR, mColorG, mColorB, alpha)); + graphics->setColor(gcn::Color(mColorR, mColorG, mColorB, alpha)); graphics->drawText(mText, screenX, screenY, gcn::Graphics::CENTER); } diff --git a/src/textparticle.h b/src/textparticle.h index b365c885..34badb57 100644 --- a/src/textparticle.h +++ b/src/textparticle.h @@ -33,21 +33,26 @@ class TextParticle : public Particle { public: + /** + * Constructor. + */ TextParticle(Map *map, const std::string &text, - int colorR, int colorG, int colorB, gcn::Font *font); + int colorR, int colorG, int colorB, + gcn::Font *font); /** - * Draws the particle image + * Draws the particle image. */ virtual void draw(Graphics *graphics, int offsetX, int offsetY) const; // hack to improve text visibility - virtual int getPixelY() const { return (int)(mPosY + mPosZ); } + virtual int getPixelY() const + { return (int) (mPos.y + mPos.z); } private: - std::string mText; /**< Text of the particle */ - gcn::Font *mTextFont; /**< Font used for drawing the text */ - int mColorR, mColorG, mColorB; /**< Color used for drawing the text */ + std::string mText; /**< Text of the particle. */ + gcn::Font *mTextFont; /**< Font used for drawing the text. */ + int mColorR, mColorG, mColorB; /**< Color used for drawing the text. */ }; #endif diff --git a/src/utils/fastsqrt.h b/src/utils/fastsqrt.h index 78768149..b7b036e9 100644 --- a/src/utils/fastsqrt.h +++ b/src/utils/fastsqrt.h @@ -5,6 +5,8 @@ * http://www.math.purdue.edu/~clomont/Math/Papers/2003/InvSqrt.pdf * * Unfortunately the original creator of this function seems to be unknown. + * + * $Id$ */ float fastInvSqrt(float x) diff --git a/src/utils/minmax.h b/src/utils/minmax.h index 27eb2565..ea6ad9e0 100644 --- a/src/utils/minmax.h +++ b/src/utils/minmax.h @@ -18,6 +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$ */ /** diff --git a/src/utils/trim.h b/src/utils/trim.h new file mode 100644 index 00000000..1b5311e6 --- /dev/null +++ b/src/utils/trim.h @@ -0,0 +1,53 @@ +/* + * The Mana World + * Copyright 2007 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$ + */ + +#ifndef _TMW_UTILS_TRIM_H_ +#define _TMW_UTILS_TRIM_H_ + +#include + +/** + * Trims spaces off the end and the beginning of the given string. + * + * @param str the string to trim spaces off + */ +static void trim(std::string &str) +{ + std::string::size_type pos = str.find_last_not_of(' '); + if (pos != std::string::npos) + { + str.erase(pos + 1); + pos = str.find_first_not_of(' '); + if (pos != std::string::npos) + { + str.erase(0, pos); + } + } + else + { + // There is nothing else but whitespace in the string + str.clear(); + } +} + +#endif diff --git a/src/vector.h b/src/vector.h new file mode 100644 index 00000000..7a5da241 --- /dev/null +++ b/src/vector.h @@ -0,0 +1,134 @@ +/* + * The Mana World + * Copyright 2007 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$ + */ + +#ifndef _TMW_VECTOR_H_ +#define _TMW_VECTOR_H_ + +/** + * Vector class. Represents either a 3D point in space, a velocity or a force. + * Provides several convenient operator overloads. + */ +class Vector +{ + public: + /** + * Constructor. + */ + Vector(): + x(0.0f), + y(0.0f), + z(0.0f) + {} + + /** + * Constructor. + */ + Vector(float x, float y, float z): + x(x), + y(y), + z(z) + {} + + /** + * Copy constructor. + */ + Vector(const Vector &v): + x(v.x), + y(v.y), + z(v.z) + {} + + /** + * Scale vector operator. + */ + Vector operator*(float c) const + { + return Vector(x * c, + y * c, + z * c); + } + + /** + * In-place scale vector operator. + */ + void operator*=(float c) + { + x *= c; + y *= c; + z *= c; + } + + /** + * Scale vector operator. + */ + Vector operator/(float c) const + { + return Vector(x / c, + y / c, + z / c); + } + + /** + * Add vector operator. + */ + Vector operator+(const Vector &v) const + { + return Vector(x + v.x, + y + v.y, + z + v.z); + } + + /** + * In-place add vector operator. + */ + void operator+=(const Vector &v) + { + x += v.x; + y += v.y; + z += v.z; + } + + /** + * Substract vector operator. + */ + Vector operator-(const Vector &v) const + { + return Vector(x - v.x, + y - v.y, + z - v.z); + } + + /** + * In-place substract vector operator. + */ + void operator-=(const Vector &v) + { + x -= v.x; + y -= v.y; + z -= v.z; + } + + float x, y, z; +}; + +#endif diff --git a/tools/adler32.c b/tools/adler32.c new file mode 100644 index 00000000..4e851713 --- /dev/null +++ b/tools/adler32.c @@ -0,0 +1,67 @@ +/* + * adler32.c (c) 2006 Bjorn Lindeijer + * License: GPL, v2 or later + * + * Calculates Adler-32 checksums for all files passed as argument. + * + * Usage: adler32 [file]... + */ + +#include +#include + +/** + * Calculates the Adler-32 checksum for the given file. + */ +unsigned long fadler32(FILE *file) +{ + // Obtain file size + fseek(file, 0, SEEK_END); + long fileSize = ftell(file); + rewind(file); + + // Calculate Adler-32 checksum + char *buffer = (char*) malloc(fileSize); + fread(buffer, 1, fileSize, file); + unsigned long adler = adler32(0L, Z_NULL, 0); + adler = adler32(adler, (Bytef*) buffer, fileSize); + free(buffer); + + return adler; +} + +/** + * Prints out usage and exists. + */ +void print_usage() +{ + printf("Usage: adler32 [file]...\n"); + exit(0); +} + +int main(int argc, char *argv[]) +{ + int i; /**< Loops through arguments. */ + + if (argc == 1) + { + print_usage(); + } + + for (i = 1; i < argc; ++i) + { + FILE *file = fopen(argv[i], "r"); + + if (!file) + { + printf("Error while opening '%s' for reading!\n", argv[i]); + exit(1); + } + + unsigned long adler = fadler32(file); + printf("%s %lx\n", argv[i], adler); + fclose(file); + } + + return 0; +} -- cgit v1.2.3-70-g09d2 From 9cfafa755012bfd68c661996ddaea76e2e265f81 Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Thu, 20 Sep 2007 20:31:24 +0000 Subject: Fixed some compilation warning. --- ChangeLog | 8 ++++++++ src/gui/browserbox.cpp | 4 ++-- src/gui/windowlistener.h | 4 ++-- src/net/chathandler.cpp | 1 - src/particle.cpp | 2 ++ src/particle.h | 3 +-- src/utils/trim.h | 2 +- 7 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index d0e43d40..83d447bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-09-20 Guillaume Melquiond + + * src/gui/browserbox.cpp: Fixed missing const qualifier. + * src/gui/windowlistener.h: Reduced warning about unused parameter. + * src/particle.h, src/particle.cpp: Moved function out of header file. + * src/net/chathandler.cpp: Removed useless include. + * src/utils/trim.h: Fixed storage qualifier. + 2007-09-16 Guillaume Melquiond * src/gui/button.cpp: Fixed improper const qualifier. diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp index c618fa69..717342de 100644 --- a/src/gui/browserbox.cpp +++ b/src/gui/browserbox.cpp @@ -140,7 +140,7 @@ void BrowserBox::addRow(const std::string &row) { unsigned int i, j, y = 0; unsigned int nextChar; - char *hyphen = "~"; + char const *hyphen = "~"; int hyphenWidth = font->getWidth(hyphen); int x = 0; for (i = 0; i < mTextRows.size(); i++) @@ -362,7 +362,7 @@ BrowserBox::draw(gcn::Graphics *graphics) if (mMode == AUTO_WRAP) { unsigned int nextChar = j + 1; - char *hyphen = "~"; + char const *hyphen = "~"; int hyphenWidth = font->getWidth(hyphen); // Wraping between words (at blank spaces) diff --git a/src/gui/windowlistener.h b/src/gui/windowlistener.h index 08aab71d..24f6a7b8 100644 --- a/src/gui/windowlistener.h +++ b/src/gui/windowlistener.h @@ -73,12 +73,12 @@ class WindowListener /** * Called whenever the window is moved. */ - virtual void windowMoved(const WindowEvent &event) {} + virtual void windowMoved(const WindowEvent &) {} /** * Called whenever the window is resized. */ - virtual void windowResized(const WindowEvent &event) {} + virtual void windowResized(const WindowEvent &) {} }; typedef std::list WindowListeners; diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index afdc2ab5..713b8f22 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -37,7 +37,6 @@ #include "../gui/chat.h" #include "../utils/tostring.h" -#include "../utils/trim.h" extern Being *player_node; diff --git a/src/particle.cpp b/src/particle.cpp index 148bbf6f..cdd6af41 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -81,6 +81,8 @@ Particle::setupEngine() logger->log("Particle engine set up"); } +void Particle::draw(Graphics *, int, int) const {} + bool Particle::update() { diff --git a/src/particle.h b/src/particle.h index dd7c5ee2..045ab9b9 100644 --- a/src/particle.h +++ b/src/particle.h @@ -89,8 +89,7 @@ class Particle : public Sprite /** * Draws the particle image. */ - virtual void - draw(Graphics *graphics, int offsetX, int offsetY) const {} + virtual void draw(Graphics *graphics, int offsetX, int offsetY) const; /** * Necessary for sorting with the other sprites. diff --git a/src/utils/trim.h b/src/utils/trim.h index 1b5311e6..fec99100 100644 --- a/src/utils/trim.h +++ b/src/utils/trim.h @@ -31,7 +31,7 @@ * * @param str the string to trim spaces off */ -static void trim(std::string &str) +inline void trim(std::string &str) { std::string::size_type pos = str.find_last_not_of(' '); if (pos != std::string::npos) -- cgit v1.2.3-70-g09d2 From a5e6a44b51d4269ed6812c9a9e0b6a293d959a4d Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Wed, 21 Nov 2007 16:30:11 +0000 Subject: Renamed {read,write}{Byte,Short,Long} to {read,write}{Int8,Int16,Int32}. This is less confusing in 64-bit context and less conflicting with the 0.0 client. --- ChangeLog | 15 +++ src/localplayer.cpp | 4 +- src/net/accountserver/account.cpp | 24 ++-- src/net/accountserver/accountserver.cpp | 4 +- src/net/beinghandler.cpp | 196 ++++++++++++++++---------------- src/net/buysellhandler.cpp | 16 +-- src/net/charserverhandler.cpp | 22 ++-- src/net/chathandler.cpp | 28 ++--- src/net/chatserver/chatserver.cpp | 8 +- src/net/gameserver/gameserver.cpp | 2 +- src/net/gameserver/player.cpp | 46 ++++---- src/net/inventoryhandler.cpp | 8 +- src/net/itemhandler.cpp | 6 +- src/net/loginhandler.cpp | 6 +- src/net/logouthandler.cpp | 8 +- src/net/messagein.cpp | 10 +- src/net/messagein.h | 6 +- src/net/messageout.cpp | 10 +- src/net/messageout.h | 6 +- src/net/npchandler.cpp | 2 +- src/net/playerhandler.cpp | 14 +-- src/net/skillhandler.cpp | 26 ++--- src/net/tradehandler.cpp | 8 +- src/npc.cpp | 8 +- 24 files changed, 249 insertions(+), 234 deletions(-) (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index f37db10b..a0c9aefe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,21 @@ * src/properties.h, src/net/charserverhandler.cpp, src/being.h: Small lingering changes made while merging to 0.0. + * src/localplayer.cpp, src/npc.cpp, + src/net/accountserver/accountserver.cpp, + src/net/accountserver/account.cpp, src/net/loginhandler.cpp, + src/net/messageout.cpp, src/net/buysellhandler.cpp, + src/net/messagein.h, src/net/beinghandler.cpp, + src/net/inventoryhandler.cpp, src/net/itemhandler.cpp, + src/net/tradehandler.cpp, src/net/charserverhandler.cpp, + src/net/logouthandler.cpp, src/net/messagein.cpp, + src/net/skillhandler.cpp, src/net/chathandler.cpp, + src/net/npchandler.cpp, src/net/gameserver/gameserver.cpp, + src/net/gameserver/player.cpp, src/net/messageout.h, + src/net/chatserver/chatserver.cpp, src/net/playerhandler.cpp: Renamed + {read,write}{Byte,Short,Long} to {read,write}{Int8,Int16,Int32}. This + is less confusing in 64-bit context and less conflicting with the 0.0 + client. 2007-11-21 Guillaume Melquiond diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 059bd0f4..d01b613e 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -286,7 +286,7 @@ void LocalPlayer::emote(Uint8 emotion) // XXX Convert for new server /* MessageOut outMsg(0x00bf); - outMsg.writeByte(emotion); + outMsg.writeInt8(emotion); */ } @@ -340,7 +340,7 @@ void LocalPlayer::revive() // XXX Convert for new server /* MessageOut outMsg(0x00b2); - outMsg.writeByte(0); + outMsg.writeInt8(0); */ } diff --git a/src/net/accountserver/account.cpp b/src/net/accountserver/account.cpp index a90f75b8..f0778b1d 100644 --- a/src/net/accountserver/account.cpp +++ b/src/net/accountserver/account.cpp @@ -37,16 +37,16 @@ void Net::AccountServer::Account::createCharacter( MessageOut msg(PAMSG_CHAR_CREATE); msg.writeString(name); - msg.writeByte(hairStyle); - msg.writeByte(hairColor); - msg.writeByte(gender); - msg.writeShort(strength); - msg.writeShort(agility); - msg.writeShort(vitality); - msg.writeShort(intelligence); - msg.writeShort(dexterity); - msg.writeShort(willpower); - msg.writeShort(charisma); + msg.writeInt8(hairStyle); + msg.writeInt8(hairColor); + msg.writeInt8(gender); + msg.writeInt16(strength); + msg.writeInt16(agility); + msg.writeInt16(vitality); + msg.writeInt16(intelligence); + msg.writeInt16(dexterity); + msg.writeInt16(willpower); + msg.writeInt16(charisma); Net::AccountServer::connection->send(msg); } @@ -55,7 +55,7 @@ void Net::AccountServer::Account::deleteCharacter(char slot) { MessageOut msg(PAMSG_CHAR_DELETE); - msg.writeByte(slot); + msg.writeInt8(slot); Net::AccountServer::connection->send(msg); } @@ -64,7 +64,7 @@ void Net::AccountServer::Account::selectCharacter(char slot) { MessageOut msg(PAMSG_CHAR_SELECT); - msg.writeByte(slot); + msg.writeInt8(slot); Net::AccountServer::connection->send(msg); } diff --git a/src/net/accountserver/accountserver.cpp b/src/net/accountserver/accountserver.cpp index 92d803e6..651758a6 100644 --- a/src/net/accountserver/accountserver.cpp +++ b/src/net/accountserver/accountserver.cpp @@ -36,7 +36,7 @@ void Net::AccountServer::login(Net::Connection *connection, int version, MessageOut msg(PAMSG_LOGIN); - msg.writeLong(version); + msg.writeInt32(version); msg.writeString(username); msg.writeString(password); @@ -51,7 +51,7 @@ void Net::AccountServer::registerAccount(Net::Connection *connection, MessageOut msg(PAMSG_REGISTER); - msg.writeLong(version); // client version + msg.writeInt32(version); // client version msg.writeString(username); msg.writeString(password); msg.writeString(email); diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp index 56ec0192..a9f992af 100644 --- a/src/net/beinghandler.cpp +++ b/src/net/beinghandler.cpp @@ -105,12 +105,12 @@ void BeingHandler::handleMessage(MessageIn &msg) case SMSG_BEING_VISIBLE: case SMSG_BEING_MOVE: // Information about a being in range - id = msg.readLong(); - speed = msg.readShort(); - msg.readShort(); // unknown - msg.readShort(); // unknown - msg.readShort(); // option - job = msg.readShort(); // class + id = msg.readInt32(); + speed = msg.readInt16(); + msg.readInt16(); // unknown + msg.readInt16(); // unknown + msg.readInt16(); // option + job = msg.readInt16(); // class dstBeing = beingManager->findBeing(id); @@ -138,32 +138,32 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing->setWalkSpeed(speed); dstBeing->mJob = job; - dstBeing->setHairStyle(msg->readShort()); + dstBeing->setHairStyle(msg->readInt16()); dstBeing->setVisibleEquipment( - Being::WEAPON_SPRITE, msg->readShort()); + Being::WEAPON_SPRITE, msg->readInt16()); dstBeing->setVisibleEquipment( - Being::BOTTOMCLOTHES_SPRITE, msg->readShort()); + Being::BOTTOMCLOTHES_SPRITE, msg->readInt16()); if (msg.getId() == SMSG_BEING_MOVE) { - msg.readLong(); // server tick + msg.readInt32(); // server tick } - msg->readShort(); // shield - headTop = msg->readShort(); - headMid = msg->readShort(); + msg->readInt16(); // shield + headTop = msg->readInt16(); + headMid = msg->readInt16(); dstBeing->setVisibleEquipment(Being::HAT_SPRITE, headTop); dstBeing->setVisibleEquipment(Being::TOPCLOTHES_SPRITE, headMid); - dstBeing->setHairColor(msg->readShort()); - msg->readShort(); // unknown - msg->readShort(); // head dir - msg->readShort(); // guild - msg->readShort(); // unknown - msg->readShort(); // unknown - msg->readShort(); // manner - msg->readShort(); // karma - msg->readByte(); // unknown - dstBeing->setSex(1 - msg->readByte()); // sex + dstBeing->setHairColor(msg->readInt16()); + msg->readInt16(); // unknown + msg->readInt16(); // head dir + msg->readInt16(); // guild + msg->readInt16(); // unknown + msg->readInt16(); // unknown + msg->readInt16(); // manner + msg->readInt16(); // karma + msg->readInt8(); // unknown + dstBeing->setSex(1 - msg->readInt8()); // sex if (msg.getId() == SMSG_BEING_MOVE) { @@ -181,19 +181,19 @@ void BeingHandler::handleMessage(MessageIn &msg) //dstBeing->setDirection(dir); } - msg.readByte(); // unknown - msg.readByte(); // unknown - msg.readByte(); // unknown / sit + msg.readInt8(); // unknown + msg.readInt8(); // unknown + msg.readInt8(); // unknown / sit break; case SMSG_BEING_REMOVE: // A being should be removed or has died - dstBeing = beingManager->findBeing(msg.readLong()); + dstBeing = beingManager->findBeing(msg.readInt32()); if (!dstBeing) break; - if (msg.readByte() == 1) + if (msg.readInt8() == 1) { dstBeing->setAction(Being::DEAD); } @@ -209,15 +209,15 @@ void BeingHandler::handleMessage(MessageIn &msg) break; case SMSG_BEING_ACTION: - srcBeing = beingManager->findBeing(msg.readLong()); - dstBeing = beingManager->findBeing(msg.readLong()); - msg.readLong(); // server tick - msg.readLong(); // src speed - msg.readLong(); // dst speed - param1 = msg.readShort(); - msg.readShort(); // param 2 - type = msg.readByte(); - msg.readShort(); // param 3 + srcBeing = beingManager->findBeing(msg.readInt32()); + dstBeing = beingManager->findBeing(msg.readInt32()); + msg.readInt32(); // server tick + msg.readInt32(); // src speed + msg.readInt32(); // dst speed + param1 = msg.readInt16(); + msg.readInt16(); // param 2 + type = msg.readInt8(); + msg.readInt16(); // param 3 switch (type) { @@ -247,7 +247,7 @@ void BeingHandler::handleMessage(MessageIn &msg) break; case SMSG_BEING_LEVELUP: - id = (Uint32) msg->readLong(); + id = (Uint32) msg->readInt32(); if (id == player_node->getId()) { logger->log("Level up"); @@ -257,7 +257,7 @@ void BeingHandler::handleMessage(MessageIn &msg) logger->log("Someone else went level up"); } Particle *levelupFX; - if (msg->readLong() == 0) { // type + if (msg->readInt32() == 0) { // type levelupFX = particleEngine->addEffect( "graphics/particles/levelup.particle.xml", 0, 0); } @@ -269,24 +269,24 @@ void BeingHandler::handleMessage(MessageIn &msg) break; case SMSG_BEING_EMOTION: - if (!(dstBeing = beingManager->findBeing(msg.readLong()))) + if (!(dstBeing = beingManager->findBeing(msg.readInt32()))) { break; } - dstBeing->mEmotion = msg.readByte(); + dstBeing->mEmotion = msg.readInt8(); dstBeing->mEmotionTime = EMOTION_TIME; break; case SMSG_BEING_CHANGE_LOOKS: { - if (!(dstBeing = beingManager->findBeing(msg.readLong()))) + if (!(dstBeing = beingManager->findBeing(msg.readInt32()))) { break; } - int type = msg.readByte(); - int id = msg.readByte(); + int type = msg.readInt8(); + int id = msg.readInt8(); switch (type) { case 1: @@ -319,7 +319,7 @@ void BeingHandler::handleMessage(MessageIn &msg) break; case SMSG_BEING_NAME_RESPONSE: - if ((dstBeing = beingManager->findBeing(msg.readLong()))) + if ((dstBeing = beingManager->findBeing(msg.readInt32()))) { dstBeing->setName(msg.readString(24)); } @@ -329,12 +329,12 @@ void BeingHandler::handleMessage(MessageIn &msg) case SMSG_PLAYER_UPDATE_2: case SMSG_PLAYER_MOVE: // An update about a player, potentially including movement. - id = msg.readLong(); - speed = msg.readShort(); - msg.readShort(); // option 1 - msg.readShort(); // option 2 - msg.readShort(); // option - job = msg.readShort(); + id = msg.readInt32(); + speed = msg.readInt16(); + msg.readInt16(); // option 1 + msg.readInt16(); // option 2 + msg.readInt16(); // option + job = msg.readInt16(); dstBeing = beingManager->findBeing(id); @@ -345,27 +345,27 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing->setWalkSpeed(speed); dstBeing->mJob = job; - dstBeing->setHairStyle(msg->readShort()); + dstBeing->setHairStyle(msg->readInt16()); dstBeing->setVisibleEquipment( - Being::WEAPON_SPRITE, msg->readShort()); - msg->readShort(); // item id 2 - headBottom = msg->readShort(); + Being::WEAPON_SPRITE, msg->readInt16()); + msg->readInt16(); // item id 2 + headBottom = msg->readInt16(); if (msg.getId() == SMSG_PLAYER_MOVE) { - msg.readLong(); // server tick + msg.readInt32(); // server tick } - headTop = msg.readShort(); - headMid = msg.readShort(); - dstBeing->setHairColor(msg.readShort()); - msg.readShort(); // unknown - msg.readShort(); // head dir - msg.readLong(); // guild - msg.readLong(); // emblem - msg.readShort(); // manner - msg.readByte(); // karma - dstBeing->setSex(1 - msg.readByte()); // sex + headTop = msg.readInt16(); + headMid = msg.readInt16(); + dstBeing->setHairColor(msg.readInt16()); + msg.readInt16(); // unknown + msg.readInt16(); // head dir + msg.readInt32(); // guild + msg.readInt32(); // emblem + msg.readInt16(); // manner + msg.readInt8(); // karma + dstBeing->setSex(1 - msg.readInt8()); // sex dstBeing->setVisibleEquipment( Being::BOTTOMCLOTHES_SPRITE, headBottom); dstBeing->setVisibleEquipment(Being::HAT_SPRITE, headTop); @@ -386,23 +386,23 @@ void BeingHandler::handleMessage(MessageIn &msg) //dstBeing->setDirection(dir); } - msg.readByte(); // unknown - msg.readByte(); // unknown + msg.readInt8(); // unknown + msg.readInt8(); // unknown if (msg.getId() == SMSG_PLAYER_UPDATE_1) { - if (msg.readByte() == 2) + if (msg.readInt8() == 2) { dstBeing->setAction(Being::SIT); } } else if (msg.getId() == SMSG_PLAYER_MOVE) { - msg.readByte(); // unknown + msg.readInt8(); // unknown } - msg.readByte(); // Lv - msg.readByte(); // unknown + msg.readInt8(); // Lv + msg.readInt8(); // unknown dstBeing->mWalkTime = tick_time; dstBeing->mFrame = 0; @@ -410,9 +410,9 @@ void BeingHandler::handleMessage(MessageIn &msg) case 0x0119: // Change in players look - logger->log("0x0119 %i %i %i %x %i", msg->readLong(), - msg->readShort(), msg->readShort(), msg->readShort(), - msg->readByte()); + logger->log("0x0119 %i %i %i %x %i", msg->readInt32(), + msg->readInt16(), msg->readInt16(), msg->readInt16(), + msg->readInt8()); break; */ } @@ -426,7 +426,7 @@ static void handleLooks(Player *being, MessageIn &msg) { Being::WEAPON_SPRITE, Being::HAT_SPRITE, Being::TOPCLOTHES_SPRITE, Being::BOTTOMCLOTHES_SPRITE }; - int mask = msg.readByte(); + int mask = msg.readInt8(); if (mask & (1 << 7)) { @@ -441,7 +441,7 @@ static void handleLooks(Player *being, MessageIn &msg) for (int i = 0; i < nb_slots; ++i) { if (!(mask & (1 << i))) continue; - int id = msg.readShort(); + int id = msg.readInt16(); being->setVisibleEquipment(slots[i], id); } } @@ -449,11 +449,11 @@ static void handleLooks(Player *being, MessageIn &msg) void BeingHandler::handleBeingEnterMessage(MessageIn &msg) { - int type = msg.readByte(); - int id = msg.readShort(); - Being::Action action = (Being::Action)msg.readByte(); - int px = msg.readShort(); - int py = msg.readShort(); + int type = msg.readInt8(); + int id = msg.readInt16(); + Being::Action action = (Being::Action)msg.readInt8(); + int px = msg.readInt16(); + int py = msg.readInt16(); Being *being; switch (type) @@ -472,16 +472,16 @@ BeingHandler::handleBeingEnterMessage(MessageIn &msg) being->setName(name); } Player *p = static_cast< Player * >(being); - int hs = msg.readByte(), hc = msg.readByte(); + int hs = msg.readInt8(), hc = msg.readInt8(); p->setHairStyle(hs, hc); - p->setGender(msg.readByte()); + p->setGender(msg.readInt8()); handleLooks(p, msg); } break; case OBJECT_MONSTER: case OBJECT_NPC: { - int subtype = msg.readShort(); + int subtype = msg.readInt16(); being = beingManager->createBeing(id, type, subtype); } break; @@ -497,7 +497,7 @@ BeingHandler::handleBeingEnterMessage(MessageIn &msg) void BeingHandler::handleBeingLeaveMessage(MessageIn &msg) { - Being *being = beingManager->findBeing(msg.readShort()); + Being *being = beingManager->findBeing(msg.readInt16()); if (!being) return; beingManager->destroyBeing(being); @@ -507,8 +507,8 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg) { while (msg.getUnreadLength()) { - int id = msg.readShort(); - int flags = msg.readByte(); + int id = msg.readInt16(); + int flags = msg.readInt8(); Being *being = beingManager->findBeing(id); int sx = 0, sy = 0, dx = 0, dy = 0, speed = 0; if (flags & MOVING_POSITION) @@ -517,12 +517,12 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg) msg.readCoordinates(sx2, sy2); sx = sx2 * 32 + 16; sy = sy2 * 32 + 16; - speed = msg.readByte(); + speed = msg.readInt8(); } if (flags & MOVING_DESTINATION) { - dx = msg.readShort(); - dy = msg.readShort(); + dx = msg.readInt16(); + dy = msg.readInt16(); if (!(flags & MOVING_POSITION)) { sx = dx; @@ -561,19 +561,19 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg) void BeingHandler::handleBeingAttackMessage(MessageIn &msg) { - Being *being = beingManager->findBeing(msg.readShort()); + Being *being = beingManager->findBeing(msg.readInt16()); if (!being) return; being->setAction(Being::ATTACK); - being->setDirection(msg.readByte()); + being->setDirection(msg.readInt8()); } void BeingHandler::handleBeingsDamageMessage(MessageIn &msg) { while (msg.getUnreadLength()) { - Being *being = beingManager->findBeing(msg.readShort()); - int damage = msg.readShort(); + Being *being = beingManager->findBeing(msg.readInt16()); + int damage = msg.readInt16(); if (being) { being->takeDamage(damage); @@ -583,15 +583,15 @@ void BeingHandler::handleBeingsDamageMessage(MessageIn &msg) void BeingHandler::handleBeingActionChangeMessage(MessageIn &msg) { - Being* being = beingManager->findBeing(msg.readShort()); + Being* being = beingManager->findBeing(msg.readInt16()); if (!being) return; - being->setAction((Being::Action) msg.readByte()); + being->setAction((Being::Action) msg.readInt8()); } void BeingHandler::handleBeingLooksChangeMessage(MessageIn &msg) { - Being *being = beingManager->findBeing(msg.readShort()); + Being *being = beingManager->findBeing(msg.readInt16()); if (!being || being->getType() != Being::PLAYER) return; handleLooks(static_cast< Player * >(being), msg); } diff --git a/src/net/buysellhandler.cpp b/src/net/buysellhandler.cpp index 9b96ced7..57806edc 100644 --- a/src/net/buysellhandler.cpp +++ b/src/net/buysellhandler.cpp @@ -53,7 +53,7 @@ BuySellHandler::BuySellHandler() void BuySellHandler::handleMessage(MessageIn &msg) { - Being *being = beingManager->findBeing(msg.readShort()); + Being *being = beingManager->findBeing(msg.readInt16()); if (!being || being->getType() != Being::NPC) { return; @@ -70,7 +70,7 @@ void BuySellHandler::handleMessage(MessageIn &msg) sellDialog->setVisible(false); sellDialog->reset(); buySellDialog->setVisible(true); - current_npc = dynamic_cast(beingManager->findBeing(msg.readLong())); + current_npc = dynamic_cast(beingManager->findBeing(msg.readInt32())); break; #endif @@ -81,9 +81,9 @@ void BuySellHandler::handleMessage(MessageIn &msg) while (msg.getUnreadLength()) { - int itemId = msg.readShort(); - int amount = msg.readShort(); - int value = msg.readShort(); + int itemId = msg.readInt16(); + int amount = msg.readInt16(); + int value = msg.readInt16(); buyDialog->addItem(itemId, amount, value); } break; @@ -95,9 +95,9 @@ void BuySellHandler::handleMessage(MessageIn &msg) while (msg.getUnreadLength()) { - int itemId = msg.readShort(); - int amount = msg.readShort(); - int value = msg.readShort(); + int itemId = msg.readInt16(); + int amount = msg.readInt16(); + int value = msg.readInt16(); sellDialog->addItem(itemId, amount, value); } break; diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp index 0082db4c..bbfa82a4 100644 --- a/src/net/charserverhandler.cpp +++ b/src/net/charserverhandler.cpp @@ -65,7 +65,7 @@ void CharServerHandler::handleMessage(MessageIn &msg) case APMSG_CHAR_DELETE_RESPONSE: { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Character deletion successful if (errMsg == ERRMSG_OK) { @@ -117,7 +117,7 @@ void CharServerHandler::handleMessage(MessageIn &msg) void CharServerHandler::handleCharCreateResponse(MessageIn &msg) { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Character creation failed if (errMsg != ERRMSG_OK) @@ -168,15 +168,15 @@ void CharServerHandler::handleCharCreateResponse(MessageIn &msg) void CharServerHandler::handleCharSelectResponse(MessageIn &msg) { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); if (errMsg == ERRMSG_OK) { token = msg.readString(32); std::string gameServer = msg.readString(); - unsigned short gameServerPort = msg.readShort(); + unsigned short gameServerPort = msg.readInt16(); std::string chatServer = msg.readString(); - unsigned short chatServerPort = msg.readShort(); + unsigned short chatServerPort = msg.readInt16(); logger->log("Game server: %s:%d", gameServer.c_str(), gameServerPort); logger->log("Chat server: %s:%d", chatServer.c_str(), chatServerPort); @@ -210,17 +210,17 @@ void CharServerHandler::handleCharSelectResponse(MessageIn &msg) LocalPlayer* CharServerHandler::readPlayerData(MessageIn &msg, int &slot) { LocalPlayer *tempPlayer = new LocalPlayer; - slot = msg.readByte(); // character slot + slot = msg.readInt8(); // character slot tempPlayer->mName = msg.readString(); - tempPlayer->setGender(msg.readByte()); - int hs = msg.readByte(), hc = msg.readByte(); + tempPlayer->setGender(msg.readInt8()); + int hs = msg.readInt8(), hc = msg.readInt8(); tempPlayer->setHairStyle(hs, hc); - tempPlayer->setLevel(msg.readByte()); - tempPlayer->setMoney(msg.readLong()); + tempPlayer->setLevel(msg.readInt8()); + tempPlayer->setMoney(msg.readInt32()); for (int i = 0; i < 7; i++) { - tempPlayer->setAttributeBase(i, msg.readByte()); + tempPlayer->setAttributeBase(i, msg.readInt8()); } return tempPlayer; diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index 713b8f22..9fe231e6 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -73,7 +73,7 @@ void ChatHandler::handleMessage(MessageIn &msg) switch (msg.getId()) { case GPMSG_SAY: - being = beingManager->findBeing(msg.readShort()); + being = beingManager->findBeing(msg.readInt16()); chatMsg = msg.readString(); if (being) { @@ -86,9 +86,9 @@ void ChatHandler::handleMessage(MessageIn &msg) } break; case CPMSG_REGISTER_CHANNEL_RESPONSE: - if(msg.readByte() == ERRMSG_OK) + if(msg.readInt8() == ERRMSG_OK) { - channelId = msg.readShort(); + channelId = msg.readInt16(); std::string channelName = msg.readString(); chatWindow->chatLog("Registered Channel " + channelName, BY_SERVER); chatWindow->addChannel(channelId, channelName); @@ -100,9 +100,9 @@ void ChatHandler::handleMessage(MessageIn &msg) } break; case CPMSG_ENTER_CHANNEL_RESPONSE: - if(msg.readByte() == ERRMSG_OK) + if(msg.readInt8() == ERRMSG_OK) { - channelId = msg.readShort(); + channelId = msg.readInt16(); channelName = msg.readString(); std::string announcement = msg.readString(); std::vector userList; @@ -126,7 +126,7 @@ void ChatHandler::handleMessage(MessageIn &msg) { channelName = msg.readString(); std::ostringstream numUsers; - numUsers << msg.readShort(); + numUsers << msg.readInt16(); if(channelName != "") { channelName += " - "; @@ -138,7 +138,7 @@ void ChatHandler::handleMessage(MessageIn &msg) break; case CPMSG_PUBMSG: - channelId = msg.readShort(); + channelId = msg.readInt16(); userNick = msg.readString(); chatMsg = msg.readString(); @@ -146,9 +146,9 @@ void ChatHandler::handleMessage(MessageIn &msg) break; case CPMSG_QUIT_CHANNEL_RESPONSE: - if(msg.readByte() == ERRMSG_OK) + if(msg.readInt8() == ERRMSG_OK) { - channelId = msg.readShort(); + channelId = msg.readInt16(); // remove the chat tab chatWindow->removeChannel(channelId); } @@ -156,8 +156,8 @@ void ChatHandler::handleMessage(MessageIn &msg) /* // Received speech from being case SMSG_BEING_CHAT: - chatMsgLength = msg.readShort() - 8; - being = beingManager->findBeing(msg.readLong()); + chatMsgLength = msg.readInt16() - 8; + being = beingManager->findBeing(msg.readInt32()); if (!being || chatMsgLength <= 0) { @@ -173,7 +173,7 @@ void ChatHandler::handleMessage(MessageIn &msg) case SMSG_PLAYER_CHAT: case SMSG_GM_CHAT: - chatMsgLength = msg.readShort() - 4; + chatMsgLength = msg.readInt16() - 4; if (chatMsgLength <= 0) { @@ -200,13 +200,13 @@ void ChatHandler::handleMessage(MessageIn &msg) break; case SMSG_WHO_ANSWER: - chatWindow->chatLog("Online users: " + toString(msg.readLong()), + chatWindow->chatLog("Online users: " + toString(msg.readInt32()), BY_SERVER); break; case 0x010c: // Display MVP player - msg.readLong(); // id + msg.readInt32(); // id chatWindow->chatLog("MVP player", BY_SERVER); break; */ diff --git a/src/net/chatserver/chatserver.cpp b/src/net/chatserver/chatserver.cpp index f24e4cd5..93fdc828 100644 --- a/src/net/chatserver/chatserver.cpp +++ b/src/net/chatserver/chatserver.cpp @@ -55,7 +55,7 @@ void Net::ChatServer::chat(short channel, const std::string &text) MessageOut msg(PCMSG_CHAT); msg.writeString(text); - msg.writeShort(channel); + msg.writeInt16(channel); connection->send(msg); } @@ -86,7 +86,7 @@ void Net::ChatServer::registerChannel(const std::string &name, { MessageOut msg(PCMSG_REGISTER_CHANNEL); - msg.writeByte(isPrivate); + msg.writeInt8(isPrivate); msg.writeString(name); msg.writeString(announcement); msg.writeString(password); @@ -98,7 +98,7 @@ void Net::ChatServer::unregisterChannel(short channel) { MessageOut msg(PCMSG_UNREGISTER_CHANNEL); - msg.writeShort(channel); + msg.writeInt16(channel); connection->send(msg); } @@ -117,7 +117,7 @@ void Net::ChatServer::quitChannel(short channel) { MessageOut msg(PCMSG_QUIT_CHANNEL); - msg.writeShort(channel); + msg.writeInt16(channel); connection->send(msg); } diff --git a/src/net/gameserver/gameserver.cpp b/src/net/gameserver/gameserver.cpp index 8f8ad8ac..e451d473 100644 --- a/src/net/gameserver/gameserver.cpp +++ b/src/net/gameserver/gameserver.cpp @@ -45,7 +45,7 @@ void Net::GameServer::logout(bool reconnectAccount) { MessageOut msg(PGMSG_DISCONNECT); - msg.writeByte((unsigned char) reconnectAccount); + msg.writeInt8((unsigned char) reconnectAccount); Net::GameServer::connection->send(msg); } diff --git a/src/net/gameserver/player.cpp b/src/net/gameserver/player.cpp index 95f7dff9..bb3567d3 100644 --- a/src/net/gameserver/player.cpp +++ b/src/net/gameserver/player.cpp @@ -39,90 +39,90 @@ void Net::GameServer::Player::say(const std::string &text) void Net::GameServer::Player::walk(int x, int y) { MessageOut msg(PGMSG_WALK); - msg.writeShort(x); - msg.writeShort(y); + msg.writeInt16(x); + msg.writeInt16(y); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::pickUp(int x, int y) { MessageOut msg(PGMSG_PICKUP); - msg.writeShort(x); - msg.writeShort(y); + msg.writeInt16(x); + msg.writeInt16(y); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::moveItem(int oldSlot, int newSlot, int amount) { MessageOut msg(PGMSG_MOVE_ITEM); - msg.writeByte(oldSlot); - msg.writeByte(newSlot); - msg.writeByte(amount); + msg.writeInt8(oldSlot); + msg.writeInt8(newSlot); + msg.writeInt8(amount); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::drop(int slot, int amount) { MessageOut msg(PGMSG_DROP); - msg.writeByte(slot); - msg.writeByte(amount); + msg.writeInt8(slot); + msg.writeInt8(amount); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::equip(int slot) { MessageOut msg(PGMSG_EQUIP); - msg.writeByte(slot); + msg.writeInt8(slot); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::unequip(int slot) { MessageOut msg(PGMSG_UNEQUIP); - msg.writeByte(slot); + msg.writeInt8(slot); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::useItem(int slot) { MessageOut msg(PGMSG_USE_ITEM); - msg.writeByte(slot); + msg.writeInt8(slot); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::attack(int direction) { MessageOut msg(PGMSG_ATTACK); - msg.writeByte(direction); + msg.writeInt8(direction); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::changeAction(Being::Action action) { MessageOut msg(PGMSG_ACTION_CHANGE); - msg.writeByte(action); + msg.writeInt8(action); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::talkToNPC(int id, bool restart) { MessageOut msg(restart ? PGMSG_NPC_TALK : PGMSG_NPC_TALK_NEXT); - msg.writeShort(id); + msg.writeInt16(id); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::selectFromNPC(int id, int choice) { MessageOut msg(PGMSG_NPC_SELECT); - msg.writeShort(id); - msg.writeByte(choice); + msg.writeInt16(id); + msg.writeInt8(choice); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::requestTrade(int id) { MessageOut msg(PGMSG_TRADE_REQUEST); - msg.writeShort(id); + msg.writeInt16(id); Net::GameServer::connection->send(msg); } @@ -135,22 +135,22 @@ void Net::GameServer::Player::acceptTrade(bool accept) void Net::GameServer::Player::tradeItem(int slot, int amount) { MessageOut msg(PGMSG_TRADE_ADD_ITEM); - msg.writeByte(slot); - msg.writeByte(amount); + msg.writeInt8(slot); + msg.writeInt8(amount); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::tradeMoney(int amount) { MessageOut msg(PGMSG_TRADE_SET_MONEY); - msg.writeLong(amount); + msg.writeInt32(amount); Net::GameServer::connection->send(msg); } void Net::GameServer::Player::tradeWithNPC(int item, int amount) { MessageOut msg(PGMSG_NPC_BUYSELL); - msg.writeShort(item); - msg.writeShort(amount); + msg.writeInt16(item); + msg.writeInt16(amount); Net::GameServer::connection->send(msg); } diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp index 6fdb827d..d48a77a5 100644 --- a/src/net/inventoryhandler.cpp +++ b/src/net/inventoryhandler.cpp @@ -58,21 +58,21 @@ void InventoryHandler::handleMessage(MessageIn &msg) case GPMSG_INVENTORY: while (msg.getUnreadLength()) { - int slot = msg.readByte(); + int slot = msg.readInt8(); if (slot == 255) { - player_node->setMoney(msg.readLong()); + player_node->setMoney(msg.readInt32()); continue; } - int id = msg.readShort(); + int id = msg.readInt16(); if (slot < EQUIPMENT_SIZE) { player_node->mEquipment->setEquipment(slot, id); } else if (slot >= 32 && slot < 32 + INVENTORY_SIZE) { - int amount = id ? msg.readByte() : 0; + int amount = id ? msg.readInt8() : 0; player_node->setInvItem(slot - 32, id, amount); } }; diff --git a/src/net/itemhandler.cpp b/src/net/itemhandler.cpp index 7c4d3940..ea65bc3b 100644 --- a/src/net/itemhandler.cpp +++ b/src/net/itemhandler.cpp @@ -48,9 +48,9 @@ void ItemHandler::handleMessage(MessageIn &msg) { while (msg.getUnreadLength()) { - int itemId = msg.readShort(); - int x = msg.readShort(); - int y = msg.readShort(); + int itemId = msg.readInt16(); + int x = msg.readInt16(); + int y = msg.readInt16(); int id = (x << 16) | y; // dummy id if (itemId) diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp index 90f2dbd5..260c117d 100644 --- a/src/net/loginhandler.cpp +++ b/src/net/loginhandler.cpp @@ -45,7 +45,7 @@ void LoginHandler::handleMessage(MessageIn &msg) { case APMSG_LOGIN_RESPONSE: { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Successful login if (errMsg == ERRMSG_OK) { @@ -77,7 +77,7 @@ void LoginHandler::handleMessage(MessageIn &msg) break; case APMSG_REGISTER_RESPONSE: { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Successful registration if (errMsg == ERRMSG_OK) { @@ -109,7 +109,7 @@ void LoginHandler::handleMessage(MessageIn &msg) break; case APMSG_RECONNECT_RESPONSE: { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Successful login if (errMsg == ERRMSG_OK) { diff --git a/src/net/logouthandler.cpp b/src/net/logouthandler.cpp index d8b9d435..c7629490 100644 --- a/src/net/logouthandler.cpp +++ b/src/net/logouthandler.cpp @@ -48,7 +48,7 @@ void LogoutHandler::handleMessage(MessageIn &msg) { case APMSG_LOGOUT_RESPONSE: { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Successful logout if (errMsg == ERRMSG_OK) @@ -86,7 +86,7 @@ void LogoutHandler::handleMessage(MessageIn &msg) break; case APMSG_UNREGISTER_RESPONSE: { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Successful unregistration if (errMsg == ERRMSG_OK) { @@ -110,7 +110,7 @@ void LogoutHandler::handleMessage(MessageIn &msg) break; case GPMSG_DISCONNECT_RESPONSE: { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Successful logout if (errMsg == ERRMSG_OK) { @@ -156,7 +156,7 @@ void LogoutHandler::handleMessage(MessageIn &msg) break; case CPMSG_DISCONNECT_RESPONSE: { - int errMsg = msg.readByte(); + int errMsg = msg.readInt8(); // Successful logout if (errMsg == ERRMSG_OK) { diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp index e90084ff..b5d5b97a 100644 --- a/src/net/messagein.cpp +++ b/src/net/messagein.cpp @@ -33,10 +33,10 @@ MessageIn::MessageIn(const char *data, unsigned int length): mPos(0) { // Read the message ID - mId = readShort(); + mId = readInt16(); } -int MessageIn::readByte() +int MessageIn::readInt8() { int value = -1; if (mPos < mLength) @@ -47,7 +47,7 @@ int MessageIn::readByte() return value; } -int MessageIn::readShort() +int MessageIn::readInt16() { int value = -1; if (mPos + 2 <= mLength) @@ -60,7 +60,7 @@ int MessageIn::readShort() return value; } -int MessageIn::readLong() +int MessageIn::readInt32() { int value = -1; if (mPos + 4 <= mLength) @@ -88,7 +88,7 @@ std::string MessageIn::readString(int length) { // Get string length if (length < 0) { - length = readShort(); + length = readInt16(); } // Make sure the string isn't erroneus diff --git a/src/net/messagein.h b/src/net/messagein.h index 37103f2c..3cc45a23 100644 --- a/src/net/messagein.h +++ b/src/net/messagein.h @@ -43,9 +43,9 @@ class MessageIn int getId() { return mId; } /**< Returns the message ID. */ - int readByte(); /**< Reads a byte. */ - int readShort(); /**< Reads a short. */ - int readLong(); /**< Reads a long. */ + int readInt8(); /**< Reads a byte. */ + int readInt16(); /**< Reads a short. */ + int readInt32(); /**< Reads a long. */ /** * Reads a 3-byte block containing tile-based coordinates. diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp index 208196e2..10f1b1d4 100644 --- a/src/net/messageout.cpp +++ b/src/net/messageout.cpp @@ -33,7 +33,7 @@ MessageOut::MessageOut(short id): mDataSize(0), mPos(0) { - writeShort(id); + writeInt16(id); } MessageOut::~MessageOut() @@ -51,14 +51,14 @@ MessageOut::expand(size_t bytes) } void -MessageOut::writeByte(char value) +MessageOut::writeInt8(char value) { expand(mPos + 1); mData[mPos] = value; mPos += 1; } -void MessageOut::writeShort(short value) +void MessageOut::writeInt16(short value) { expand(mPos + 2); uint16_t t = ENET_HOST_TO_NET_16(value); @@ -67,7 +67,7 @@ void MessageOut::writeShort(short value) } void -MessageOut::writeLong(long value) +MessageOut::writeInt32(long value) { expand(mPos + 4); uint32_t t = ENET_HOST_TO_NET_32(value); @@ -82,7 +82,7 @@ MessageOut::writeString(const std::string &string, int length) if (length < 0) { // Write the length at the start if not fixed - writeShort(stringLength); + writeInt16(stringLength); length = stringLength; } else if (length < stringLength) diff --git a/src/net/messageout.h b/src/net/messageout.h index 82412a30..032db190 100644 --- a/src/net/messageout.h +++ b/src/net/messageout.h @@ -45,9 +45,9 @@ class MessageOut */ ~MessageOut(); - void writeByte(char value); /**< Writes a byte. */ - void writeShort(short value); /**< Writes a short. */ - void writeLong(long value); /**< Writes a long. */ + void writeInt8(char value); /**< Writes a byte. */ + void writeInt16(short value); /**< Writes a short. */ + void writeInt32(long value); /**< Writes a long. */ /** * Writes a string. If a fixed length is not given (-1), it is stored diff --git a/src/net/npchandler.cpp b/src/net/npchandler.cpp index 9cc93df1..a838c844 100644 --- a/src/net/npchandler.cpp +++ b/src/net/npchandler.cpp @@ -47,7 +47,7 @@ NPCHandler::NPCHandler() void NPCHandler::handleMessage(MessageIn &msg) { - Being *being = beingManager->findBeing(msg.readShort()); + Being *being = beingManager->findBeing(msg.readInt16()); if (!being || being->getType() != Being::NPC) { return; diff --git a/src/net/playerhandler.cpp b/src/net/playerhandler.cpp index afaeca69..f6f7a8fa 100644 --- a/src/net/playerhandler.cpp +++ b/src/net/playerhandler.cpp @@ -107,7 +107,7 @@ void PlayerHandler::handleMessage(MessageIn &msg) { // TODO: Implement reconnecting to another game server std::string token = msg.readString(32); std::string address = msg.readString(); - int port = msg.readShort(); + int port = msg.readInt16(); logger->log("Changing server to %s:%d", address.c_str(), port); } break; @@ -116,9 +116,9 @@ void PlayerHandler::handleMessage(MessageIn &msg) logger->log("ATTRIBUTE UPDATE:"); while (msg.getUnreadLength()) { - int stat = msg.readByte(); - int base = msg.readShort(); - int value = msg.readShort(); + int stat = msg.readInt8(); + int base = msg.readInt16(); + int value = msg.readInt16(); logger->log("%d set to %d %d", stat, base, value); if (stat == BASE_ATTR_HP) @@ -141,7 +141,7 @@ void PlayerHandler::handleMessage(MessageIn &msg) /* case SMSG_PLAYER_ARROW_MESSAGE: { - Sint16 type = msg.readShort(); + Sint16 type = msg.readInt16(); switch (type) { case 0: @@ -162,8 +162,8 @@ void PlayerHandler::handleMapChangeMessage(MessageIn &msg) { std::string mapName = msg.readString(); - unsigned short x = msg.readShort(); - unsigned short y = msg.readShort(); + unsigned short x = msg.readInt16(); + unsigned short y = msg.readInt16(); logger->log("Changing map to %s (%d, %d)", mapName.c_str(), x, y); diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp index 50150ca8..8a19fe45 100644 --- a/src/net/skillhandler.cpp +++ b/src/net/skillhandler.cpp @@ -45,20 +45,20 @@ void SkillHandler::handleMessage(MessageIn &msg) { #if 0 case SMSG_PLAYER_SKILLS: - msg.readShort(); // length + msg.readInt16(); // length skillCount = (msg.getLength() - 4) / 37; skillDialog->cleanList(); for (int k = 0; k < skillCount; k++) { - Sint16 skillId = msg.readShort(); - msg.readShort(); // target type - msg.readShort(); // unknown - Sint16 level = msg.readShort(); - Sint16 sp = msg.readShort(); - msg.readShort(); // range + Sint16 skillId = msg.readInt16(); + msg.readInt16(); // target type + msg.readInt16(); // unknown + Sint16 level = msg.readInt16(); + Sint16 sp = msg.readInt16(); + msg.readInt16(); // range std::string skillName = msg.readString(24); - Sint8 up = msg.readByte(); + Sint8 up = msg.readInt8(); if (level != 0 || up != 0) { @@ -76,11 +76,11 @@ void SkillHandler::handleMessage(MessageIn &msg) // Action failed (ex. sit because you have not reached the // right level) CHATSKILL action; - action.skill = msg.readShort(); - action.bskill = msg.readShort(); - action.unused = msg.readShort(); // unknown - action.success = msg.readByte(); - action.reason = msg.readByte(); + action.skill = msg.readInt16(); + action.bskill = msg.readInt16(); + action.unused = msg.readInt16(); // unknown + action.success = msg.readInt8(); + action.reason = msg.readInt8(); if (action.success != SKILL_FAILED && action.bskill == BSKILL_EMOTE) { diff --git a/src/net/tradehandler.cpp b/src/net/tradehandler.cpp index db07b786..b659f8a4 100644 --- a/src/net/tradehandler.cpp +++ b/src/net/tradehandler.cpp @@ -76,7 +76,7 @@ void TradeHandler::handleMessage(MessageIn &msg) { case GPMSG_TRADE_REQUEST: { - Being *being = beingManager->findBeing(msg.readShort()); + Being *being = beingManager->findBeing(msg.readInt16()); if (!being) { Net::GameServer::Player::acceptTrade(false); @@ -92,13 +92,13 @@ void TradeHandler::handleMessage(MessageIn &msg) case GPMSG_TRADE_ADD_ITEM: { - int type = msg.readShort(); - int amount = msg.readByte(); + int type = msg.readInt16(); + int amount = msg.readInt8(); tradeWindow->addItem(type, false, amount); } break; case GPMSG_TRADE_SET_MONEY: - tradeWindow->setMoney(msg.readLong()); + tradeWindow->setMoney(msg.readInt32()); break; case GPMSG_TRADE_START: diff --git a/src/npc.cpp b/src/npc.cpp index 980f1c8b..8e0b00a5 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -85,8 +85,8 @@ NPC::buy() // XXX Convert for new server /* MessageOut outMsg(CMSG_NPC_BUY_SELL_REQUEST); - outMsg.writeLong(mId); - outMsg.writeByte(0); + outMsg.writeInt32(mId); + outMsg.writeInt8(0); */ } @@ -96,7 +96,7 @@ NPC::sell() // XXX Convert for new server /* MessageOut outMsg(CMSG_NPC_BUY_SELL_REQUEST); - outMsg.writeLong(mId); - outMsg.writeByte(1); + outMsg.writeInt32(mId); + outMsg.writeInt8(1); */ } -- cgit v1.2.3-70-g09d2 From d8214f7e46ec507dac603ea2a108410f5f64a4bd Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Wed, 20 Feb 2008 18:06:03 +0000 Subject: Merged revisions 3790,3799,3801-3807,3809-3810,3812-3813,3815-3816,3818-3821 via svnmerge from https://themanaworld.svn.sourceforge.net/svnroot/themanaworld/tmw/branches/0.0 ........ r3790 | b_lindeijer | 2007-12-18 14:54:17 +0100 (Tue, 18 Dec 2007) | 3 lines Remember to delete the progressbar and label also when the game was not started. ........ r3801 | b_lindeijer | 2007-12-21 12:56:23 +0100 (Fri, 21 Dec 2007) | 2 lines Fixed shop list box not to scroll up when the selection is removed. ........ r3802 | b_lindeijer | 2007-12-21 13:37:17 +0100 (Fri, 21 Dec 2007) | 2 lines Added logging of error on PHYSFS_addToSearchPath. ........ r3803 | b_lindeijer | 2007-12-21 15:56:38 +0100 (Fri, 21 Dec 2007) | 3 lines Fixed inventory size not matching the size assumed by eAthena and related memory corruption and increased default chat log length. ........ r3804 | the_enemy | 2007-12-21 16:07:20 +0100 (Fri, 21 Dec 2007) | 1 line Attempted to fix client freeze when unable to connect to update host, and added exit dialog ........ r3805 | b_lindeijer | 2007-12-22 16:24:14 +0100 (Sat, 22 Dec 2007) | 2 lines Updated version to 0.0.24. Release data set to tomorrow, we'll see. ........ r3806 | b_lindeijer | 2007-12-22 21:42:35 +0100 (Sat, 22 Dec 2007) | 2 lines Make sure chat messages are also trimmed for the local player. ........ r3809 | crush_tmw | 2007-12-23 03:16:53 +0100 (Sun, 23 Dec 2007) | 1 line Particle images are now reference-counted properly. Avoided attempts to load "data/graphics/" when a monster or equipment piece has no sprite. Error placeholder is now used when attempting to load a sprite definition file that doesn't exist. ........ r3810 | b_lindeijer | 2007-12-24 02:20:42 +0100 (Mon, 24 Dec 2007) | 2 lines Updated release date. ........ r3812 | the_enemy | 2007-12-24 15:16:15 +0100 (Mon, 24 Dec 2007) | 1 line Minor update, fixed disconnection dialog ........ r3813 | b_lindeijer | 2007-12-24 15:45:34 +0100 (Mon, 24 Dec 2007) | 2 lines Fixed compile warning. ........ r3816 | b_lindeijer | 2007-12-25 13:31:21 +0100 (Tue, 25 Dec 2007) | 2 lines Fixed year. :) ........ r3818 | b_lindeijer | 2007-12-25 23:11:55 +0100 (Tue, 25 Dec 2007) | 2 lines Updated CMake file. ........ r3821 | b_lindeijer | 2007-12-26 19:06:15 +0100 (Wed, 26 Dec 2007) | 2 lines Fixed year in README too. ........ --- ChangeLog | 46 +++++++++++++++++++++++++++++++++++++-- INSTALL | 12 +++++----- NEWS | 12 +++++++--- data/help/changes.txt | 34 ++++++++++++++++++++--------- data/help/header.txt | 2 +- src/game.cpp | 31 ++++++++++++++++++++++++++ src/gui/inventorywindow.cpp | 2 +- src/gui/shoplistbox.cpp | 4 ++-- src/gui/updatewindow.cpp | 15 ++++++++----- src/inventory.cpp | 6 +++++ src/localplayer.cpp | 1 + src/localplayer.h | 4 +--- src/main.cpp | 3 +-- src/monster.cpp | 8 +++++-- src/net/chathandler.cpp | 1 + src/openglgraphics.cpp | 2 +- src/particleemitter.cpp | 35 +++++++++++++++++++++++++++++ src/particleemitter.h | 10 +++++++++ src/player.cpp | 15 ++++++++----- src/resources/resourcemanager.cpp | 8 +++++-- src/resources/resourcemanager.h | 4 +++- src/resources/spritedef.cpp | 3 ++- 22 files changed, 210 insertions(+), 48 deletions(-) (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index 874bb04a..01824d45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -141,6 +141,50 @@ Len. * data/maps/new_3-1.tmx: Some mapping errors fixed by Zipon. +2007-12-25 Bjørn Lindeijer + + * data/help/header.txt: Fixed year. :) + +2007-12-24 David Athay + + * src/game.cpp: Fixed dialog for disconnections, so it says Ok, not + yes/no. + * src/openglgraphics.cpp: Changed type so it would compile on Leopard. + +2007-12-24 Bjørn Lindeijer + + * src/particleemitter.cpp: Fix compile warning. + +2007-12-23 Philipp Sehmisch + + * src/particleemitter.cpp, src/particleemitter.h: Particle images are + now reference-counted properly. + * src/resources/spritedef.cpp: Error placeholder is now used when + attempting to load a sprite definition file that doesn't exist. + * src/monster.cpp, src/player.cpp: Avoided attempts to load + "data/graphics/" when a monster or equipment piece has no sprite. + * data/graphics/particles/cookingfire.particle.xml: Removed some + particle properties that did nothing because they were misspelled. + +2007-12-22 Bjørn Lindeijer + + * src/net/chathandler.cpp, NEWS: Make sure chat messages are also + trimmed for the local player. + +2007-12-21 David Athay + + * src/game.cpp, src/gui/updatewindow.cpp: Attempted to fix client + freeze when unable to connect to update host, and added exit dialog + when client loses connection. + +2007-12-21 Bjørn Lindeijer + + * src/gui/shoplistbox.cpp: Fixed shop list box not to scroll up when + the selection is removed. + * src/resources/resourcemanager.h, src/resources/resourcemanager.cpp: + Added logging of error on PHYSFS_addToSearchPath. + * src/main.cpp: Increased default chat log length. + 2007-12-19 Philipp Sehmisch * data/maps/new_18-1.tmx: Fixed a map bug (monster trap) on @@ -157,8 +201,6 @@ 2007-12-18 Bjørn Lindeijer - * src/main.cpp: Remember to delete the progressbar and label also when - the game was not started. * tools/upalyzer/analyse.php: Added initial version of the update analysis tool upalyzer. * tools/upalyzer/analyse.php: Optimized with single loop approach and diff --git a/INSTALL b/INSTALL index a6f43ed1..ac5a9fb8 100644 --- a/INSTALL +++ b/INSTALL @@ -20,13 +20,14 @@ and some libraries. The required libraries are: * SDL_mixer http://www.libsdl.org/projects/SDL_mixer/ * SDL_image http://www.libsdl.org/projects/SDL_image/ * ENet 1.2 http://enet.bespin.org/ -* Guichan 0.7.0 http://guichan.sourceforge.net/ +* Guichan 0.7.x http://guichan.sourceforge.net/ * libxml2 http://www.xmlsoft.org/ * physfs 1.0.x http://icculus.org/physfs/ * zlib 1.2.x http://www.gzip.org/zlib/ * libcurl http://curl.haxx.se/libcurl/ -If you checked TMW out from CVS you will also need these tools to compile: +If you checked TMW out from Subversion you will also need these tools to +compile: * GNU automake 1.9 http://www.gnu.org/software/automake/ * GNU autoconf http://www.gnu.org/software/autoconf/ @@ -50,11 +51,10 @@ It should have installed The Mana World on your system now, and you can run it with "tmw". By default all files are installed to /usr/local, you can pass a different prefix to configure as usual. - NOTE: For those people with modern video cards and fast OpenGL performance, - we have been working on OpenGL support. To enable this perform step 3 as - follows: + NOTE: It is possible to compile TMW without support for OpenGL rendering. + To do this perform step 3 as follows: - "./configure --with-opengl" + ./configure --without-opengl Rebuild the executable from scratch using "make clean" and then "make". diff --git a/NEWS b/NEWS index a1ad3814..ebdae676 100644 --- a/NEWS +++ b/NEWS @@ -1,20 +1,26 @@ -0.0.24 (... 2007) +0.0.24 (24 December 2007) +- Added female specific hair styles - Added user-definable key settings -- Added shortcut bar for quick access to inventory items - Added XP gaining notification - Added close button to most windows +- Added support for dynamic sprite recoloring +- Added notification when the connection to the server is lost - Updated to work with Guichan 0.7.x - Mouse cursor now indicates when resize is possible - Changed amount slider in buy and sell dialogs to start at 1 - Made weapon sprites and sounds customizable - Made buy and sell dialogs resizable - Merged equipment database with items database +- Chat window log no longer goes back forever +- Chat messages are trimmed (spaces are removed on both sides) - Fixed segmentation fault with some OpenGL drivers -- Fixed updating of defence when increasing vitality +- Fixed updating of defense when increasing vitality - Fixed a bug that prevented being-controlled particles from being deleted - Fixed a crash in the particle engine related to child emitters - Fixed encoding issues with user home directory - Fixed a crash in equipment window on failure to load an item icon +- Fixed a crash on filling up your inventory +- Fixed item list in shops not to scroll back when selling 0.0.23 (3 June 2007) - Added a particle engine along with some particle effects diff --git a/data/help/changes.txt b/data/help/changes.txt index dd062e49..26bd21d1 100644 --- a/data/help/changes.txt +++ b/data/help/changes.txt @@ -3,6 +3,30 @@ ##3 === RECENT CHANGES === + 0.0.24 (24 December 2007) + - Added female specific hair styles + - Added user-definable key settings + - Added XP gaining notification + - Added close button to most windows + - Added support for dynamic sprite recoloring + - Added notification when the connection to the server is lost + - Updated to work with Guichan 0.7.x + - Mouse cursor now indicates when resize is possible + - Changed amount slider in buy and sell dialogs to start at 1 + - Made weapon sprites and sounds customizable + - Made buy and sell dialogs resizable + - Merged equipment database with items database + - Chat window log no longer goes back forever + - Chat messages are trimmed (spaces are removed on both sides) + - Fixed segmentation fault with some OpenGL drivers + - Fixed updating of defense when increasing vitality + - Fixed a bug that prevented being-controlled particles from being deleted + - Fixed a crash in the particle engine related to child emitters + - Fixed encoding issues with user home directory + - Fixed a crash in equipment window on failure to load an item icon + - Fixed a crash on filling up your inventory + - Fixed item list in shops not to scroll back when selling + 0.0.23 (3 June 2007) - Added a particle engine along with some particle effects - Added a cursor to indicate targeted enemy @@ -46,13 +70,3 @@ - Fixed pathfinding to allow walking through beings when they block your path - Fixed an issue with NPC dialogs staying open after player respawn - 0.0.21.1 (30 October 2006) - - Reload wallpaper after loading updates - - Added support for gzip compressed map layer data - - Added support for building with CMake - - Added slider to setup dialog for configuring overlay effect - - Fixed excessive unnecessary reloading of sprites - - Fixed problem with OpenGL related redefinition - - Fixed problems with hiding windows using h - - Fixed trade window positioning - diff --git a/data/help/header.txt b/data/help/header.txt index b10ed991..19afb84f 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.23 ##2Date:##33 June 2007 + ##2Version:##6 0.0.24 ##2Date:##324 December 2007 ##2 Website: http://themanaworld.org diff --git a/src/game.cpp b/src/game.cpp index 7ae21009..cf6dc547 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -60,6 +60,7 @@ #include "gui/ministatus.h" #include "gui/npclistdialog.h" #include "gui/npc_text.h" +#include "gui/ok_dialog.h" #include "gui/sdlinput.h" #include "gui/sell.h" #include "gui/setup.h" @@ -96,6 +97,7 @@ Joystick *joystick = NULL; extern Window *weightNotice; extern Window *deathNotice; QuitDialog *quitDialog = NULL; +OkDialog *disconnectedDialog = NULL; ChatWindow *chatWindow; MenuWindow *menuWindow; @@ -127,6 +129,21 @@ Particle *particleEngine = NULL; const int MAX_TIME = 10000; +/** + * Listener used for exitting handling. + */ +namespace { + struct ExitListener : public gcn::ActionListener + { + void action(const gcn::ActionEvent &event) + { + if (event.getId() == "yes" || event.getId() == "ok") { + done = true; + } + } + } exitListener; +} + /** * Advances game logic counter. */ @@ -407,6 +424,20 @@ void Game::logic() // Handle network stuff Net::flush(); + + // TODO: Fix notification when the connection is lost + if (false /*!mNetwork->isConnected() */) + { + if (!disconnectedDialog) + { + disconnectedDialog = new + OkDialog("Network Error", + "The connection to the server was lost, the program will now quit"); + disconnectedDialog->addActionListener(&exitListener); + } + + disconnectedDialog->requestMoveToTop(); + } } } diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index bf23a419..0ef1ab35 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -65,7 +65,7 @@ InventoryWindow::InventoryWindow(): mDropButton = new Button(_("Drop"), "drop", this); mSplitButton = new Button(_("Split"), "split", this); - mItems = new ItemContainer(player_node->mInventory.get(), 10, 5); + mItems = new ItemContainer(player_node->mInventory, 10, 5); mItems->addSelectionListener(this); mInvenScroll = new ScrollArea(mItems); diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp index ffa4d116..e6d3c516 100644 --- a/src/gui/shoplistbox.cpp +++ b/src/gui/shoplistbox.cpp @@ -114,10 +114,10 @@ void ShopListBox::setSelected(int selected) std::max(-1, selected)); gcn::Widget *parent = getParent(); - if (parent) + if (parent && mSelected >= 0) { gcn::Rectangle scroll; - scroll.y = (mSelected < 0) ? 0 : mRowHeight * mSelected; + scroll.y = mRowHeight * mSelected; scroll.height = mRowHeight; parent->showWidgetPart(this, scroll); } diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index 5d81bb9c..abae69f6 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -307,17 +307,20 @@ int UpdaterWindow::downloadThread(void *ptr) switch (res) { case CURLE_COULDNT_CONNECT: - // give more debug info on that error - std::cerr << "curl error " << res << ": " - << uw->mCurlError << " " << url.c_str() - << std::endl; - break; - default: std::cerr << "curl error " << res << ": " << uw->mCurlError << " host: " << url.c_str() << std::endl; + break; + } + + if (!uw->mStoreInMemory) + { + fclose(outfile); + ::remove(outFilename.c_str()); } + attempts++; + continue; } curl_easy_cleanup(curl); diff --git a/src/inventory.cpp b/src/inventory.cpp index bc4bd1c0..807e1223 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -26,6 +26,7 @@ #include #include "item.h" +#include "log.h" struct SlotUsed : public std::unary_function { @@ -64,6 +65,11 @@ void Inventory::addItem(int id, int quantity) void Inventory::setItem(int index, int id, int quantity) { + if (index < 0 || index >= INVENTORY_SIZE) { + logger->log("Warning: invalid inventory index: %d", index); + return; + } + if (!mItems[index] && id > 0) { mItems[index] = new Item(id, quantity); mItems[index]->setInvIndex(index); diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 12de3de4..085c80c5 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -69,6 +69,7 @@ LocalPlayer::LocalPlayer(): LocalPlayer::~LocalPlayer() { + delete mInventory; } void LocalPlayer::logic() diff --git a/src/localplayer.h b/src/localplayer.h index fca6f993..548325dc 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -24,8 +24,6 @@ #ifndef _TMW_LOCALPLAYER_H #define _TMW_LOCALPLAYER_H -#include - #include "player.h" // TODO move into some sane place... @@ -329,7 +327,7 @@ class LocalPlayer : public Player float mLastAttackTime; /**< Used to synchronize the charge dialog */ - std::auto_ptr mInventory; + Inventory *mInventory; std::auto_ptr mEquipment; protected: diff --git a/src/main.cpp b/src/main.cpp index 0726f5dc..9c69b203 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -191,7 +191,7 @@ void initConfiguration(const Options &options) config.setValue("fpslimit", 0); config.setValue("updatehost", "http://updates.themanaworld.org"); config.setValue("customcursor", 1); - config.setValue("ChatLogLength", 64); + config.setValue("ChatLogLength", 128); // Checking if the configuration file exists... otherwise create it with // default options. @@ -1055,7 +1055,6 @@ int main(int argc, char *argv[]) #ifdef PACKAGE_VERSION delete versionLabel; #endif - } catch (...) { diff --git a/src/monster.cpp b/src/monster.cpp index 9cbd28eb..ae749017 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -35,8 +35,12 @@ Monster::Monster(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { - mSprites[BASE_SPRITE] = AnimatedSprite::load( - "graphics/sprites/" + getInfo().getSprite()); + std::string filename = getInfo().getSprite(); + if (filename.empty()) + filename = "error.xml"; + + mSprites[BASE_SPRITE] = + AnimatedSprite::load("graphics/sprites/" + filename); } Being::Type diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index 9fe231e6..d10c1556 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -191,6 +191,7 @@ void ChatHandler::handleMessage(MessageIn &msg) { chatMsg.erase(0, pos + 3); } + trim(chatMsg); player_node->setSpeech(chatMsg, SPEECH_TIME); } else diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp index 51e99fa0..76eff9f5 100644 --- a/src/openglgraphics.cpp +++ b/src/openglgraphics.cpp @@ -89,7 +89,7 @@ bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) (gotDoubleBuffer ? "with" : "without")); char const *glExtensions = (char const *)glGetString(GL_EXTENSIONS); - int texSize; + GLint texSize; bool rectTex = strstr(glExtensions, "GL_ARB_texture_rectangle"); if (rectTex) { diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp index 035882b6..6f66b632 100644 --- a/src/particleemitter.cpp +++ b/src/particleemitter.cpp @@ -237,9 +237,44 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map * } } +ParticleEmitter::ParticleEmitter(const ParticleEmitter &o) +{ + *this = o; +} + +ParticleEmitter & ParticleEmitter::operator=(const ParticleEmitter &o) +{ + mParticlePosX = o.mParticlePosX; + mParticlePosY = o.mParticlePosY; + mParticlePosZ = o.mParticlePosZ; + mParticleAngleHorizontal = o.mParticleAngleHorizontal; + mParticleAngleVertical = o.mParticleAngleVertical; + mParticlePower = o.mParticlePower; + mParticleGravity = o.mParticleGravity; + mParticleRandomnes = o.mParticleRandomnes; + mParticleBounce = o.mParticleBounce; + mParticleTarget = o.mParticleTarget; + mParticleAcceleration = o.mParticleAcceleration; + mParticleDieDistance = o.mParticleDieDistance; + mParticleMomentum = o.mParticleMomentum; + mParticleLifetime = o.mParticleLifetime; + mParticleFadeOut = o.mParticleFadeOut; + mParticleFadeIn = o.mParticleFadeIn; + mMap = o.mMap; + mOutput = o.mOutput; + mParticleImage = o.mParticleImage; + mParticleAnimation = o.mParticleAnimation; + mParticleChildEmitters = o.mParticleChildEmitters; + + if (mParticleImage) mParticleImage->incRef(); + + return *this; +} + ParticleEmitter::~ParticleEmitter() { + if (mParticleImage) mParticleImage->decRef(); } diff --git a/src/particleemitter.h b/src/particleemitter.h index 37d067a6..c9524488 100644 --- a/src/particleemitter.h +++ b/src/particleemitter.h @@ -47,6 +47,16 @@ class ParticleEmitter */ ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map *map); + /** + * Copy Constructor (necessary for reference counting of particle images) + */ + ParticleEmitter(const ParticleEmitter &o); + + /** + * Assignment operator that calls the copy constructor + */ + ParticleEmitter & operator=(const ParticleEmitter &o); + /** * Destructor. */ diff --git a/src/player.cpp b/src/player.cpp index 050790e8..b1372925 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -128,9 +128,16 @@ void Player::setSprite(int slot, int id, const std::string &color) } else { - AnimatedSprite *equipmentSprite = AnimatedSprite::load( - "graphics/sprites/" + ItemDB::get(id).getSprite(mGender) + - "|" + color); + std::string filename = ItemDB::get(id).getSprite(mGender); + AnimatedSprite *equipmentSprite = NULL; + + if (!filename.empty()) + { + if (!color.empty()) + filename += "|" + color; + equipmentSprite = + AnimatedSprite::load("graphics/sprites/" + filename); + } if (equipmentSprite) equipmentSprite->setDirection(getSpriteDirection()); @@ -139,9 +146,7 @@ void Player::setSprite(int slot, int id, const std::string &color) mSprites[slot] = equipmentSprite; if (slot == WEAPON_SPRITE) - { mEquippedWeapon = &ItemDB::get(id); - } setAction(mAction); } diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index 6f91390e..fb9da9d7 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -144,11 +144,15 @@ ResourceManager::setWriteDir(const std::string &path) return (bool) PHYSFS_setWriteDir(path.c_str()); } -void +bool ResourceManager::addToSearchPath(const std::string &path, bool append) { logger->log("Adding to PhysicsFS: %s", path.c_str()); - PHYSFS_addToSearchPath(path.c_str(), append ? 1 : 0); + if (!PHYSFS_addToSearchPath(path.c_str(), append ? 1 : 0)) { + logger->log("Error: %s", PHYSFS_getLastError()); + return false; + } + return true; } void diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h index 46b17d1b..abfd629a 100644 --- a/src/resources/resourcemanager.h +++ b/src/resources/resourcemanager.h @@ -73,8 +73,10 @@ class ResourceManager * Adds a directory or archive to the search path. If append is true * then the directory is added to the end of the search path, otherwise * it is added at the front. + * + * @return true on success, false otherwise. */ - void + bool addToSearchPath(const std::string &path, bool append); /** diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp index de6f8d0b..d2e32c03 100644 --- a/src/resources/spritedef.cpp +++ b/src/resources/spritedef.cpp @@ -62,7 +62,8 @@ SpriteDef *SpriteDef::load(std::string const &animationFile, int variant) char *data = (char*) resman->loadFile (animationFile.substr(0, pos).c_str(), size); - if (!data) return NULL; + if (!data && animationFile != "graphics/sprites/error.xml") + return load("graphics/sprites/error.xml", 0); xmlDocPtr doc = xmlParseMemory(data, size); free(data); -- cgit v1.2.3-70-g09d2 From bbb40f595e6e20e5106a23e6aa606b825b1e62b4 Mon Sep 17 00:00:00 2001 From: David Athay Date: Mon, 14 Apr 2008 17:05:29 +0000 Subject: Added new TabbedArea which extends gui::TabbedArea. Changed Guild and Chat windows to use new TabbedArea. Added private messaging. --- ChangeLog | 8 +++++ src/gui/chat.cpp | 68 ++++++++++++++++++++++----------------- src/gui/chat.h | 14 +++++--- src/gui/guildwindow.cpp | 45 +++++++++++++------------- src/gui/guildwindow.h | 5 ++- src/gui/widgets/tabbedarea.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++ src/gui/widgets/tabbedarea.h | 60 ++++++++++++++++++++++++++++++++++ src/net/chathandler.cpp | 11 +++++++ 8 files changed, 224 insertions(+), 60 deletions(-) create mode 100644 src/gui/widgets/tabbedarea.cpp create mode 100644 src/gui/widgets/tabbedarea.h (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index 4c12aa32..c5dcee84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-04-14 David Athay + + * src/gui/guildwindow.cpp, src/gui/chat.cpp, + src/gui/widgets/tabbedarea.h, src/gui/widgets/tabbedarea.cpp, + src/gui/chat.h, src/gui/guildwindow.h, src/net/chathandler.cpp: + Added new TabbedArea which extends gui::TabbedArea. Changed Guild and + Chat windows to use new TabbedArea. Added private messaging. + 2008-04-12 Yohann Ferreira * src/CMakeLists.txt: Fixed a compilation error using Cmake. diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 1efee8ed..0602c671 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -30,12 +30,12 @@ #include "browserbox.h" #include "chatinput.h" -#include "gccontainer.h" #include "scrollarea.h" #include "sdlinput.h" -#include "tabbedcontainer.h" #include "windowcontainer.h" +#include "widgets/tabbedarea.h" + #include "../channelmanager.h" #include "../channel.h" #include "../configuration.h" @@ -53,7 +53,7 @@ ChatWindow::ChatWindow(): mTmpVisible(false) { setResizable(true); - setDefaultSize(0, (windowContainer->getHeight() - 123), 600, 100); + setDefaultSize(0, (windowContainer->getHeight() - 105), 600, 100); setTitleBarHeight(5); loadWindowState("Chat"); @@ -72,24 +72,18 @@ ChatWindow::ChatWindow(): gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS); scrollArea->setOpaque(false); - GCContainer *tab = new GCContainer(); - tab->setWidth(getWidth() - 2 * tab->getFrameSize()); - tab->setHeight(getHeight() - 2 * tab->getFrameSize()); - tab->setOpaque(false); - tab->add(scrollArea); + mChatTabs = new TabbedArea(); + mChatTabs->addTab("General", scrollArea); + mChatTabs->setWidth(getWidth()); + mChatTabs->setHeight(getHeight()); - mContainer = new TabbedContainer(); - mContainer->addTab(tab, "General"); - mContainer->setOpaque(false); mChannelOutput["General"] = textOutput; mChannelScroll["General"] = scrollArea; - mTabs["General"] = tab; - mTextOutput = textOutput; mScrollArea = scrollArea; - add(mContainer); + add(mChatTabs); add(mChatInput); // Add key listener to chat input to be able to respond to up/down @@ -99,23 +93,20 @@ ChatWindow::ChatWindow(): ChatWindow::~ChatWindow() { - for_each(mTabs.begin(), mTabs.end(), make_dtor(mTabs)); + delete mChatTabs; } void ChatWindow::logic() { // todo: only do this when the size changes (updateWidgets?) - const gcn::Rectangle area = getChildrenArea(); mChatInput->setPosition(mChatInput->getFrameSize(), area.height - mChatInput->getHeight() - mChatInput->getFrameSize()); mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize()); - mContainer->setWidth(area.width - 2 * mContainer->getFrameSize()); - mContainer->setHeight(area.height - 2 * mContainer->getFrameSize() - - mChatInput->getHeight() - 5); + mScrollArea->setWidth(area.width - 2 * mScrollArea->getFrameSize()); mScrollArea->setHeight(area.height - 2 * mScrollArea->getFrameSize() - mChatInput->getHeight() - 26); @@ -225,7 +216,8 @@ ChatWindow::action(const gcn::ActionEvent &event) mCurHist = mHistory.end(); // Send the message to the server - chatSend(player_node->getName(), message, mContainer->getActiveWidget()); + gcn::Tab *tab = mChatTabs->getSelectedTab(); + chatSend(player_node->getName(), message, tab->getCaption()); // Clear the text from the chat input mChatInput->setText(""); @@ -280,7 +272,8 @@ void ChatWindow::chatSend(std::string const &nick, std::string const &msg, // Prepare ordinary message if (msg[0] != '/') { - if (mContainer->getActiveWidget() == "General") + gcn::Tab *tab = mChatTabs->getSelectedTab(); + if (tab->getCaption() == "General") { Net::GameServer::Player::say(msg); } @@ -311,6 +304,7 @@ void ChatWindow::chatSend(std::string const &nick, std::string const &msg, chatLog("/announce > Global announcement (GM only)", BY_SERVER, channelName); chatLog("/where > Display map name", BY_SERVER, channelName); chatLog("/who > Display number of online users", BY_SERVER, channelName); + chatLog("/msg > Send a private message to a user", BY_SERVER, channelName); chatLog("/list > Display all public channels", BY_SERVER, channelName); chatLog("/register > Register a new channel", BY_SERVER, channelName); chatLog("/join > Join an already registered channel", BY_SERVER, channelName); @@ -328,6 +322,14 @@ void ChatWindow::chatSend(std::string const &nick, std::string const &msg, MessageOut outMsg(0x00c1); */ } + else if (command == "msg") + { + std::string::size_type pos = arg.find(' ', 1); + std::string recipient(arg, 0, pos-1); + std::string text(arg, pos+1); + chatLog("* " + text, BY_SERVER); + Net::ChatServer::privMsg(recipient, text); + } else if (command == "register") { chatLog("Requesting to register channel " + arg, BY_SERVER); @@ -458,8 +460,10 @@ ChatWindow::removeChannel(short channelId) Channel* channel = channelManager->findById(channelId); if(channel) { - mContainer->removeTab(channel->getName()); - mTabs.erase(channel->getName()); + gcn::Tab *tab = mChatTabs->getTab(channel->getName()); + if (!tab) + return; + mChatTabs->removeTab(tab); mChannelOutput.erase(channel->getName()); mChannelScroll.erase(channel->getName()); channelManager->removeChannel(channel); @@ -478,13 +482,8 @@ ChatWindow::createNewChannelTab(std::string channelName) scrollArea->setPosition(scrollArea->getFrameSize(), scrollArea->getFrameSize()); scrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS); scrollArea->setOpaque(false); - GCContainer *tab = new GCContainer(); - tab->setWidth(getWidth() - 2 * tab->getFrameSize()); - tab->setHeight(getHeight() - 2 * tab->getFrameSize()); - tab->add(scrollArea); - tab->setOpaque(false); - mContainer->addTab(tab, channelName); - mTabs[channelName] = tab; + + mChatTabs->addTab(channelName, scrollArea); mChannelOutput[channelName] = textOutput; mChannelScroll[channelName] = scrollArea; mScrollArea = scrollArea; @@ -553,3 +552,12 @@ ChatWindow::setVisible(bool isVisible) */ mTmpVisible = false; } + +bool +ChatWindow::tabExists(const std::string &tabName) +{ + gcn::Tab *tab = mChatTabs->getTab(tabName); + if (tab) + return true; + return false; +} diff --git a/src/gui/chat.h b/src/gui/chat.h index 19795dd3..d605def0 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -37,8 +37,9 @@ class BrowserBox; class ScrollArea; -class TabbedContainer; -class GCContainer; +//class TabbedContainer; +//class GCContainer; +class TabbedArea; enum { @@ -213,6 +214,10 @@ class ChatWindow : public Window, public gcn::ActionListener, void setVisible(bool visible); + /** Check if tab with that name already exists */ + bool + tabExists(const std::string &tabName); + private: bool mTmpVisible; @@ -229,11 +234,12 @@ class ChatWindow : public Window, public gcn::ActionListener, #if 0 /** Constructs failed messages for actions */ std::string const_msg(CHATSKILL); -#endif - std::map mTabs; TabbedContainer *mContainer; /**< Tabbed container for tabbing between channels */ GCContainer *mTab; /**< Tabs */ +#endif + + TabbedArea *mChatTabs; /** < Chat Tabbed area for holding each channel */ gcn::TextField *mChatInput; /**< Input box for typing chat messages */ std::map mChannelOutput; /**< Map each TextOutput to a tab */ std::map mChannelScroll; /**< Map each ScrollArea to a tab */ diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp index eb0faa35..7b69f9bf 100644 --- a/src/gui/guildwindow.cpp +++ b/src/gui/guildwindow.cpp @@ -26,14 +26,13 @@ #include "button.h" #include "chat.h" #include "confirm_dialog.h" -#include "gccontainer.h" #include "guildlistbox.h" #include "scrollarea.h" -#include "tabbedcontainer.h" #include "textdialog.h" #include "windowcontainer.h" #include "widgets/layout.h" +#include "widgets/tabbedarea.h" #include "../guild.h" #include "../log.h" @@ -45,12 +44,14 @@ #include +#include + GuildWindow::GuildWindow(): Window(player_node->getName()), mFocus(false) { setCaption("Guild"); - setResizable(true); + setResizable(false); setCloseButton(true); setMinWidth(200); setMinHeight(280); @@ -63,14 +64,12 @@ GuildWindow::GuildWindow(): mGuildButton[1]->setEnabled(false); mGuildButton[2]->setEnabled(false); - mGuildsContainer = new TabbedContainer(); - - mGuildsContainer->setOpaque(false); + mGuildTabs = new TabbedArea(); place(0, 0, mGuildButton[0]); place(1, 0, mGuildButton[1]); place(2, 0, mGuildButton[2]); - place(0, 1, mGuildsContainer); + place(0, 1, mGuildTabs); Layout &layout = getLayout(); layout.setColWidth(0, 48); layout.setColWidth(1, 65); @@ -80,7 +79,7 @@ GuildWindow::GuildWindow(): GuildWindow::~GuildWindow() { - for_each(mTabs.begin(), mTabs.end(), make_dtor(mTabs)); + delete mGuildTabs; } void GuildWindow::update() @@ -102,13 +101,14 @@ void GuildWindow::action(const gcn::ActionEvent &event) // Stats Part if (eventId == "CREATE_GUILD") { - if (mGuildsContainer->getNumberOfTabs() > 1) + if (mGuildTabs->getNumberOfTabs() > 1) { // This is just to limit the number of guild tabs that are created // TODO: Either limit this server side, or fix the interface issue chatWindow->chatLog("Current maximum number of guilds ownable is 2", BY_SERVER); return; } + // Set focus so that guild name to be created can be typed. mFocus = true; guildDialog = new TextDialog("Guild Name", "Choose your guild's name", this); @@ -129,7 +129,7 @@ void GuildWindow::action(const gcn::ActionEvent &event) if (guild) { Net::ChatServer::Guild::quitGuild(guild); - chatWindow->chatLog("Guild " + mGuildsContainer->getActiveWidget() + " quit", BY_SERVER); + chatWindow->chatLog("Guild " + mGuildTabs->getSelectedTab()->getCaption() + " quit", BY_SERVER); } } else if (eventId == "CREATE_GUILD_OK") @@ -172,27 +172,25 @@ void GuildWindow::newGuildTab(const std::string &guildName) { // Create new tab - GCContainer *tab = new GCContainer(); - tab->setWidth(getWidth() - 2 * tab->getFrameSize()); - tab->setHeight(getHeight() - 2 * tab->getFrameSize()); - tab->setOpaque(false); ListBox *list = new ListBox(); list->setListModel(player_node->getGuild(guildName)); ScrollArea *sa = new ScrollArea(list); sa->setDimension(gcn::Rectangle(5, 5, 135, 250)); - tab->add(sa); - mGuildsContainer->addTab(tab, guildName); - mGuildsContainer->setDimension(gcn::Rectangle(28,35,280,250)); - - mTabs.push_back(tab); + mGuildTabs->addTab(guildName, sa); + mGuildTabs->setDimension(gcn::Rectangle(28,35,140,250)); updateTab(); } void GuildWindow::updateTab() { - setTab(mGuildsContainer->getActiveWidget()); + gcn::Tab *tab = mGuildTabs->getSelectedTab(); + if (tab) + { + setTab(tab->getCaption()); + } + mGuildTabs->logic(); } void GuildWindow::setTab(const std::string &guildName) @@ -217,7 +215,7 @@ bool GuildWindow::isFocused() short GuildWindow::getSelectedGuild() { - Guild *guild = player_node->getGuild(mGuildsContainer->getActiveWidget()); + Guild *guild = player_node->getGuild(mGuildTabs->getSelectedTab()->getCaption()); if (guild) { return guild->getId(); @@ -248,7 +246,8 @@ void GuildWindow::removeTab(int guildId) Guild* guild = player_node->getGuild(guildId); if (guild) { - mGuildsContainer->removeTab(guild->getName()); + gcn::Tab *tab = mGuildTabs->getTab(guild->getName()); + mGuildTabs->removeTab(tab); } - mGuildsContainer->logic(); + mGuildTabs->logic(); } diff --git a/src/gui/guildwindow.h b/src/gui/guildwindow.h index 5f7600e5..f6cb38fd 100644 --- a/src/gui/guildwindow.h +++ b/src/gui/guildwindow.h @@ -45,9 +45,9 @@ class LocalPlayer; class TextDialog; class ConfirmDialog; class GuildListBox; -class TabbedContainer; class ScrollArea; class GCContainer; +class TabbedArea; class GuildWindow : public Window, public gcn::ActionListener { @@ -124,10 +124,9 @@ private: TextDialog *guildDialog; TextDialog *inviteDialog; ConfirmDialog *acceptDialog; - TabbedContainer *mGuildsContainer; + TabbedArea *mGuildTabs; GuildListBox *mGuildMembersList; ScrollArea *mScrollArea; - std::vector mTabs; bool mFocus; std::string invitedGuild; }; diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp new file mode 100644 index 00000000..6ba27622 --- /dev/null +++ b/src/gui/widgets/tabbedarea.cpp @@ -0,0 +1,73 @@ +/* + * The Mana World + * Copyright 2008 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: $ + */ + +#include "tabbedarea.h" + +#include + +TabbedArea::TabbedArea() : gcn::TabbedArea() +{ + mWidgetContainer->setOpaque(false); +} + +int TabbedArea::getNumberOfTabs() +{ + return mTabs.size(); +} + +gcn::Tab* TabbedArea::getTab(const std::string &name) +{ + std::vector< std::pair >::iterator itr = mTabs.begin(), + itr_end = mTabs.end(); + while (itr != itr_end) + { + if ((*itr).first->getCaption() == name) + { + return (*itr).first; + } + ++itr; + } +} + +void TabbedArea::draw(gcn::Graphics *graphics) +{ + if (mTabs.empty()) + { + return; + } + + std::vector< std::pair >::iterator itr; + unsigned int i; + for (i = 0; i < mTabs.size(); i++) + { + if (mTabs[i].first == mSelectedTab) + { + mTabs[i].second->setWidth(getWidth()); + mTabs[i].second->setHeight(getHeight()); + mTabs[i].second->logic(); + break; + } + } + + gcn::TabbedArea::draw(graphics); +} diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h new file mode 100644 index 00000000..42275fae --- /dev/null +++ b/src/gui/widgets/tabbedarea.h @@ -0,0 +1,60 @@ +/* + * The Mana World + * Copyright 2008 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: $ + */ + +#ifndef _TMW_TABBEDAREA_H +#define _TMW_TABBEDAREA_H + +#include +#include + +#include + +/** + * A tabbed area, the same as the guichan tabbed area in 0.8, but extended + */ +class TabbedArea : public gcn::TabbedArea +{ + public: + /** + * Constructor. + */ + TabbedArea(); + + /** + * Draw the tabbed area. + */ + void draw(gcn::Graphics *graphics); + + /** + * Return how many tabs have been created + */ + int getNumberOfTabs(); + + /** + * Return tab with specified name as caption + */ + gcn::Tab* getTab(const std::string &name); +}; + +#endif + diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index d10c1556..4d48865a 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -137,6 +137,17 @@ void ChatHandler::handleMessage(MessageIn &msg) chatWindow->chatLog("End of channel list", BY_SERVER); break; + case CPMSG_PRIVMSG: + userNick = msg.readString(); + chatMsg = msg.readString(); + + if (!chatWindow->tabExists(userNick)) + { + chatWindow->createNewChannelTab(userNick); + chatWindow->chatLog(userNick + ": " + chatMsg, BY_OTHER, userNick); + } + break; + case CPMSG_PUBMSG: channelId = msg.readInt16(); userNick = msg.readString(); -- cgit v1.2.3-70-g09d2 From e2e4ceb9fa8a72ad94853f74724676fff82b15c0 Mon Sep 17 00:00:00 2001 From: David Athay Date: Tue, 15 Apr 2008 15:42:04 +0000 Subject: Added online status of guild members --- ChangeLog | 11 +++++++++++ data/graphics/gui/circle-gray.png | Bin 0 -> 295 bytes data/graphics/gui/circle-green.png | Bin 0 -> 299 bytes src/Makefile.am | 2 ++ src/gui/guildlistbox.cpp | 35 ++++++++++++++++++++++++++--------- src/gui/guildlistbox.h | 26 +++++++++++++++++--------- src/gui/guildwindow.cpp | 18 +++++++++++++++--- src/gui/guildwindow.h | 7 ++++++- src/gui/widgets/tabbedarea.cpp | 15 ++++++++++++++- src/gui/widgets/tabbedarea.h | 6 ++++++ src/net/chathandler.cpp | 23 ++++++++++++++++++++++- src/net/chatserver/chatserver.cpp | 9 +++++++++ src/net/chatserver/chatserver.h | 2 ++ src/net/guildhandler.cpp | 11 +++++++++++ src/net/protocol.h | 2 +- tmw.cbp | 5 ++--- 16 files changed, 144 insertions(+), 28 deletions(-) create mode 100644 data/graphics/gui/circle-gray.png create mode 100644 data/graphics/gui/circle-green.png (limited to 'src/net/chathandler.cpp') diff --git a/ChangeLog b/ChangeLog index 63d46e50..f45af6e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-04-15 David Athay + + * src/gui/guildlistbox.cpp, src/gui/guildwindow.h + src/gui/widgets/tabbedarea.h, src/gui/widgets/tabbedarea.cpp, + src/gui/guildlistbox.h, src/gui/guildwindow.cpp, + src/net/guildhandler.cpp, src/net/protocol.h, src/net/chathandler.cpp, + src/net/chatserver/chatserver.cpp, src/net/chatserver/chatserver.h, + src/Makefile.am, data/graphics/gui/circle-green.png + data/graphics/gui/circle-gray.png, tmw.cbp: Added online status of + guild members. + 2008-04-14 Yohann Ferreira * src/CMakeLists.txt: Fixed (again) a compilation error using CMake. diff --git a/data/graphics/gui/circle-gray.png b/data/graphics/gui/circle-gray.png new file mode 100644 index 00000000..719b0b10 Binary files /dev/null and b/data/graphics/gui/circle-gray.png differ diff --git a/data/graphics/gui/circle-green.png b/data/graphics/gui/circle-green.png new file mode 100644 index 00000000..bab39e05 Binary files /dev/null and b/data/graphics/gui/circle-green.png differ diff --git a/src/Makefile.am b/src/Makefile.am index c46fe481..3cfa64ea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/widgets/layout.h \ gui/widgets/resizegrip.cpp \ gui/widgets/resizegrip.h \ + gui/widgets/tabbedarea.cpp \ + gui/widgets/tabbedarea.h \ gui/box.h \ gui/box.cpp \ gui/browserbox.cpp \ diff --git a/src/gui/guildlistbox.cpp b/src/gui/guildlistbox.cpp index 11661235..1c14fd55 100644 --- a/src/gui/guildlistbox.cpp +++ b/src/gui/guildlistbox.cpp @@ -1,6 +1,6 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright 2008 The Mana World Development Team * * This file is part of The Mana World. * @@ -18,25 +18,32 @@ * 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$ + * $Id $ */ #include "guildlistbox.h" #include "../graphics.h" +#include "../resources/image.h" +#include "../resources/resourcemanager.h" + #include GuildListBox::GuildListBox(): ListBox(NULL) { + onlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-green.png"); + offlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-gray.png"); } -void GuildListBox::draw(gcn::Graphics *graphics) +void GuildListBox::draw(gcn::Graphics *gcnGraphics) { if (!mListModel) return; + Graphics *graphics = static_cast(gcnGraphics); + graphics->setColor(gcn::Color(110, 160, 255)); graphics->setFont(getFont()); @@ -48,17 +55,22 @@ void GuildListBox::draw(gcn::Graphics *graphics) getWidth(), fontHeight)); } - // TODO: Add online status image - // Draw the list elements for (int i = 0, y = 0; i < mListModel->getNumberOfElements(); ++i, y += fontHeight) { - graphics->drawText(mListModel->getElementAt(i), 1, y); + // Draw online status + bool online = mUsers[mListModel->getElementAt(i)]; + Image *icon = online ? onlineIcon : offlineIcon; + if (icon) + graphics->drawImage(icon, 1, y); + // Draw Name + graphics->setColor(gcn::Color(0, 0, 0)); + graphics->drawText(mListModel->getElementAt(i), 33, y); } } - +/* void GuildListBox::setSelected(int selected) { if (!mListModel) @@ -84,14 +96,19 @@ void GuildListBox::setSelected(int selected) distributeValueChangedEvent(); } - +*/ void GuildListBox::mousePressed(gcn::MouseEvent &event) { if (event.getButton() == gcn::MouseEvent::LEFT) { - // TODO: Add guild functions, ie private messaging int y = event.getY(); setSelected(y / getFont()->getHeight()); distributeActionEvent(); } + // TODO: Add guild functions, ie private messaging +} + +void GuildListBox::setOnlineStatus(const std::string &user, bool online) +{ + mUsers[user] = online; } diff --git a/src/gui/guildlistbox.h b/src/gui/guildlistbox.h index 262012a4..0f030d0a 100644 --- a/src/gui/guildlistbox.h +++ b/src/gui/guildlistbox.h @@ -1,6 +1,6 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright 2008 The Mana World Development Team * * This file is part of The Mana World. * @@ -18,17 +18,20 @@ * 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$ + * $Id $ */ #ifndef _TMW_GUI_GUILDLISTBOX_H #define _TMW_GUI_GUILDLISTBOX_H +#include #include #include #include "listbox.h" +class Image; + class GuildListBox : public ListBox { public: @@ -37,22 +40,27 @@ public: */ GuildListBox(); - /** - * Set ListModel - */ - void setList(gcn::ListModel *listModel); - /** * Draws the list box. */ - void draw(gcn::Graphics *graphics); + void draw(gcn::Graphics *gcnGraphics); void mousePressed(gcn::MouseEvent &event); /** * Sets the index of the selected element. */ - void setSelected(int selected); +// void setSelected(int selected); + + /** + * Set whether a member is online or offline + */ + void setOnlineStatus(const std::string &user, bool online); + +private: + Image *onlineIcon; + Image *offlineIcon; + std::map mUsers; }; #endif diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp index 7b69f9bf..7237a870 100644 --- a/src/gui/guildwindow.cpp +++ b/src/gui/guildwindow.cpp @@ -84,7 +84,7 @@ GuildWindow::~GuildWindow() void GuildWindow::update() { - + updateTab(); } void GuildWindow::draw(gcn::Graphics *g) @@ -172,7 +172,7 @@ void GuildWindow::newGuildTab(const std::string &guildName) { // Create new tab - ListBox *list = new ListBox(); + GuildListBox *list = new GuildListBox(); list->setListModel(player_node->getGuild(guildName)); ScrollArea *sa = new ScrollArea(list); sa->setDimension(gcn::Rectangle(5, 5, 135, 250)); @@ -224,7 +224,8 @@ short GuildWindow::getSelectedGuild() return 0; } -void GuildWindow::openAcceptDialog(const std::string &inviterName, const std::string &guildName) +void GuildWindow::openAcceptDialog(const std::string &inviterName, + const std::string &guildName) { std::string msg = inviterName + " has invited you to join the guild " + guildName; chatWindow->chatLog(msg, BY_SERVER); @@ -248,6 +249,17 @@ void GuildWindow::removeTab(int guildId) { gcn::Tab *tab = mGuildTabs->getTab(guild->getName()); mGuildTabs->removeTab(tab); + updateTab(); } mGuildTabs->logic(); } + +void GuildWindow::setOnline(const std::string &guildName, const std::string &member, + bool online) +{ + GuildListBox *box = dynamic_cast(mGuildTabs->getWidget(guildName)); + if (box) + { + box->setOnlineStatus(member, online); + } +} diff --git a/src/gui/guildwindow.h b/src/gui/guildwindow.h index f6cb38fd..b85ca3a5 100644 --- a/src/gui/guildwindow.h +++ b/src/gui/guildwindow.h @@ -112,6 +112,12 @@ public: */ void removeTab(int guildId); + /** + * Set guild member status in userlist + */ + void setOnline(const std::string &guildName, const std::string &member, + bool online); + protected: /** * Get selected guild tab @@ -125,7 +131,6 @@ private: TextDialog *inviteDialog; ConfirmDialog *acceptDialog; TabbedArea *mGuildTabs; - GuildListBox *mGuildMembersList; ScrollArea *mScrollArea; bool mFocus; std::string invitedGuild; diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 6ba27622..20c100e5 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -56,7 +56,6 @@ void TabbedArea::draw(gcn::Graphics *graphics) return; } - std::vector< std::pair >::iterator itr; unsigned int i; for (i = 0; i < mTabs.size(); i++) { @@ -71,3 +70,17 @@ void TabbedArea::draw(gcn::Graphics *graphics) gcn::TabbedArea::draw(graphics); } + +gcn::Widget* TabbedArea::getWidget(const std::string &name) +{ + unsigned int i; + for (i = 0; i < mTabs.size(); i++) + { + if (mTabs[i].first->getCaption() == name) + { + return mTabs[i].second; + } + } + + return NULL; +} diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 42275fae..3f58acde 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -24,6 +24,7 @@ #ifndef _TMW_TABBEDAREA_H #define _TMW_TABBEDAREA_H +#include #include #include @@ -54,6 +55,11 @@ class TabbedArea : public gcn::TabbedArea * Return tab with specified name as caption */ gcn::Tab* getTab(const std::string &name); + + /** + * Return selected tab's widget + */ + gcn::Widget* getWidget(const std::string &name); }; #endif diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp index 4d48865a..d8a228ea 100644 --- a/src/net/chathandler.cpp +++ b/src/net/chathandler.cpp @@ -35,6 +35,7 @@ #include "../game.h" #include "../gui/chat.h" +#include "../gui/guildwindow.h" #include "../utils/tostring.h" @@ -49,6 +50,7 @@ ChatHandler::ChatHandler() CPMSG_LIST_CHANNELS_RESPONSE, CPMSG_PUBMSG, CPMSG_QUIT_CHANNEL_RESPONSE, + CPMSG_LIST_CHANNELUSERS_RESPONSE, /* SMSG_BEING_CHAT, SMSG_PLAYER_CHAT, @@ -106,9 +108,13 @@ void ChatHandler::handleMessage(MessageIn &msg) channelName = msg.readString(); std::string announcement = msg.readString(); std::vector userList; + std::string user; while(msg.getUnreadLength()) { - userList.push_back(msg.readString()); + user = msg.readString(); + if (user == "") + break; + userList.push_back(user); } chatWindow->addChannel(channelId, channelName); chatWindow->createNewChannelTab(channelName); @@ -125,6 +131,8 @@ void ChatHandler::handleMessage(MessageIn &msg) while(msg.getUnreadLength()) { channelName = msg.readString(); + if (channelName == "") + break; std::ostringstream numUsers; numUsers << msg.readInt16(); if(channelName != "") @@ -164,6 +172,19 @@ void ChatHandler::handleMessage(MessageIn &msg) chatWindow->removeChannel(channelId); } break; + + case CPMSG_LIST_CHANNELUSERS_RESPONSE: + channelName = msg.readString(); + while(msg.getUnreadLength()) + { + userNick = msg.readString(); + if (userNick == "") + { + break; + } + guildWindow->setOnline(channelName, userNick, true); + } + break; /* // Received speech from being case SMSG_BEING_CHAT: diff --git a/src/net/chatserver/chatserver.cpp b/src/net/chatserver/chatserver.cpp index 93fdc828..67cb5796 100644 --- a/src/net/chatserver/chatserver.cpp +++ b/src/net/chatserver/chatserver.cpp @@ -128,3 +128,12 @@ void Net::ChatServer::getChannelList() connection->send(msg); } + +void Net::ChatServer::getUserList(const std::string &channel) +{ + MessageOut msg(PCMSG_LIST_CHANNELUSERS); + + msg.writeString(channel); + + connection->send(msg); +} diff --git a/src/net/chatserver/chatserver.h b/src/net/chatserver/chatserver.h index c4e0003d..b49d0c9e 100644 --- a/src/net/chatserver/chatserver.h +++ b/src/net/chatserver/chatserver.h @@ -54,6 +54,8 @@ namespace Net void getChannelList(); + void getUserList(const std::string &channel); + } } diff --git a/src/net/guildhandler.cpp b/src/net/guildhandler.cpp index 494dcdc0..fd23546c 100644 --- a/src/net/guildhandler.cpp +++ b/src/net/guildhandler.cpp @@ -99,20 +99,30 @@ void GuildHandler::handleMessage(MessageIn &msg) if(msg.readInt8() == ERRMSG_OK) { std::string guildMember; + std::string guildName; Guild *guild; + short guildId = msg.readInt16(); guild = player_node->getGuild(guildId); + if (!guild) return; + + guildName = guild->getName(); + while(msg.getUnreadLength()) { guildMember = msg.readString(); if(guildMember != "") { guild->addMember(guildMember); + guildWindow->setOnline(guildName, guildMember, false); } } + guildWindow->updateTab(); + + Net::ChatServer::getUserList(guildName); } } break; @@ -126,6 +136,7 @@ void GuildHandler::handleMessage(MessageIn &msg) if (guild) { guild->addMember(guildMember); + guildWindow->setOnline(guild->getName(), guildMember, false); } guildWindow->updateTab(); } break; diff --git a/src/net/protocol.h b/src/net/protocol.h index 748a4e11..79e1f2ca 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -171,7 +171,7 @@ enum { CPMSG_USERJOINED = 0x0450, // W channel, S name CPMSG_USERLEFT = 0x0451, // W channel, S name PCMSG_LIST_CHANNELUSERS = 0x0460, // S channel - CPMSG_LIST_CHANNELUSERS_RESPONSE = 0x0461, // S users + CPMSG_LIST_CHANNELUSERS_RESPONSE = 0x0461, // S channel, S users XXMSG_INVALID = 0x7FFF }; diff --git a/tmw.cbp b/tmw.cbp index d503d01d..d30bb0e2 100644 --- a/tmw.cbp +++ b/tmw.cbp @@ -303,9 +303,6 @@ - -