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/skillhandler.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src/net/skillhandler.cpp') diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp index e9dc9c19..89009e47 100644 --- a/src/net/skillhandler.cpp +++ b/src/net/skillhandler.cpp @@ -46,20 +46,20 @@ void SkillHandler::handleMessage(MessageIn *msg) switch (msg->getId()) { case SMSG_PLAYER_SKILLS: - msg->readInt16(); // length + msg->readShort(); // length skillCount = (msg->getLength() - 4) / 37; skillDialog->cleanList(); for (int k = 0; k < skillCount; k++) { - Sint16 skillId = msg->readInt16(); - msg->readInt16(); // target type - msg->readInt16(); // unknown - Sint16 level = msg->readInt16(); - Sint16 sp = msg->readInt16(); - msg->readInt16(); // range + 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->readInt8(); + 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->readInt16(); - action.bskill = msg->readInt16(); - action.unused = msg->readInt16(); // unknown - action.success = msg->readInt8(); - action.reason = msg->readInt8(); + 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) { -- 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/skillhandler.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 8da32105732949b4b0273c718d118bcfae70a1c9 Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Mon, 11 Dec 2006 15:47:35 +0000 Subject: Merged 0.0 changes from revision 2825 to 2898 to trunk. --- ChangeLog | 292 +++++++++++++++++++++++- NEWS | 11 + data/CMakeLists.txt | 3 +- data/Makefile.am | 3 +- data/graphics/images/CMakeLists.txt | 1 + data/graphics/images/Makefile.am | 1 + data/graphics/images/error.png | Bin 0 -> 314 bytes src/CMakeLists.txt | 19 +- src/Makefile.am | 19 +- src/action.cpp | 66 ++++++ src/action.h | 61 +++++ src/animatedsprite.cpp | 430 +++++++++--------------------------- src/animatedsprite.h | 131 +++-------- src/animation.cpp | 127 +---------- src/animation.h | 97 ++------ src/base64.cpp | 63 +++--- src/base64.h | 11 +- src/being.cpp | 87 ++++---- src/being.h | 36 +-- src/beingmanager.cpp | 24 +- src/engine.cpp | 147 +----------- src/engine.h | 14 -- src/floor_item.cpp | 4 +- src/floor_item.h | 10 +- src/game.cpp | 94 ++++---- src/graphics.cpp | 3 + src/gui/buy.cpp | 4 +- src/gui/char_select.cpp | 51 +++-- src/gui/char_select.h | 11 +- src/gui/confirm_dialog.cpp | 1 + src/gui/confirm_dialog.h | 2 +- src/gui/debugwindow.cpp | 10 +- src/gui/gui.cpp | 152 +------------ src/gui/gui.h | 38 +--- src/gui/inventorywindow.cpp | 3 +- src/gui/item_amount.cpp | 3 +- src/gui/login.cpp | 1 + src/gui/ok_dialog.cpp | 1 + src/gui/ok_dialog.h | 2 +- src/gui/passwordfield.h | 4 +- src/gui/playerbox.cpp | 37 +--- src/gui/playerbox.h | 24 +- src/gui/popupmenu.cpp | 4 +- src/gui/register.cpp | 1 + src/gui/sell.cpp | 5 +- src/gui/serverdialog.cpp | 1 + src/gui/serverdialog.h | 2 +- src/gui/setup_joystick.cpp | 2 +- src/gui/shop.cpp | 6 +- src/gui/textfield.h | 1 - src/gui/trade.cpp | 36 +-- src/gui/updatewindow.cpp | 2 +- src/gui/viewport.cpp | 392 ++++++++++++++++++++++++++++++++ src/gui/viewport.h | 145 ++++++++++++ src/gui/window.cpp | 3 + src/gui/window.h | 3 +- src/gui/windowcontainer.h | 3 +- src/item.h | 4 +- src/localplayer.cpp | 36 ++- src/localplayer.h | 10 +- src/log.cpp | 23 +- src/main.cpp | 51 ++--- src/map.cpp | 53 +++-- src/map.h | 12 +- src/monster.cpp | 39 +++- src/monster.h | 2 + src/net/beinghandler.cpp | 83 ++++--- src/net/inventoryhandler.cpp | 2 +- src/net/npchandler.cpp | 10 +- src/net/playerhandler.cpp | 18 +- src/net/skillhandler.cpp | 4 +- src/npc.cpp | 17 +- src/npc.h | 8 +- src/openglgraphics.cpp | 3 + src/player.cpp | 109 +++++---- src/player.h | 18 +- src/resources/equipmentdb.cpp | 158 +++++++++++++ src/resources/equipmentdb.h | 52 +++++ src/resources/equipmentinfo.h | 52 +++++ src/resources/image.cpp | 10 +- src/resources/itemdb.cpp | 170 ++++++++++++++ src/resources/itemdb.h | 53 +++++ src/resources/iteminfo.h | 12 +- src/resources/itemmanager.cpp | 173 --------------- src/resources/itemmanager.h | 59 ----- src/resources/mapreader.cpp | 32 +-- src/resources/monsterdb.cpp | 151 +++++++++++++ src/resources/monsterdb.h | 45 ++++ src/resources/monsterinfo.cpp | 70 ++++++ src/resources/monsterinfo.h | 74 +++++++ src/resources/resourcemanager.cpp | 61 +++-- src/resources/resourcemanager.h | 17 +- src/resources/soundeffect.cpp | 19 +- src/resources/spritedef.cpp | 381 ++++++++++++++++++++++++++++++++ src/resources/spritedef.h | 158 +++++++++++++ src/resources/spriteset.h | 6 +- src/sound.cpp | 6 +- src/sound.h | 4 +- src/sprite.h | 2 +- src/utils/wingettimeofday.h | 111 ++++++++++ src/utils/xml.cpp | 54 +++++ src/utils/xml.h | 46 ++++ tmw.cbp | 102 +++++++-- 103 files changed, 3532 insertions(+), 1752 deletions(-) create mode 100644 data/graphics/images/error.png create mode 100644 src/action.cpp create mode 100644 src/action.h create mode 100644 src/gui/viewport.cpp create mode 100644 src/gui/viewport.h create mode 100644 src/resources/equipmentdb.cpp create mode 100644 src/resources/equipmentdb.h create mode 100644 src/resources/equipmentinfo.h create mode 100644 src/resources/itemdb.cpp create mode 100644 src/resources/itemdb.h delete mode 100644 src/resources/itemmanager.cpp delete mode 100644 src/resources/itemmanager.h create mode 100644 src/resources/monsterdb.cpp create mode 100644 src/resources/monsterdb.h create mode 100644 src/resources/monsterinfo.cpp create mode 100644 src/resources/monsterinfo.h create mode 100644 src/resources/spritedef.cpp create mode 100644 src/resources/spritedef.h create mode 100644 src/utils/wingettimeofday.h create mode 100644 src/utils/xml.cpp create mode 100644 src/utils/xml.h (limited to 'src/net/skillhandler.cpp') diff --git a/ChangeLog b/ChangeLog index 807de694..c67d6cd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,16 +1,305 @@ +2006-12-09 Eugenio Favalli + + * data/graphics/sprites/npcs.png: Added pirate NPC. + +2006-12-09 Bjørn Lindeijer + + * src/sprite.h, src/gui/playerbox.h, src/gui/char_select.cpp, + src/gui/playerbox.cpp, src/gui/passwordfield.h,src/gui/char_select.h, + src/gui/textfield.h, src/main.cpp, src/being.cpp, src/player.h, + src/floor_item.h, src/being.h: Use new animation system in character + selection/creation. Shows equipment and allowed for some cleanup. Had + a bit of help from the patch by VictorSan. + +2006-12-08 Bjørn Lindeijer + + * src/base64.cpp, src/base64.h, src/resources/mapreader.cpp: + Downgraded to base64 codec from PHP 3 to resolve licensing issues. + +2006-12-06 Eugenio Favalli + + * The Mana World.dev, tmw.cbp: Updated project files. + +2006-12-06 Philipp Sehmisch + + * src/net/beinghandler.cpp: Fixed crashs when changing equipment. + * data/graphics/tiles/desert1.png, data/graphics/tiles/desert2.png: + More tiling related fixes at the cliffs. + +2006-12-06 Bjørn Lindeijer + + * src/gui/item_amount.cpp: Fixed visibility of item amount window. + +2006-12-05 Philipp Sehmisch + + * data/graphics/tiles/desert1.png: Improved the tiling behavior + of the cliffs (still not gridless but at least the edges fit + together in the most common situations) + +2006-12-04 Bjørn Lindeijer + + * src/game.cpp, src/engine.h, src/gui/windowcontainer.h, + src/gui/viewport.cpp, src/gui/gui.cpp, src/gui/gui.h, + src/gui/debugwindow.cpp, src/gui/inventorywindow.cpp, + src/gui/viewport.h, src/engine.cpp, src/CMakeLists.txt, + src/Makefile.am: Introduced a new class Viewport which combines the + drawing code from Engine with the (rather misplaced) input handling + from the Gui class. Also, it's a Container itself which should allow + for extending it to show Guichan widgets on map coordinates. + +2006-12-03 Bjørn Lindeijer + + * src/sound.cpp, src/monster.cpp, src/sound.h, + src/resources/soundeffect.cpp, src/resources/resourcemanager.cpp: + Don't try to play empty strings as sounds, and don't return a + SoundEffect instance when Mix_Chunk loading failed. + * src/beingmanager.cpp, src/npc.cpp, src/npc.h: Show NPC names. + * src/game.cpp, src/gui/char_server.cpp, src/gui/window.cpp, + src/gui/login.cpp, src/gui/char_select.cpp, src/gui/ok_dialog.cpp, + src/gui/confirm_dialog.cpp, src/gui/ok_dialog.h, src/gui/window.h, + src/gui/confirm_dialog.h, src/gui/register.cpp: Windows now default + to invisible, since this seems the most common case. + +2006-12-02 Philipp Sehmisch + + * data/graphics/sprites/chest-leather-female.png: A little correction + at the female leather shirt by mangamaniac. + +2006-12-01 Philipp Sehmisch + + * src/net/beinghandler.cpp, src/being.h, src/being.cpp, src/monster.h, + src/gui/gui.cpp: Visible equipment slot numbers are now converted by + the beinghandler from eAthena to our system. No more distinction + between monster attacking and player attacking between beinghandler + and the being classes. + * src/being.cpp, src/monster.cpp, src/being.h, src/monster.h: Moved + the monster specific action handling into the monster class. + * monster.cpp, mosterinfo.cpp, monsterinfo.h: Monsters now make sounds + when they attack, gett hurt or die. + * src/being.cpp: Delayed the damage numbers a bit to synchronize them + better with the hurt sounds. + * data/monsters.xml, data/sfx//bat-dying1.ogg, data/sfx/bat-hit1.ogg, + data/sfx/bow_shoot_1.ogg, data/sfx/fire-goblin-hit1.ogg, + data/sfx/fire-goblin-hit2.ogg, data/sfx/fire-goblin-miss1.ogg, + data/sfx/fist-swish.ogg, data/sfx/flower-hit1.ogg, + data/sfx/flower-hit2.ogg, data/sfx/flower-miss1.ogg, + data/sfx/fluffy-hit1.ogg, data/sfx/fluffy-hit2.ogg, + data/sfx/fluffy-hit3.ogg, data/sfx/fluffy-hurt1.ogg, + data/sfx/fluffy-miss1.ogg, data/sfx/knife-hit1.ogg, + data/sfx/knife-miss1.ogg, data/sfx/levelup.ogg, + data/sfx/scorpion-hit1.ogg, data/sfx/scorpion-hit2.ogg, + data/sfx/scorpion-hit3.ogg, data/sfx/scorpion-hit4.ogg, + data/sfx/scorpion-miss1.ogg, data/sfx/short-sword-hit1.ogg, + data/sfx/short-sword-miss1.ogg, data/sfx/shroom-hit1.ogg, + data/sfx/slime-hit1.ogg, data/sfx/Makefile.AM, + data/sfx/CMakeLists.txt: Added a lot of sound effects by Cosmostrator. + +2006-11-30 Bjørn Lindeijer + + * data/maps/Makefile.am: Fixed small trailing slash issue. + * src/player.cpp: Optimized setSex and setWeapon by first loading the + new sprite and then deleting the old one (prevents potentially + unnecessary reload). + * src/net/beinghandler.cpp: Optimized handling of player walk + messages, by first setting the gender right and then setting the + equipment. Gets rid of reload of complete equipment in the case of + female. + +2006-11-30 Eugenio Favalli + + * The Mana World.dev, tmw.cbp: Updated project files. + +2006-11-29 Bjørn Lindeijer + + * src/monster.cpp: Small fix to resource path. + +2006-11-29 Philipp Sehmisch + + * src/resources/equipment.h: Made getSprite return a constant + reference. + * src/resources/monsterdb.cpp, src/resources/monsterdb.h, + src/resources/monsterinfo.cpp, src/resources/monsterinfo.h, + src/Makefile.AM, src/CMakeLists.txt, src/main.cpp: + Added the MonsterDB namespace that reads the monsters.xml + and maps monster IDs to names, sprite definitions and sound effects. + * src/monster.cpp: Get sprite definition filenames from MonsterDB. + * src/engine.cpp: Show monster name when targeting a monster. + * data/monsters.xml, data/graphics/sprites/Makefile.AM, + data/graphics/sprites/CMakeLists.txt, data/graphics/sprites/monster*: + Renamed all monster sprites to more associative names (whew, we got to + train some monkeys for tasks like that). + +2006-11-27 Bjørn Lindeijer + + * tmw.cbp: Updated Code::Blocks project file. + +2006-11-27 Philipp Sehmisch + + * src/log.cpp, src/util/wingettimeofday.h: Added implementation of + gettimeofday() for windows machines. + +2006-11-26 Bjørn Lindeijer + + * src/log.cpp: Higher precision log timestamps. + * src/graphics.cpp, src/gui/gui.cpp, src/openglgraphics.cpp, + src/main.cpp, src/resources/equipmentdb.cpp, + src/resources/resourcemanager.cpp: Added some additional log + statements. + * src/resources/itemdb.cpp: Removed usage of READ_PROP in favour of + XML::getProperty and updated log statements. + * src/resources/image.cpp: Added support for loading TGA images. + +2006-11-26 Björn Steinbrink + + * src/resources/resourcemanager.cpp: Remove unnecessary check for + file existance, loading will just fail with the correct error message. + +2006-11-26 Bjørn Lindeijer + + * src/game.cpp, src/being.cpp, src/net/beinghandler.cpp, src/being.h: + Made Being::mDirection protected, forcing the use of setDirection. + * src/npc.cpp, src/player.cpp, src/animatedsprite.h, src/monster.cpp, + src/resources/resourcemanager.h: Defaulted variant argument to 0 since + this is the most common situation. + * src/resources/spritedef.cpp, src/resources/spritedef.h: Some + refactoring, splitting up the loading into several methods, in + preparation of adding support for including other sprites. + * src/main.cpp: ItemDB needs to be unloaded before deleting the + resource manager instance, since ItemInfo refers to an Image. + +2006-11-26 Philipp Sehmisch + + * src/being.cpp, src/being.h, src/engine.cpp, src/main.cpp, + src/player.cpp, src/player.h, src/resources/equipmentdb.h, + src/resources/equipmentdb.cpp, src/resources/equipmentinfo.h, + src/resources/itemdb.cpp, src/resources/itemdb.h, + data/graphics/images/error.png, data/graphics/sprites/error.xml: + Added the EquipmentDB namespace that reads the equipment.xml, maps + equipment IDs to sprite definition files and thus allows gender + specific equipment sprites. + * data/graphics/sprites/chest-leather-female.png, + data/graphics/sprites/chest-leather-male.png, + data/graphics/sprites/chest-leather-female.xml, + data/graphics/sprites/chest-leather-male.xml, + data/equipment.xml: Added and defined male and female leather shirt as + proof of concept of the gender specific equipment. + * data/graphics/images/Makefile.am, data/graphics/sprites/Makefile.am, + data/Makefile.am, src/Makefile.am, + data/graphics/images/CMakeLists.txt, + data/graphics/sprites/CMakeLists.txt, data/CMakeLists.txt, + src/CMakeLists.txt: Updated Makefiles and CMake Lists. + +2006-11-24 Philipp Sehmisch + + * src/engine.cpp, src/floor_item.cpp, src/item.h, src/main.cpp, + src/gui/buy.cpp, src/gui/popupmenu.cpp, src/gui/sell.cpp, + src/gui/shop.cpp, src/net/inventoryhandler.cpp, + src/resources/itemdb.cpp, src/resources/itemdb.h, + src/resources/iteminfo.h, src/resources/itemmanager.cpp, + src/resources/itemmanager.h: Refactored the Itemmanager class to an + ItemDB namespace. + +2006-11-23 Eugenio Favalli + + * The Mana World.dev, tmw.cbp: Updated project files. + +2006-11-19 Bjørn Lindeijer + + * src/gui/setup_joystick.cpp: Fixed joystick option to show enabled + when the joystick is enabled. + * src/localplayer.cpp, src/game.cpp, src/action.h, src/action.cpp, + src/player.cpp, src/animatedsprite.h, src/being.cpp, src/animation.h, + src/monster.cpp, src/CMakeLists.txt, src/player.h, + src/animatedsprite.cpp, src/localplayer.h, src/animation.cpp, + src/Makefile.am, src/being.h, src/resources/resourcemanager.cpp, + src/resources/spritedef.cpp, src/resources/resourcemanager.h, + src/resources/spriteset.h, src/resources/spritedef.cpp: Separated + sprite definition from playback. + 2006-11-17 Björn Steinbrink * data/graphics/sprites/CMakeLists.txt: Fixed some filenames. +2006-11-17 Wai Ling Tsang + + * src/gui/gui.cpp: Added mouse following ability/feature under + logic(). + * src/gui/gui.h: Added mouseMotion(), mouseRelease() and private + variables for mouse following. + +2006-11-15 Philipp Sehmisch + + * data/graphics/tiles/Woodland_village.png, + data/graphics/tiles/Woodland_village_x2.png, + data/graphics/tiles/Woodland_x2.png, + data/graphics/tiles/Makefile.AM, + data/graphics/tiles/CMakeList.txt, + data/maps/new_9-1.tmx.gz, data/maps/new_14-1.tmx.gz, + data/maps/new_15-1.tmx.gz, data/maps/new_16-1.tmx.gz, + data/maps/new_17-1.tmx.gz, data/maps/new_18-1.tmx.gz, + data/maps/new_19-1.tmx.gz, data/maps/CMakeList.txt, + data/maps/Makefile.AM: + Added woodland village outdoor tileset and maps. Modified gates on + the nearby maps. + +2006-11-15 Bjørn Lindeijer + + * src/animatedsprite.h, src/CMakeLists.txt, src/animatedsprite.cpp, + src/utils/xml.cpp, src/utils/xml.h, src/Makefile.am, + src/resources/mapreader.cpp: Separated getProperty method to an XML + utility namespace. + +2006-11-15 Eugenio Favalli + + * The Mana World.dev, tmw.cbp: Updated project files. + * The Mana World.dev, tmw.cbp: Fixed dynamic linking of libcurl. + +2006-11-14 Bjørn Lindeijer + + * src/action.h, src/action.cpp, src/animation.h, src/CMakeLists.txt, + src/animatedsprite.cpp, src/animation.cpp, src/Makefile.am: Separated + Action class to its own module. + * src/action.h, src/action.cpp, src/animatedsprite.h, src/animation.h, + src/animatedsprite.cpp, src/animation.cpp: Resolve Image* of animation + phase at load time instead of storing just the spriteset index and + looking it up later (checking validity should still be added). Also + calculate animation length during loading instead of summing it up + each time it is requested. + +2006-11-12 Bjørn Lindeijer + + * src/map.cpp, src/map.h: Made pathfinding algorithm cope better with + beings blocking the road. This is done by allowing walking over other + beings, but at an additional cost so that it is preferable to walk + around them. + * src/game.cpp: Worked around a Guichan exception thrown for mice with + many buttons (patch by Roel van Dijk). + 2006-11-11 Björn Steinbrink * src/Makefile.am: Fixed autotools configuration. +2006-11-09 Eugenio Favalli + + * src/main.cpp, src/net/network.cpp, src/net/network.h, + The Mana World.dev, tmw.cbp: Fixed a conflict with Windows headers and + updated project files. + 2006-11-05 Eugenio Favalli * The Mana World.dev, tmw.cbp: Updated project files. Warning: Dev-Cpp will now build objects in the source folder. +2006-11-05 Bjørn Lindeijer + + * src/gui/trade.cpp: Fixed money field to no longer hide below the + bottom of the window. + * src/CMakeLists.txt: Added shoplistbox.h/cpp files. + * src/gui/updatewindow.cpp: Fixed percentage indicator of update + window. + * src/main.cpp, src/net/beinghandler.cpp, src/net/skillhandler.cpp, + src/net/network.cpp: Changed some printf statements to log statements. + 2006-11-05 Bjørn Lindeijer * data/graphics/images/login_wallpaper.png: Reverted to standard @@ -37,6 +326,7 @@ precisions about the total money in it. * src/gui/shop.h, src/gui/shop.cpp, src/gui/sell.cpp: Fixes to Sell dialog. + * src/gui/sell.cpp: Fixes the money value after selling something. 2006-11-05 Björn Steinbrink @@ -78,7 +368,7 @@ 2006-11-04 Philipp Sehmisch - * data/maps/new_17-1.tmx.gz, + * data/maps/new_17-1.tmx.gz, data/graphics/images/minimap_new_17-1.png, data/graphics/images/Makefile.am, data/graphics/images/CMakeLists.txt: diff --git a/NEWS b/NEWS index 4633c39b..f3b586f8 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,14 @@ +0.0.22 (...) +- Added support for female-specific equipment graphics +- Added support for monster sounds +- Changed to new update host (http://updates.themanaworld.org) +- Worked around a Guichan exception thrown for mice with many buttons +- Changed mouse walk to keep following mouse while button is held down +- Extended font support for å and Å. +- Fixed joystick setting not to show disabled when it's actually enabled +- Fixed money field to no longer hide below the bottom of the window +- Fixed pathfinding to allow walking through beings when they block your path + 0.0.21.1 (30 October 2006) - Reload wallpaper after loading updates - Added support for gzip compressed map layer data diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 36259082..e60bfe30 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -7,7 +7,8 @@ ADD_SUBDIRECTORY(maps) ADD_SUBDIRECTORY(sfx) SET(FILES + equipment.xml items.xml ) -INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}) +INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}) \ No newline at end of file diff --git a/data/Makefile.am b/data/Makefile.am index 7d16a1fc..ed080d08 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -4,7 +4,8 @@ SUBDIRS = graphics help icons maps sfx tmwdatadir = $(pkgdatadir)/data tmwdata_DATA = \ + equipment.xml \ items.xml EXTRA_DIST = \ - $(tmwdata_DATA) + $(tmwdata_DATA) \ No newline at end of file diff --git a/data/graphics/images/CMakeLists.txt b/data/graphics/images/CMakeLists.txt index 53f8b3a7..f02cd2ea 100644 --- a/data/graphics/images/CMakeLists.txt +++ b/data/graphics/images/CMakeLists.txt @@ -1,6 +1,7 @@ ADD_SUBDIRECTORY(ambient) SET(FILES + error.png login_wallpaper.png minimap_new_1-1.png minimap_new_14-1.png diff --git a/data/graphics/images/Makefile.am b/data/graphics/images/Makefile.am index cc71b18a..00d9ed7e 100644 --- a/data/graphics/images/Makefile.am +++ b/data/graphics/images/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = ambient imagesdir = $(pkgdatadir)/data/graphics/images images_DATA = \ + error.png \ login_wallpaper.png \ minimap_new_1-1.png \ minimap_new_2-1.png \ diff --git a/data/graphics/images/error.png b/data/graphics/images/error.png new file mode 100644 index 00000000..6fd7c1a8 Binary files /dev/null and b/data/graphics/images/error.png differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4fd8d880..e0b93382 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -155,6 +155,8 @@ SET(SRCS gui/vbox.h gui/windowcontainer.cpp gui/windowcontainer.h + gui/viewport.cpp + gui/viewport.h gui/window.cpp gui/window.h gui/widgets/dropdown.cpp @@ -216,17 +218,24 @@ SET(SRCS resources/ambientoverlay.h resources/buddylist.cpp resources/buddylist.h + resources/equipmentdb.cpp + resources/equipmentdb.h + resources/equipmentinfo.h resources/image.cpp resources/image.h resources/imagewriter.cpp resources/imagewriter.h resources/iteminfo.cpp + resources/itemdb.cpp + resources/itemdb.h resources/iteminfo.h - resources/itemmanager.cpp - resources/itemmanager.h resources/mapreader.cpp resources/mapreader.h resources/music.cpp + resources/monsterdb.h + resources/monsterdb.cpp + resources/monsterinfo.h + resources/monsterinfo.cpp resources/music.h resources/openglsdlimageloader.cpp resources/openglsdlimageloader.h @@ -239,9 +248,15 @@ SET(SRCS resources/soundeffect.cpp resources/soundeffect.h resources/spriteset.cpp + resources/spritedef.h + resources/spritedef.cpp resources/spriteset.h utils/dtor.h utils/tostring.h + utils/xml.cpp + utils/xml.h + action.cpp + action.h animatedsprite.cpp animatedsprite.h animation.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 23c57922..1628df18 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -110,6 +110,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ gui/textfield.h \ gui/trade.cpp \ gui/trade.h \ + gui/viewport.cpp \ + gui/viewport.h \ gui/window.cpp \ gui/window.h \ gui/windowcontainer.cpp \ @@ -179,16 +181,23 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ net/gameserver/player.h \ resources/ambientoverlay.cpp \ resources/ambientoverlay.h \ + resources/equipmentdb.cpp \ + resources/equipmentdb.h \ + resources/equipmentinfo.h \ resources/image.cpp \ resources/image.h \ resources/imagewriter.cpp \ resources/imagewriter.h \ + resources/itemdb.cpp \ + resources/itemdb.h \ resources/iteminfo.h \ resources/iteminfo.cpp \ - resources/itemmanager.cpp \ - resources/itemmanager.h \ resources/mapreader.cpp \ resources/mapreader.h \ + resources/monsterdb.h \ + resources/monsterdb.cpp \ + resources/monsterinfo.h \ + resources/monsterinfo.cpp \ resources/music.h \ resources/music.cpp \ resources/openglsdlimageloader.h \ @@ -201,12 +210,18 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ resources/sdlimageloader.cpp \ resources/soundeffect.h \ resources/soundeffect.cpp \ + resources/spritedef.h \ + resources/spritedef.cpp \ resources/spriteset.h \ resources/spriteset.cpp \ resources/buddylist.h \ resources/buddylist.cpp \ utils/dtor.h \ utils/tostring.h \ + utils/xml.cpp \ + utils/xml.h \ + action.cpp \ + action.h \ animatedsprite.cpp \ animatedsprite.h \ animation.cpp \ diff --git a/src/action.cpp b/src/action.cpp new file mode 100644 index 00000000..148ea105 --- /dev/null +++ b/src/action.cpp @@ -0,0 +1,66 @@ +/* + * 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 "action.h" + +#include + +#include "animation.h" +#include "utils/dtor.h" + + +Action::Action() +{ +} + +Action::~Action() +{ + std::for_each(mAnimations.begin(), mAnimations.end(), + make_dtor(mAnimations)); +} + +Animation* +Action::getAnimation(int direction) const +{ + Animations::const_iterator i = mAnimations.find(direction); + + // When the direction isn't defined, try the default + if (i == mAnimations.end()) + { + i = mAnimations.find(0); + } + + return (i == mAnimations.end()) ? NULL : i->second; +} + +void +Action::setAnimation(int direction, Animation *animation) +{ + // Set first direction as default direction + if (mAnimations.empty()) + { + mAnimations[0] = animation; + } + + mAnimations[direction] = animation; +} diff --git a/src/action.h b/src/action.h new file mode 100644 index 00000000..8d5e8d11 --- /dev/null +++ b/src/action.h @@ -0,0 +1,61 @@ +/* + * 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_ACTION_H +#define _TMW_ACTION_H + +#include + +#include + +class Animation; + +/** + * An action consists of several animations, one for each direction. + */ +class Action +{ + public: + /** + * Constructor. + */ + Action(); + + /** + * Destructor. + */ + ~Action(); + + void + setAnimation(int direction, Animation *animation); + + Animation* + getAnimation(int direction) const; + + protected: + typedef std::map Animations; + typedef Animations::iterator AnimationIterator; + Animations mAnimations; +}; + +#endif diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp index 3815f04a..46369c80 100644 --- a/src/animatedsprite.cpp +++ b/src/animatedsprite.cpp @@ -24,401 +24,177 @@ #include "animatedsprite.h" #include "animation.h" +#include "action.h" #include "graphics.h" #include "log.h" #include "resources/resourcemanager.h" #include "resources/spriteset.h" +#include "resources/image.h" -AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant): - mAction(NULL), +#include "utils/xml.h" + +#include + +AnimatedSprite::AnimatedSprite(SpriteDef *sprite): mDirection(DIRECTION_DOWN), mLastTime(0), - mSpeed(1.0f), - mAnimationFile(animationFile) + mFrameIndex(0), + mFrameTime(0), + mSprite(sprite), + mAction(0), + mAnimation(0), + mFrame(0) { - int size; - ResourceManager *resman = ResourceManager::getInstance(); - char *data = (char*)resman->loadFile(animationFile.c_str(), size); - - if (!data) { - logger->error("Animation: Could not find " + animationFile + "!"); - } - - xmlDocPtr doc = xmlParseMemory(data, size); - free(data); - - if (!doc) { - logger->error( - "Animation: Error while parsing animation definition file!"); - } - - xmlNodePtr node = xmlDocGetRootElement(doc); - if (!node || !xmlStrEqual(node->name, BAD_CAST "sprite")) { - logger->error( - "Animation: this is not a valid animation definition file!"); - } - - // Get the variant - int variant_num = getProperty(node, "variants", 0); - int variant_offset = getProperty(node, "variant_offset", 0); - - if (variant_num > 0 && variant < variant_num ) { - variant_offset *= variant; - } else { - variant_offset = 0; - } + assert(mSprite); - for (node = node->xmlChildrenNode; node != NULL; node = node->next) - { - if (xmlStrEqual(node->name, BAD_CAST "imageset")) - { - int width = getProperty(node, "width", 0); - int height = getProperty(node, "height", 0); - std::string name = getProperty(node, "name", ""); - std::string imageSrc = getProperty(node, "src", ""); - - Spriteset *spriteset = - resman->getSpriteset(imageSrc, width, height); - - if (!spriteset) { - logger->error("Couldn't load spriteset!"); - } - - mSpritesets[name] = spriteset; - } - // get action - else if (xmlStrEqual(node->name, BAD_CAST "action")) - { - std::string actionName = getProperty(node, "name", ""); - std::string imageset = getProperty(node, "imageset", ""); - - if (mSpritesets.find(imageset) == mSpritesets.end()) { - logger->log("Warning: imageset \"%s\" not defined in %s", - imageset.c_str(), - animationFile.c_str()); - - // skip loading animations - continue; - } - - - SpriteAction actionType = makeSpriteAction(actionName); - if (actionType == ACTION_INVALID) - { - logger->log("Warning: Unknown action \"%s\" defined in %s", - actionName.c_str(), - animationFile.c_str()); - continue; - } - Action *action = new Action(); - action->setSpriteset(mSpritesets[imageset]); - mActions[actionType] = action; - - // When first action set it as default direction - if (mActions.empty()) - { - mActions[ACTION_DEFAULT] = action; - } - - - // get animations - for (xmlNodePtr animationNode = node->xmlChildrenNode; - animationNode != NULL; - animationNode = animationNode->next) - { - // We're only interested in animations - if (!xmlStrEqual(animationNode->name, BAD_CAST "animation")) - continue; - - std::string directionName = getProperty(animationNode, "direction", ""); - - SpriteDirection directionType = makeSpriteDirection(directionName); - if (directionType == DIRECTION_INVALID) - { - logger->log("Warning: Unknown direction \"%s\" defined for action %s in %s", - directionName.c_str(), - actionName.c_str(), - animationFile.c_str()); - continue; - } - - Animation *animation = new Animation(); - action->setAnimation(directionType, animation); - - // Get animation phases - for (xmlNodePtr phaseNode = animationNode->xmlChildrenNode; - phaseNode != NULL; - phaseNode = phaseNode->next) - { - int delay = getProperty(phaseNode, "delay", 0); - - if (xmlStrEqual(phaseNode->name, BAD_CAST "frame")) - { - int index = getProperty(phaseNode, "index", -1); - int offsetX = getProperty(phaseNode, "offsetX", 0); - int offsetY = getProperty(phaseNode, "offsetY", 0); - - offsetY -= mSpritesets[imageset]->getHeight() - 32; - offsetX -= mSpritesets[imageset]->getWidth() / 2 - 16; - animation->addPhase(index + variant_offset, delay, - offsetX, offsetY); - } - else if (xmlStrEqual(phaseNode->name, BAD_CAST "sequence")) - { - int start = getProperty(phaseNode, "start", 0); - int end = getProperty(phaseNode, "end", 0); - int offsetY = -mSpritesets[imageset]->getHeight() + 32; - int offsetX = -mSpritesets[imageset]->getWidth() / 2 + 16; - while (end >= start) - { - animation->addPhase(start + variant_offset, - delay, offsetX, offsetY); - start++; - } - } - else if (xmlStrEqual(phaseNode->name, BAD_CAST "end")) - { - animation->addTerminator(); - }; - } // for phaseNode - } // for animationNode - } // if "" else if "" - } // for node - - // Complete missing actions - substituteAction(ACTION_STAND, ACTION_DEFAULT); - substituteAction(ACTION_WALK, ACTION_STAND); - substituteAction(ACTION_WALK, ACTION_RUN); - substituteAction(ACTION_ATTACK, ACTION_STAND); - substituteAction(ACTION_ATTACK_SWING, ACTION_ATTACK); - substituteAction(ACTION_ATTACK_STAB, ACTION_ATTACK_SWING); - substituteAction(ACTION_ATTACK_BOW, ACTION_ATTACK_STAB); - substituteAction(ACTION_ATTACK_THROW, ACTION_ATTACK_SWING); - substituteAction(ACTION_CAST_MAGIC, ACTION_ATTACK_SWING); - substituteAction(ACTION_USE_ITEM, ACTION_CAST_MAGIC); - substituteAction(ACTION_SIT, ACTION_STAND); - substituteAction(ACTION_SLEEP, ACTION_SIT); - substituteAction(ACTION_HURT, ACTION_STAND); - substituteAction(ACTION_DEAD, ACTION_HURT); + // Take possession of the sprite + mSprite->incRef(); // Play the stand animation by default play(ACTION_STAND); - - xmlFreeDoc(doc); -} - -int -AnimatedSprite::getProperty(xmlNodePtr node, const char* name, int def) -{ - int &ret = def; - - xmlChar *prop = xmlGetProp(node, BAD_CAST name); - if (prop) { - ret = atoi((char*)prop); - xmlFree(prop); - } - - return ret; } -std::string -AnimatedSprite::getProperty(xmlNodePtr node, const char* name, - const std::string& def) +AnimatedSprite::AnimatedSprite(const std::string& filename, int variant): + mDirection(DIRECTION_DOWN), + mLastTime(0), + mFrameIndex(0), + mFrameTime(0), + mAnimation(0), + mFrame(0) { - xmlChar *prop = xmlGetProp(node, BAD_CAST name); - if (prop) { - std::string val = (char*)prop; - xmlFree(prop); - return val; - } - - return def; -} + ResourceManager *resman = ResourceManager::getInstance(); + mSprite = resman->getSprite(filename, variant); + assert(mSprite); -void -AnimatedSprite::substituteAction(SpriteAction complete, - SpriteAction with) -{ - if (mActions.find(complete) == mActions.end()) - { - ActionIterator i = mActions.find(with); - if (i != mActions.end()) { - mActions[complete] = i->second; - } - } + // Play the stand animation by default + play(ACTION_STAND); } AnimatedSprite::~AnimatedSprite() { - for (SpritesetIterator i = mSpritesets.begin(); i != mSpritesets.end(); ++i) - { - i->second->decRef(); - } - mSpritesets.clear(); + mSprite->decRef(); } void AnimatedSprite::reset() { - // Reset all defined actions (because of aliases some will be resetted - // multiple times, but this doesn't matter) - for (ActionIterator i = mActions.begin(); i != mActions.end(); ++i) - { - if (i->second) - { - i->second->reset(); - } - } + mFrameIndex = 0; + mFrameTime = 0; + mLastTime = 0; } void -AnimatedSprite::play(SpriteAction action) +AnimatedSprite::play(SpriteAction spriteAction) { - ActionIterator i = mActions.find(action); - - if (i == mActions.end()) + Action *action = mSprite->getAction(spriteAction); + if (!action) { - //logger->log("Warning: no action %u defined for \"%s\"!", - // action, mAnimationFile.c_str()); - mAction = NULL; return; } - if (mAction != i->second) + mAction = action; + Animation *animation = mAction->getAnimation(mDirection); + + if (animation && animation != mAnimation && animation->getLength() > 0) { - mAction = i->second; - //mAction->reset(); + mAnimation = animation; + mFrame = mAnimation->getFrame(0); + + reset(); } } void AnimatedSprite::update(int time) { - bool notFinished = true; // Avoid freaking out at first frame or when tick_time overflows if (time < mLastTime || mLastTime == 0) + { mLastTime = time; + } // If not enough time has passed yet, do nothing - if (time > mLastTime && mAction) + if (time <= mLastTime || !mAnimation) { - Animation *animation = mAction->getAnimation(mDirection); - if (animation != NULL) { - notFinished = animation->update((unsigned int)(time - mLastTime));} - mLastTime = time; + return; } - if (!notFinished) + unsigned int dt = time - mLastTime; + mLastTime = time; + + if (!updateCurrentAnimation(dt)) { + // Animation finished, reset to default play(ACTION_STAND); } } bool -AnimatedSprite::draw(Graphics* graphics, Sint32 posX, Sint32 posY) const +AnimatedSprite::updateCurrentAnimation(unsigned int time) { - if (!mAction) + if (!mFrame || Animation::isTerminator(*mFrame)) + { return false; + } - Animation *animation = mAction->getAnimation(mDirection); - if (animation == NULL) return false; + mFrameTime += time; - int phase = animation->getCurrentPhase(); - if (phase < 0) - return false; + while (mFrameTime > mFrame->delay && mFrame->delay > 0) + { + mFrameTime -= mFrame->delay; + mFrameIndex++; - Spriteset *spriteset = mAction->getSpriteset(); - Image *image = spriteset->get(phase); - Sint32 offsetX = animation->getOffsetX(); - Sint32 offsetY = animation->getOffsetY(); - return graphics->drawImage(image, posX + offsetX, posY + offsetY); -} + if (mFrameIndex == mAnimation->getLength()) + { + mFrameIndex = 0; + } -int -AnimatedSprite::getWidth() const -{ - return mAction ? mAction->getSpriteset()->getWidth() : 0; -} + mFrame = mAnimation->getFrame(mFrameIndex); -int -AnimatedSprite::getHeight() const -{ - return mAction ? mAction->getSpriteset()->getHeight() : 0; + if (Animation::isTerminator(*mFrame)) + { + mAnimation = 0; + mFrame = 0; + return false; + } + } + + return true; } -SpriteAction -AnimatedSprite::makeSpriteAction(const std::string& action) +bool +AnimatedSprite::draw(Graphics* graphics, int posX, int posY) const { - if (action == "" || action == "default") { - return ACTION_DEFAULT; - } - if (action == "stand") { - return ACTION_STAND; - } - else if (action == "walk") { - return ACTION_WALK; - } - else if (action == "run") { - return ACTION_RUN; - } - else if (action == "attack") { - return ACTION_ATTACK; - } - else if (action == "attack_swing") { - return ACTION_ATTACK_SWING; - } - else if (action == "attack_stab") { - return ACTION_ATTACK_STAB; - } - else if (action == "attack_bow") { - return ACTION_ATTACK_BOW; - } - else if (action == "attack_throw") { - return ACTION_ATTACK_THROW; - } - else if (action == "cast_magic") { - return ACTION_CAST_MAGIC; - } - else if (action == "use_item") { - return ACTION_USE_ITEM; - } - else if (action == "sit") { - return ACTION_SIT; - } - else if (action == "sleep") { - return ACTION_SLEEP; - } - else if (action == "hurt") { - return ACTION_HURT; - } - else if (action == "dead") { - return ACTION_DEAD; - } - else { - return ACTION_INVALID; + if (!mFrame || !mFrame->image) + { + return false; } + + return graphics->drawImage(mFrame->image, + posX + mFrame->offsetX, + posY + mFrame->offsetY); } -SpriteDirection -AnimatedSprite::makeSpriteDirection(const std::string& direction) +void +AnimatedSprite::setDirection(SpriteDirection direction) { - if (direction == "" || direction == "default") { - return DIRECTION_DEFAULT; - } - else if (direction == "up") { - return DIRECTION_UP; - } - else if (direction == "left") { - return DIRECTION_LEFT; - } - else if (direction == "right") { - return DIRECTION_RIGHT; - } - else if (direction == "down") { - return DIRECTION_DOWN; + if (mDirection != direction) + { + mDirection = direction; + + if (!mAction) + { + return; + } + + Animation *animation = mAction->getAnimation(mDirection); + + if (animation && animation != mAnimation && animation->getLength() > 0) + { + mAnimation = animation; + mFrame = mAnimation->getFrame(0); + reset(); + } } - else { - return DIRECTION_INVALID; - }; } diff --git a/src/animatedsprite.h b/src/animatedsprite.h index bda612ab..4e485f14 100644 --- a/src/animatedsprite.h +++ b/src/animatedsprite.h @@ -24,56 +24,34 @@ #ifndef _TMW_ANIMATEDSPRITE_H #define _TMW_ANIMATEDSPRITE_H +#include "resources/spritedef.h" + #include #include -#include - -#include -class Action; class Graphics; -class Spriteset; - -enum SpriteAction -{ - ACTION_DEFAULT = 0, - ACTION_STAND, - ACTION_WALK, - ACTION_RUN, - ACTION_ATTACK, - ACTION_ATTACK_SWING, - ACTION_ATTACK_STAB, - ACTION_ATTACK_BOW, - ACTION_ATTACK_THROW, - ACTION_CAST_MAGIC, - ACTION_USE_ITEM, - ACTION_SIT, - ACTION_SLEEP, - ACTION_HURT, - ACTION_DEAD, - ACTION_INVALID -}; - -enum SpriteDirection -{ - DIRECTION_DEFAULT = 0, - DIRECTION_DOWN, - DIRECTION_UP, - DIRECTION_LEFT, - DIRECTION_RIGHT, - DIRECTION_INVALID -}; +struct AnimationPhase; /** - * Defines a class to load an animation. + * Animates a sprite by adding playback state. */ class AnimatedSprite { public: /** * Constructor. + * @param sprite the sprite to animate */ - AnimatedSprite(const std::string& animationFile, int variant); + AnimatedSprite(SpriteDef *sprite); + + /** + * A convenience constructor, which will request the sprite to animate + * from the resource manager. + * + * @param filename the file of the sprite to animate + * @param variant the sprite variant + */ + AnimatedSprite(const std::string& filename, int variant = 0); /** * Destructor. @@ -81,8 +59,7 @@ class AnimatedSprite ~AnimatedSprite(); /** - * Resets the animated sprite. This is used to synchronize several - * animated sprites. + * Resets the animated sprite. */ void reset(); @@ -97,84 +74,36 @@ class AnimatedSprite * Inform the animation of the passed time so that it can output the * correct animation phase. */ - void update(int time); + void + update(int time); /** * Draw the current animation phase at the coordinates given in screen * pixels. */ bool - draw(Graphics* graphics, Sint32 posX, Sint32 posY) const; - - /** - * gets the width in pixels of the current animation phase. - */ - int - getWidth() const; - - /** - * gets the height in pixels of the current animation phase. - */ - int - getHeight() const; + draw(Graphics* graphics, int posX, int posY) const; /** * Sets the direction. */ void - setDirection(SpriteDirection direction) - { - mDirection = direction; - } + setDirection(SpriteDirection direction); private: - /** - * When there are no animations defined for the action "complete", its - * animations become a copy of those of the action "with". - */ - void - substituteAction(SpriteAction complete, SpriteAction with); - - /** - * Gets an integer property from an xmlNodePtr. - * - * TODO: Same function is present in MapReader. Should probably be - * TODO: shared in a static utility class. - */ - static int - getProperty(xmlNodePtr node, const char *name, int def); - - /** - * Gets a string property from an xmlNodePtr. - */ - static std::string - getProperty(xmlNodePtr node, const char *name, const std::string &def); - - /** - * Converts a string into a SpriteAction enum. - */ - static SpriteAction - makeSpriteAction(const std::string &action); - - /** - * Converts a string into a SpriteDirection enum. - */ - static SpriteDirection - makeSpriteDirection(const std::string &direction); - + bool + updateCurrentAnimation(unsigned int dt); - typedef std::map Spritesets; - typedef Spritesets::iterator SpritesetIterator; + SpriteDirection mDirection; /**< The sprite direction. */ + int mLastTime; /**< The last time update was called. */ - typedef std::map Actions; - typedef Actions::iterator ActionIterator; + unsigned int mFrameIndex; /**< The index of the current frame. */ + unsigned int mFrameTime; /**< The time since start of frame. */ - Spritesets mSpritesets; - Actions mActions; - Action *mAction; - SpriteDirection mDirection; - int mLastTime; - float mSpeed; + SpriteDef *mSprite; /**< The sprite definition. */ + Action *mAction; /**< The currently active action. */ + Animation *mAnimation; /**< The currently active animation. */ + AnimationPhase *mFrame; /**< The currently active frame. */ std::string mAnimationFile; }; diff --git a/src/animation.cpp b/src/animation.cpp index 98a4abb8..67fdae11 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -27,138 +27,29 @@ #include "utils/dtor.h" -Animation::Animation() +Animation::Animation(): + mDuration(0) { - reset(); } void -Animation::reset() +Animation::addPhase(Image *image, unsigned int delay, int offsetX, int offsetY) { - mTime = 0; - iCurrentPhase = mAnimationPhases.begin(); -} - - -bool -Animation::update(unsigned int time) -{ - mTime += time; - if (mAnimationPhases.empty()) - return true; - if (isTerminator(*iCurrentPhase)) - return false; - - unsigned int delay = iCurrentPhase->delay; - - while (mTime > delay) - { - if (!delay) - return true; - mTime -= delay; - iCurrentPhase++; - if (iCurrentPhase == mAnimationPhases.end()) - { - iCurrentPhase = mAnimationPhases.begin(); - } - if (isTerminator(*iCurrentPhase)) - return false; - delay = iCurrentPhase->delay; - } - return true; -} - - -int -Animation::getCurrentPhase() const -{ - return mAnimationPhases.empty() ? -1 : iCurrentPhase->image; -} - - -void -Animation::addPhase(int image, unsigned int delay, int offsetX, int offsetY) -{ - //add new phase to animation list - AnimationPhase newPhase = { image, delay, offsetX, offsetY}; + // Add new phase to animation list + AnimationPhase newPhase = { image, delay, offsetX, offsetY }; mAnimationPhases.push_back(newPhase); - //reset animation circle - iCurrentPhase = mAnimationPhases.begin(); + mDuration += delay; } void Animation::addTerminator() { - AnimationPhase terminator = { -1, 0, 0, 0}; - mAnimationPhases.push_back(terminator); - iCurrentPhase = mAnimationPhases.begin(); + addPhase(NULL, 0, 0, 0); } bool -Animation::isTerminator(AnimationPhase candidate) -{ - return (candidate.image < 0); -} - -int -Animation::getLength() -{ - if (mAnimationPhases.empty()) - return 0; - - std::list::iterator i; - int length = 0; - for (i = mAnimationPhases.begin(); i != mAnimationPhases.end(); i++) - { - length += i->delay; - } - return length; -} - -Action::Action(): - mSpriteset(NULL) -{ -} - -Action::~Action() -{ - std::for_each(mAnimations.begin(), mAnimations.end(), make_dtor(mAnimations)); - mAnimations.clear(); -} - -Animation* -Action::getAnimation(int direction) const -{ - Animations::const_iterator i = mAnimations.find(direction); - - // When the direction isn't defined, try the default - if (i == mAnimations.end()) - { - i = mAnimations.find(0); - } - - return (i == mAnimations.end()) ? NULL : i->second; -} - -void -Action::setAnimation(int direction, Animation *animation) -{ - // Set first direction as default direction - if (mAnimations.empty()) - { - mAnimations[0] = animation; - } - - mAnimations[direction] = animation; -} - -void -Action::reset() +Animation::isTerminator(const AnimationPhase candidate) { - for (AnimationIterator i = mAnimations.begin(); - i != mAnimations.end(); ++i) - { - i->second->reset(); - } + return (candidate.image == NULL); } diff --git a/src/animation.h b/src/animation.h index 605d8cb1..85e950d7 100644 --- a/src/animation.h +++ b/src/animation.h @@ -24,8 +24,7 @@ #ifndef _TMW_ANIMATION_H #define _TMW_ANIMATION_H -#include -#include +#include #include @@ -34,10 +33,12 @@ class Spriteset; /** * A single frame in an animation, with a delay and an offset. + * + * TODO: Rename this struct to Frame */ struct AnimationPhase { - int image; + Image *image; unsigned int delay; int offsetX; int offsetY; @@ -55,106 +56,46 @@ class Animation */ Animation(); - /** - * Restarts the animation from the first frame. - */ - void - reset(); - /** * Appends a new animation at the end of the sequence */ void - addPhase(int image, unsigned int delay, int offsetX, int offsetY); + addPhase(Image *image, unsigned int delay, int offsetX, int offsetY); /** * Appends an animation terminator that states that the animation - * should not loop + * should not loop. */ void addTerminator(); /** - * Updates animation phase. - * true indicates a still running animation while false indicates a - * finished animation + * Returns the frame at the specified index. */ - bool - update(unsigned int time); - - int - getCurrentPhase() const; + AnimationPhase* + getFrame(int index) { return &(mAnimationPhases[index]); } /** - * Returns the x offset of the current frame. + * Returns the length of this animation in frames. */ - int - getOffsetX() const { return iCurrentPhase->offsetX; }; + unsigned int + getLength() const { return mAnimationPhases.size(); } /** - * Returns the y offset of the current frame. + * Returns the duration of this animation. */ int - getOffsetY() const { return iCurrentPhase->offsetY; }; + getDuration() const { return mDuration; } /** - * Returns the length of this animation. + * Determines whether the given animation frame is a terminator. */ - int - getLength(); - - protected: - static bool isTerminator(AnimationPhase); - std::list mAnimationPhases; - std::list::iterator iCurrentPhase; - unsigned int mTime; -}; - -/** - * An action consists of several animations, one for each direction. - */ -class Action -{ - public: - /** - * Constructor. - */ - Action(); - - /** - * Destructor. - */ - ~Action(); - - /** - * Sets the spriteset used by this action. - */ - void - setSpriteset(Spriteset *spriteset) { mSpriteset = spriteset; } - - /** - * Returns the spriteset used by this action. - */ - Spriteset* - getSpriteset() const { return mSpriteset; } - - void - setAnimation(int direction, Animation *animation); - - /** - * Resets all animations associated with this action. - */ - void - reset(); - - Animation* - getAnimation(int direction) const; + static bool + isTerminator(const AnimationPhase phase); protected: - Spriteset *mSpriteset; - typedef std::map Animations; - typedef Animations::iterator AnimationIterator; - Animations mAnimations; + std::vector mAnimationPhases; + int mDuration; }; #endif diff --git a/src/base64.cpp b/src/base64.cpp index 6d503a53..9a8f6356 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -1,16 +1,27 @@ /* +----------------------------------------------------------------------+ - | PHP version 4.0 | + | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | + | Copyright (c) 1997-2000 PHP Development Team (See Credits file) | +----------------------------------------------------------------------+ - | This source file is subject to version 2.02 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://www.php.net/license/2_02.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program 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 both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | +----------------------------------------------------------------------+ | Author: Jim Winstead (jimw@php.net) | +----------------------------------------------------------------------+ @@ -32,8 +43,8 @@ static char base64_table[] = }; static char base64_pad = '='; -unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length) { - const unsigned char *current = str; +unsigned char *php3_base64_encode(const unsigned char *string, int length, int *ret_length) { + const unsigned char *current = string; int i = 0; unsigned char *result = (unsigned char *)malloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char)); @@ -69,27 +80,13 @@ unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_ } /* as above, but backwards. :) */ -unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length) { - const unsigned char *current = str; +unsigned char *php3_base64_decode(const unsigned char *string, int length, int *ret_length) { + const unsigned char *current = string; int ch, i = 0, j = 0, k; - /* this sucks for threaded environments */ - static short reverse_table[256]; - static int table_built; - unsigned char *result; - - if (++table_built == 1) { - char *chp; - for(ch = 0; ch < 256; ch++) { - chp = strchr(base64_table, ch); - if(chp) { - reverse_table[ch] = chp - base64_table; - } else { - reverse_table[ch] = -1; - } - } - } + char *chp; + + unsigned char *result = (unsigned char *)malloc(length + 1); - result = (unsigned char *)malloc(length + 1); if (result == NULL) { return NULL; } @@ -107,8 +104,9 @@ unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_ if (ch == ' ') ch = '+'; - ch = reverse_table[ch]; - if (ch < 0) continue; + chp = strchr(base64_table, ch); + if (chp == NULL) continue; + ch = chp - base64_table; switch(i % 4) { case 0: @@ -149,4 +147,3 @@ unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_ result[k] = '\0'; return result; } - diff --git a/src/base64.h b/src/base64.h index 5b275c45..ff20ac53 100644 --- a/src/base64.h +++ b/src/base64.h @@ -31,14 +31,7 @@ #ifndef _TMW_BASE64_H #define _TMW_BASE64_H -extern unsigned char *php_base64_encode(const unsigned char *, int, int *); -extern unsigned char *php_base64_decode(const unsigned char *, int, int *); +extern unsigned char *php3_base64_encode(const unsigned char *, int, int *); +extern unsigned char *php3_base64_decode(const unsigned char *, int, int *); #endif /* _TMW_BASE64_H */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ diff --git a/src/being.cpp b/src/being.cpp index 50a2dc35..9cd0af0d 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -49,7 +49,7 @@ PATH_NODE::PATH_NODE(Uint16 iX, Uint16 iY): Being::Being(Uint16 id, Uint16 job, Map *map): mJob(job), - mX(0), mY(0), mDirection(DOWN), + mX(0), mY(0), mAction(STAND), mWalkTime(0), mEmotion(0), mEmotionTime(0), @@ -60,12 +60,15 @@ Being::Being(Uint16 id, Uint16 job, Map *map): mWeapon(0), mWalkSpeed(150), mSpeedModifier(1024), + mDirection(DOWN), mMap(NULL), mHairStyle(0), mHairColor(0), mSpeechTime(0), mDamageTime(0), mShowSpeech(false), mShowDamage(false), - mSprites(VECTOREND_SPRITE, NULL) + mPx(0), mPy(0), + mSprites(VECTOREND_SPRITE, NULL), + mEquipmentSpriteIDs(VECTOREND_SPRITE, 0) { setMap(map); } @@ -110,9 +113,7 @@ void Being::adjustCourse(Uint16 srcX, Uint16 srcY, Uint16 dstX, Uint16 dstY) p1 = mMap->findPath(srcX / 32, srcY / 32, dstX / 32, dstY / 32); if (p1.empty()) { - // No path? Better teleport. - mX = dstX; - mY = dstY; + // No path, but don't teleport since it could be user input. setPath(p1); return; } @@ -189,9 +190,8 @@ void Being::adjustCourse(Uint16 srcX, Uint16 srcY, Uint16 dstX, Uint16 dstY) if (bestRating < 0) { - // Unable to reach the path? Better teleport. - mX = srcX; - mY = srcY; + // Unable to reach the path? Still, don't teleport since it could be + // user input instead of server command. setPath(p1); delete[] p1_dist; return; @@ -263,8 +263,9 @@ Being::setHairStyle(Uint16 style) } void -Being::setVisibleEquipment(Uint8 slot, Uint8 id) +Being::setVisibleEquipment(Uint8 slot, int id) { + mEquipmentSpriteIDs[slot] = id; } void @@ -304,7 +305,7 @@ Being::setMap(Map *map) void Being::setAction(Uint8 action) { - SpriteAction currentAction = ACTION_STAND; + SpriteAction currentAction = ACTION_INVALID; switch (action) { case WALK: @@ -314,37 +315,21 @@ Being::setAction(Uint8 action) currentAction = ACTION_SIT; break; case ATTACK: - if (getType() == MONSTER) + switch (getWeapon()) { - currentAction = ACTION_DEAD; + 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; } - else { - switch (getWeapon()) - { - 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; - } - for (int i = 0; i < VECTOREND_SPRITE; i++) - { - if (mSprites[i]) - { - mSprites[i]->reset(); - } - } - }; - break; - case MONSTER_ATTACK: - currentAction = ACTION_ATTACK; for (int i = 0; i < VECTOREND_SPRITE; i++) { if (mSprites[i]) @@ -353,25 +338,33 @@ Being::setAction(Uint8 action) } } break; + case HURT: + //currentAction = ACTION_HURT; // Buggy: makes the player stop + // attacking and unable to attack + // again until he moves + break; case DEAD: currentAction = ACTION_DEAD; break; - default: + case STAND: currentAction = ACTION_STAND; break; } - for (int i = 0; i < VECTOREND_SPRITE; i++) + if (currentAction != ACTION_INVALID) { - if (mSprites[i]) + for (int i = 0; i < VECTOREND_SPRITE; i++) { - mSprites[i]->play(currentAction); + if (mSprites[i]) + { + mSprites[i]->play(currentAction); + } } + mAction = action; } - - mAction = action; } + void Being::setDirection(Uint8 direction) { @@ -487,7 +480,7 @@ Being::logic() } void -Being::draw(Graphics *graphics, int offsetX, int offsetY) +Being::draw(Graphics *graphics, int offsetX, int offsetY) const { int px = mPx + offsetX; int py = mPy + offsetY; @@ -528,7 +521,7 @@ Being::drawSpeech(Graphics *graphics, Sint32 offsetX, Sint32 offsetY) } // Draw damage above this being - if (mShowDamage) + if (mShowDamage && get_elapsed_time(mDamageTime) > 250) { // Selecting the right color if (mDamage == "miss") diff --git a/src/being.h b/src/being.h index 2804b20b..c95cd191 100644 --- a/src/being.h +++ b/src/being.h @@ -68,14 +68,12 @@ class Being : public Sprite }; enum Action { - STAND = 0, - WALK = 1, - MONSTER_ATTACK = 5, - SIT = 7, - DEAD = 8, - ATTACK = 9, - MONSTER_DEAD = 9, - HIT = 17 + STAND, + WALK, + ATTACK, + SIT, + DEAD, + HURT }; enum Sprite { @@ -101,7 +99,6 @@ class Being : public Sprite std::string mName; /**< Name of character */ Uint16 mJob; /**< Job (player job, npc, monster, ) */ Uint16 mX, mY; /**< Pixel coordinates (tile center) */ - Uint8 mDirection; /**< Facing direction */ Uint8 mAction; /**< Action the being is performing */ Uint16 mWalkTime; Uint8 mEmotion; /**< Currently showing emotion */ @@ -199,7 +196,7 @@ class Being : public Sprite * Sets visible equipments for this being. */ virtual void - setVisibleEquipment(Uint8 slot, Uint8 id); + setVisibleEquipment(Uint8 slot, int id); /** * Sets the sex for this being. @@ -216,7 +213,7 @@ class Being : public Sprite /** * Makes this being take the next step of his path. */ - void + virtual void nextStep(); /** @@ -301,7 +298,13 @@ class Being : public Sprite /** * Sets the current action. */ - void setAction(Uint8 action); + virtual void + setAction(Uint8 action); + + /** + * Returns the current direction. + */ + Uint8 getDirection() const { return mDirection; } /** * Sets the current direction. @@ -314,7 +317,7 @@ class Being : public Sprite * @see Sprite::draw(Graphics, int, int) */ virtual void - draw(Graphics *graphics, Sint32 offsetX, Sint32 offsetY); + draw(Graphics *graphics, Sint32 offsetX, Sint32 offsetY) const; /** * Returns the pixel X coordinate. @@ -343,7 +346,6 @@ class Being : public Sprite getYOffset() const { return getOffset(mStepY); } std::auto_ptr mEquipment; - int mVisibleEquipment[6]; /**< Visible equipments */ protected: /** @@ -363,6 +365,7 @@ class Being : public Sprite Uint16 mWeapon; /**< Weapon picture id */ Uint16 mWalkSpeed; /**< Walking speed */ Uint16 mSpeedModifier; /**< Modifier to keep course on sync (1024 = normal speed) */ + Uint8 mDirection; /**< Facing direction */ Map *mMap; /**< Map on which this being resides */ SpriteIterator mSpriteIterator; @@ -376,11 +379,14 @@ class Being : public Sprite Sint32 mPx, mPy; /**< Pixel coordinates */ std::vector mSprites; + std::vector mEquipmentSpriteIDs; private: + int + getOffset(int step) const; + Sint16 mStepX, mStepY; Uint16 mStepTime; - int getOffset(int) const; }; #endif diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp index 923283b5..14b4ea7e 100644 --- a/src/beingmanager.cpp +++ b/src/beingmanager.cpp @@ -38,7 +38,7 @@ class FindBeingFunctor Uint16 other_y = y + ((being->getType() == Being::NPC) ? 1 : 0); return (being->mX / 32 == x && (being->mY / 32 == y || being->mY / 32 == other_y) && - being->mAction != Being::MONSTER_DEAD && + being->mAction != Being::DEAD && (type == Being::UNKNOWN || being->getType() == type)); } @@ -64,14 +64,7 @@ Being* BeingManager::createBeing(Uint16 id, Uint16 job) Being *being; if (job < 10) - { being = new Player(id, job, mMap); - // XXX Convert for new server - /* - MessageOut outMsg(0x0094); - outMsg.writeLong(id); - */ - } else if (job >= 100 & job < 200) being = new NPC(id, job, mMap); else if (job >= 1000 && job < 1200) @@ -79,6 +72,17 @@ Being* BeingManager::createBeing(Uint16 id, Uint16 job) else being = new Being(id, job, mMap); + // Player or NPC + if (job < 200) + { + // XXX Convert for new server + /* + MessageOut outMsg(mNetwork); + outMsg.writeInt16(0x0094); + outMsg.writeInt32(id);//readLong(2)); + */ + } + mBeings.push_back(being); return being; @@ -127,7 +131,8 @@ void BeingManager::logic() being->logic(); - /*if (being->mAction == Being::MONSTER_DEAD && being->mFrame >= 20) + /* + if (being->mAction == Being::DEAD && being->mFrame >= 20) { delete being; i = mBeings.erase(i); @@ -168,7 +173,6 @@ Being* BeingManager::findNearestLivingBeing(Uint16 x, Uint16 y, int maxdist, if ((being->getType() == type || type == Being::UNKNOWN) && (d < dist || closestBeing == NULL) // it is closer && being->mAction != Being::DEAD // no dead beings - && being->mAction != Being::MONSTER_DEAD ) { dist = d; diff --git a/src/engine.cpp b/src/engine.cpp index 231313c4..30f0097e 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -39,9 +39,10 @@ #include "gui/gui.h" #include "gui/minimap.h" +#include "gui/viewport.h" -#include "resources/itemmanager.h" #include "resources/mapreader.h" +#include "resources/monsterdb.h" #include "resources/resourcemanager.h" #include "resources/spriteset.h" @@ -51,16 +52,12 @@ extern Minimap *minimap; char itemCurrenyQ[10] = "0"; -int camera_x, camera_y; - -ItemManager *itemDb; /**< Item database object */ Spriteset *emotionset; Spriteset *npcset; std::vector weaponset; Engine::Engine(): - mShowDebugPath(false), mCurrentMap(NULL) { // Load the sprite sets @@ -82,9 +79,6 @@ Engine::Engine(): if (!npcset) logger->error("Unable to load NPC spriteset!"); if (!emotionset) logger->error("Unable to load emotions spriteset!"); - - // Initialize item manager - itemDb = new ItemManager(); } Engine::~Engine() @@ -96,8 +90,6 @@ Engine::~Engine() std::for_each(weaponset.begin(), weaponset.end(), std::mem_fun(&Spriteset::decRef)); weaponset.clear(); - - delete itemDb; } void Engine::changeMap(const std::string &mapPath) @@ -125,6 +117,7 @@ void Engine::changeMap(const std::string &mapPath) } minimap->setMapImage(mapImage); beingManager->setMap(newMap); + viewport->setMap(newMap); // Start playing new music file when necessary std::string oldMusic = ""; @@ -152,139 +145,5 @@ void Engine::logic() void Engine::draw(Graphics *graphics) { - int midTileX = graphics->getWidth() / 2; - int midTileY = graphics->getHeight() / 2; - static int lastTick = tick_time; - - int player_x = player_node->mX - midTileX + player_node->getXOffset(); - int player_y = player_node->mY - midTileY + player_node->getYOffset(); - - scrollLaziness = (int)config.getValue("ScrollLaziness", 32); - scrollRadius = (int)config.getValue("ScrollRadius", 32); - - if (scrollLaziness < 1) - scrollLaziness = 1; //avoids division by zero - - //apply lazy scrolling - int nbTicks = get_elapsed_time(lastTick) / 10; - lastTick += nbTicks; - for (; nbTicks > 0; --nbTicks) - { - if (player_x > view_x + scrollRadius) - { - view_x += (player_x - view_x - scrollRadius) / scrollLaziness; - } - if (player_x < view_x - scrollRadius) - { - view_x += (player_x - view_x + scrollRadius) / scrollLaziness; - } - if (player_y > view_y + scrollRadius) - { - view_y += (player_y - view_y - scrollRadius) / scrollLaziness; - } - if (player_y < view_y - scrollRadius) - { - view_y += (player_y - view_y + scrollRadius) / scrollLaziness; - } - } - - //auto center when player is off screen - if ( player_x - view_x > graphics->getWidth() / 2 - || view_x - player_x > graphics->getWidth() / 2 - || view_y - player_y > graphics->getHeight() / 2 - || player_y - view_y > graphics->getHeight() / 2 - ) - { - view_x = player_x; - view_y = player_y; - }; - - if (mCurrentMap) { - if (view_x < 0) { - view_x = 0; - } - if (view_y < 0) { - view_y = 0; - } - if (view_x > mCurrentMap->getWidth() * 32 - midTileX) { - view_x = mCurrentMap->getWidth() * 32 - midTileX; - } - if (view_y > mCurrentMap->getHeight() * 32 - midTileY) { - view_y = mCurrentMap->getHeight() * 32 - midTileY; - } - } - - camera_x = (int)view_x; - camera_y = (int)view_y; - - // Draw tiles and sprites - if (mCurrentMap != NULL) - { - mCurrentMap->draw(graphics, camera_x, camera_y, 0); - mCurrentMap->draw(graphics, camera_x, camera_y, 1); - mCurrentMap->draw(graphics, camera_x, camera_y, 2); - mCurrentMap->drawOverlay( graphics, - view_x, - view_y, - (int)config.getValue("OverlayDetail", 2) - ); - } - else - { - // When no map is loaded, draw a replacement background - graphics->setColor(gcn::Color(128, 128, 128)); - graphics->fillRectangle(gcn::Rectangle(0, 0, - graphics->getWidth(), graphics->getHeight())); - } - - // Find a path from the player to the mouse, and draw it. This is for debug - // purposes. - if (mShowDebugPath && mCurrentMap != NULL) - { - // Get the current mouse position - int mouseX, mouseY; - SDL_GetMouseState(&mouseX, &mouseY); - - int mouseTileX = (mouseX + camera_x) / 32; - int mouseTileY = (mouseY + camera_y) / 32; - - Path debugPath = mCurrentMap->findPath( - player_node->mX / 32, player_node->mY / 32, - mouseTileX, mouseTileY); - - graphics->setColor(gcn::Color(255, 0, 0)); - for (PathIterator i = debugPath.begin(); i != debugPath.end(); i++) - { - int squareX = i->x * 32 - camera_x + 12; - int squareY = i->y * 32 - camera_y + 12; - - graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8)); - graphics->drawText( - toString(mCurrentMap->getMetaTile(i->x, i->y)->Gcost), - squareX + 4, squareY + 12, gcn::Graphics::CENTER); - } - } - - // Draw player nickname, speech, and emotion sprite as needed - Beings &beings = beingManager->getAll(); - for (BeingIterator i = beings.begin(); i != beings.end(); i++) - { - (*i)->drawSpeech(graphics, -camera_x, -camera_y); - (*i)->drawName(graphics, -camera_x, -camera_y); - (*i)->drawEmotion(graphics, -camera_x, -camera_y); - } - - // Draw target marker if needed - Being *target; - if ((target = player_node->getTarget())) - { - graphics->setFont(speechFont); - graphics->setColor(gcn::Color(255, 255, 255)); - int dy = (target->getType() == Being::PLAYER) ? 90 : 52; - - graphics->drawText("[TARGET]", target->getPixelX() - camera_x + 15, - target->getPixelY() - camera_y - dy, gcn::Graphics::CENTER); - } - gui->draw(); } diff --git a/src/engine.h b/src/engine.h index e8ef7e33..62e82a49 100644 --- a/src/engine.h +++ b/src/engine.h @@ -26,8 +26,6 @@ #include -extern int camera_x, camera_y; - class Graphics; class Map; @@ -67,20 +65,8 @@ class Engine */ void draw(Graphics *graphics); - /** - * Toggles whether the path debug graphics are shown - */ - void toggleDebugPath() { mShowDebugPath = !mShowDebugPath; }; - private: - bool mShowDebugPath; - Map *mCurrentMap; - - int scrollRadius; - int scrollLaziness; - float view_x; // current viewpoint in pixels - float view_y; // current viewpoint in pixels }; extern Engine *engine; diff --git a/src/floor_item.cpp b/src/floor_item.cpp index 9a179a21..f33f7eb4 100644 --- a/src/floor_item.cpp +++ b/src/floor_item.cpp @@ -25,7 +25,7 @@ #include "map.h" -#include "resources/itemmanager.h" +#include "resources/itemdb.h" #include "resources/iteminfo.h" #include "resources/spriteset.h" @@ -42,7 +42,7 @@ FloorItem::FloorItem(unsigned int id, mMap(map) { // Retrieve item image from item info - mImage = itemDb->getItemInfo(itemId).getImage(); + mImage = ItemDB::get(itemId).getImage(); // Add ourselves to the map mSpriteIterator = mMap->addSprite(this); diff --git a/src/floor_item.h b/src/floor_item.h index 386d0759..36f81585 100644 --- a/src/floor_item.h +++ b/src/floor_item.h @@ -53,25 +53,25 @@ class FloorItem : public Sprite * Returns instance id of this item. */ unsigned int - getId() { return mId; } + getId() const { return mId; } /** * Returns the item id. */ unsigned int - getItemId() { return mItemId; } + getItemId() const { return mItemId; } /** * Returns the x coordinate. */ unsigned short - getX() { return mX; } + getX() const { return mX; } /** * Returns the y coordinate. */ unsigned short - getY() { return mY; } + getY() const { return mY; } /** * Returns the pixel y coordinate. @@ -87,7 +87,7 @@ class FloorItem : public Sprite * @see Sprite::draw(Graphics, int, int) */ void - draw(Graphics *graphics, int offsetX, int offsetY) + draw(Graphics *graphics, int offsetX, int offsetY) const { graphics->drawImage(mImage, mX * 32 + offsetX, diff --git a/src/game.cpp b/src/game.cpp index 5052f2ce..15298ec6 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -29,6 +29,7 @@ #include #include +#include #include "beingmanager.h" #include "configuration.h" @@ -42,23 +43,25 @@ #include "gui/buy.h" #include "gui/buysell.h" -#include "gui/chargedialog.h" +//#include "gui/chargedialog.h" #include "gui/chat.h" #include "gui/confirm_dialog.h" +#include "gui/debugwindow.h" #include "gui/equipmentwindow.h" +#include "gui/gui.h" #include "gui/help.h" #include "gui/inventorywindow.h" +#include "gui/menuwindow.h" #include "gui/minimap.h" +#include "gui/ministatus.h" #include "gui/npclistdialog.h" #include "gui/npc_text.h" #include "gui/sell.h" #include "gui/setup.h" #include "gui/skill.h" -#include "gui/menuwindow.h" #include "gui/status.h" -#include "gui/ministatus.h" #include "gui/trade.h" -#include "gui/debugwindow.h" +#include "gui/viewport.h" #include "net/beinghandler.h" #include "net/buysellhandler.h" @@ -85,7 +88,7 @@ bool done = false; volatile int tick_time; volatile int fps = 0, frame = 0; Engine *engine = NULL; -Joystick *joystick; +Joystick *joystick = NULL; extern Window *weightNotice; extern Window *deathNotice; @@ -106,7 +109,7 @@ SkillDialog *skillDialog; Setup* setupWindow; Minimap *minimap; EquipmentWindow *equipmentWindow; -ChargeDialog *chargeDialog; +//ChargeDialog *chargeDialog; TradeWindow *tradeWindow; //BuddyWindow *buddyWindow; HelpWindow *helpWindow; @@ -182,47 +185,23 @@ void createGuiWindows() setupWindow = new Setup(); minimap = new Minimap(); equipmentWindow = new EquipmentWindow(player_node->mEquipment.get()); - chargeDialog = new ChargeDialog(); + //chargeDialog = new ChargeDialog(); tradeWindow = new TradeWindow; //buddyWindow = new BuddyWindow(); helpWindow = new HelpWindow(); debugWindow = new DebugWindow(); // Initialize window positions - int screenW = graphics->getWidth(); - int screenH = graphics->getHeight(); - - chargeDialog->setPosition( - screenW - 5 - chargeDialog->getWidth(), - screenH - chargeDialog->getHeight() - 15); + //chargeDialog->setPosition( + // graphics->getWidth() - 5 - chargeDialog->getWidth(), + // graphics->getHeight() - chargeDialog->getHeight() - 15); - /*buddyWindow->setPosition(10, - minimap->getHeight() + 30);*/ + //buddyWindow->setPosition(10, minimap->getHeight() + 30); // Set initial window visibility -// chatWindow->setSticky(true); -// miniStatusWindow->setSticky(true); -// menuWindow->setSticky(true); - chatWindow->setVisible(true); miniStatusWindow->setVisible(true); - statusWindow->setVisible(false); menuWindow->setVisible(true); - buyDialog->setVisible(false); - sellDialog->setVisible(false); - buySellDialog->setVisible(false); - inventoryWindow->setVisible(false); - npcTextDialog->setVisible(false); - npcListDialog->setVisible(false); - skillDialog->setVisible(false); - //newSkillWindow->setVisible(false); - setupWindow->setVisible(false); - equipmentWindow->setVisible(false); - chargeDialog->setVisible(false); - tradeWindow->setVisible(false); - //buddyWindow->setVisible(false); - helpWindow->setVisible(false); - debugWindow->setVisible(false); } /** @@ -244,7 +223,7 @@ void destroyGuiWindows() delete setupWindow; delete minimap; delete equipmentWindow; - delete chargeDialog; + //delete chargeDialog; //delete newSkillWindow; delete tradeWindow; //delete buddyWindow; @@ -511,13 +490,13 @@ void Game::handleInput() // If none below the player, try the tile in front of // the player if (!item) { - if (player_node->mDirection & Being::UP) + if (player_node->getDirection() & Being::UP) y--; - if (player_node->mDirection & Being::DOWN) + if (player_node->getDirection() & Being::DOWN) y++; - if (player_node->mDirection & Being::LEFT) + if (player_node->getDirection() & Being::LEFT) x--; - if (player_node->mDirection & Being::RIGHT) + if (player_node->getDirection() & Being::RIGHT) x++; item = floorItemManager->findByCoordinates(x, y); @@ -584,7 +563,7 @@ void Game::handleInput() case SDLK_f: // Find path to mouse (debug purpose) - engine->toggleDebugPath(); + viewport->toggleDebugPath(); used = true; break; } @@ -621,8 +600,17 @@ void Game::handleInput() } // Push input to GUI when not used - if (!used) { - guiInput->pushInput(event); + if (!used) + { + try + { + guiInput->pushInput(event); + } + catch (gcn::Exception e) + { + const char* err = e.getMessage().c_str(); + logger->log("Warning: guichan input exception: %s", err); + } } } // End while @@ -633,35 +621,35 @@ void Game::handleInput() !chatWindow->isFocused()) { Uint16 x = player_node->mX / 32, y = player_node->mY / 32; - unsigned char Direction = 0; + unsigned char direction = 0; // Translate pressed keys to movement and direction if (keys[SDLK_UP] || keys[SDLK_KP8] || keys[SDLK_KP7] || keys[SDLK_KP9] || joystick && joystick->isUp()) { - Direction |= Being::UP; + direction |= Being::UP; } else if (keys[SDLK_DOWN] || keys[SDLK_KP2] || keys[SDLK_KP1] || keys[SDLK_KP3] || joystick && joystick->isDown()) { - Direction |= Being::DOWN; + direction |= Being::DOWN; } if (keys[SDLK_LEFT] || keys[SDLK_KP4] || keys[SDLK_KP1] || keys[SDLK_KP7] || joystick && joystick->isLeft()) { - Direction |= Being::LEFT; + direction |= Being::LEFT; } else if (keys[SDLK_RIGHT] || keys[SDLK_KP6] || keys[SDLK_KP3] || keys[SDLK_KP9] || joystick && joystick->isRight()) { - Direction |= Being::RIGHT; + direction |= Being::RIGHT; } - player_node->walk(Direction); + player_node->walk(direction); // Attacking monsters if (keys[SDLK_LCTRL] || keys[SDLK_RCTRL] || @@ -675,13 +663,13 @@ void Game::handleInput() { Uint16 targetX = x, targetY = y; - if (player_node->mDirection & Being::UP) + if (player_node->getDirection() & Being::UP) targetY--; - if (player_node->mDirection & Being::DOWN) + if (player_node->getDirection() & Being::DOWN) targetY++; - if (player_node->mDirection & Being::LEFT) + if (player_node->getDirection() & Being::LEFT) targetX--; - if (player_node->mDirection & Being::RIGHT) + if (player_node->getDirection() & Being::RIGHT) targetX++; // Attack priority is: Monster, Player, auto target diff --git a/src/graphics.cpp b/src/graphics.cpp index 065c0a46..f007470a 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -39,6 +39,9 @@ Graphics::~Graphics() bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) { + logger->log("Setting video mode %dx%d %s", + w, h, fs ? "fullscreen" : "windowed"); + int displayFlags = SDL_ANYFORMAT; mFullscreen = fs; diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index b681b683..9fcf752b 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -32,7 +32,7 @@ #include "../npc.h" -#include "../resources/itemmanager.h" +#include "../resources/itemdb.h" #include "../utils/tostring.h" @@ -266,7 +266,7 @@ void BuyDialog::selectionChanged(const SelectionEvent &event) if (selectedItem > -1) { const ItemInfo &info = - itemDb->getItemInfo(mShopItems->at(selectedItem).id); + ItemDB::get(mShopItems->at(selectedItem).id); mItemDescLabel->setCaption("Description: " + info.getDescription()); mItemEffectLabel->setCaption("Effect: " + info.getEffect()); diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index d825db31..3cb42078 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -83,7 +83,7 @@ CharSelectDialog::CharSelectDialog(LockedArray *charInfo): mNameLabel = new gcn::Label("Name"); mLevelLabel = new gcn::Label("Level"); mMoneyLabel = new gcn::Label("Money"); - mPlayerBox = new PlayerBox(0); + mPlayerBox = new PlayerBox(); int w = 195; int h = 220; @@ -116,8 +116,9 @@ CharSelectDialog::CharSelectDialog(LockedArray *charInfo): add(mLevelLabel); add(mMoneyLabel); - mSelectButton->requestFocus(); setLocationRelativeTo(getParent()); + setVisible(true); + mSelectButton->requestFocus(); updatePlayerInfo(); } @@ -171,7 +172,8 @@ void CharSelectDialog::updatePlayerInfo() { LocalPlayer *pi = mCharInfo->getEntry(); - if (pi) { + if (pi) + { mNameLabel->setCaption(pi->getName()); mLevelLabel->setCaption("Lvl: " + toString(pi->mLevel)); mMoneyLabel->setCaption("Money: " + toString(pi->mMoney)); @@ -181,22 +183,17 @@ void CharSelectDialog::updatePlayerInfo() mDelCharButton->setEnabled(true); mSelectButton->setEnabled(true); } - mPlayerBox->mHairStyle = pi->getHairStyle(); - mPlayerBox->mHairColor = pi->getHairColor(); - mPlayerBox->mSex = pi->getSex(); - mPlayerBox->mShowPlayer = true; - } else { + } + else { mNameLabel->setCaption("Name"); mLevelLabel->setCaption("Level"); mMoneyLabel->setCaption("Money"); mNewCharButton->setEnabled(true); mDelCharButton->setEnabled(false); mSelectButton->setEnabled(false); - - mPlayerBox->mHairStyle = 0; - mPlayerBox->mHairColor = 0; - mPlayerBox->mShowPlayer = false; } + + mPlayerBox->setPlayer(pi); } void CharSelectDialog::attemptCharDelete() @@ -240,6 +237,10 @@ std::string CharSelectDialog::getName() CharCreateDialog::CharCreateDialog(Window *parent, int slot): Window("Create Character", true, parent), mSlot(slot) { + mPlayer = new Player(0, 0, NULL); + mPlayer->setHairStyle(rand() % NR_HAIR_STYLES + 1); + mPlayer->setHairColor(rand() % NR_HAIR_COLORS + 1); + mNameField = new TextField(""); mNameLabel = new gcn::Label("Name:"); mNextHairColorButton = new Button(">", "nextcolor", this); @@ -250,8 +251,7 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): mHairStyleLabel = new gcn::Label("Hair Style:"); mCreateButton = new Button("Create", "create", this); mCancelButton = new Button("Cancel", "cancel", this); - mPlayerBox = new PlayerBox(0); - mPlayerBox->mShowPlayer = true; + mPlayerBox = new PlayerBox(mPlayer); mNameField->setEventId("create"); @@ -290,6 +290,12 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): add(mCancelButton); setLocationRelativeTo(getParent()); + setVisible(true); +} + +CharCreateDialog::~CharCreateDialog() +{ + delete mPlayer; } void CharCreateDialog::action(const std::string &eventId, gcn::Widget *widget) @@ -299,7 +305,9 @@ void CharCreateDialog::action(const std::string &eventId, gcn::Widget *widget) // Attempt to create the character mCreateButton->setEnabled(false); Net::AccountServer::Account::createCharacter( - getName(), mPlayerBox->mHairStyle, mPlayerBox->mHairColor, + getName(), + mPlayer->getHairStyle(), + mPlayer->getHairColor(), 0, // gender 10, // STR 10, // AGI @@ -318,20 +326,19 @@ void CharCreateDialog::action(const std::string &eventId, gcn::Widget *widget) scheduleDelete(); } else if (eventId == "nextcolor") { - mPlayerBox->mHairColor++; + mPlayer->setHairColor(mPlayer->getHairColor() % NR_HAIR_COLORS + 1); } else if (eventId == "prevcolor") { - mPlayerBox->mHairColor += NR_HAIR_COLORS - 1; + int prevColor = mPlayer->getHairColor() + NR_HAIR_COLORS - 2; + mPlayer->setHairColor(prevColor % NR_HAIR_COLORS + 1); } else if (eventId == "nextstyle") { - mPlayerBox->mHairStyle++; + mPlayer->setHairStyle(mPlayer->getHairStyle() % NR_HAIR_STYLES + 1); } else if (eventId == "prevstyle") { - mPlayerBox->mHairStyle += NR_HAIR_STYLES - 1; + int prevStyle = mPlayer->getHairStyle() + NR_HAIR_STYLES - 2; + mPlayer->setHairStyle(prevStyle % NR_HAIR_STYLES + 1); } - - mPlayerBox->mHairColor %= NR_HAIR_COLORS; - mPlayerBox->mHairStyle %= NR_HAIR_STYLES; } std::string CharCreateDialog::getName() diff --git a/src/gui/char_select.h b/src/gui/char_select.h index 6d9d1a83..9d2d77da 100644 --- a/src/gui/char_select.h +++ b/src/gui/char_select.h @@ -31,6 +31,7 @@ #include +class Player; class LocalPlayer; class PlayerBox; @@ -48,7 +49,7 @@ class CharSelectDialog : public Window, public gcn::ActionListener */ CharSelectDialog(LockedArray *charInfo); - void action(const std::string& eventId, gcn::Widget* widget); + void action(const std::string &eventId, gcn::Widget *widget); void updatePlayerInfo(); @@ -103,7 +104,12 @@ class CharCreateDialog : public Window, public gcn::ActionListener */ CharCreateDialog(Window *parent, int slot); - void action(const std::string& eventId, gcn::Widget* widget); + /** + * Destructor. + */ + ~CharCreateDialog(); + + void action(const std::string &eventId, gcn::Widget *widget); std::string getName(); @@ -119,6 +125,7 @@ class CharCreateDialog : public Window, public gcn::ActionListener gcn::Button *mCreateButton; gcn::Button *mCancelButton; + Player *mPlayer; PlayerBox *mPlayerBox; int mSlot; diff --git a/src/gui/confirm_dialog.cpp b/src/gui/confirm_dialog.cpp index ed2f8680..5a70544f 100644 --- a/src/gui/confirm_dialog.cpp +++ b/src/gui/confirm_dialog.cpp @@ -61,6 +61,7 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, setLocationRelativeTo(getParent()); getParent()->moveToTop(this); } + setVisible(true); yesButton->requestFocus(); } diff --git a/src/gui/confirm_dialog.h b/src/gui/confirm_dialog.h index 1c206b03..771ecc36 100644 --- a/src/gui/confirm_dialog.h +++ b/src/gui/confirm_dialog.h @@ -47,7 +47,7 @@ class ConfirmDialog : public Window, public gcn::ActionListener { /** * Called when receiving actions from the widgets. */ - void action(const std::string& eventId, gcn::Widget* widget); + void action(const std::string &eventId, gcn::Widget *widget); }; #endif diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index d467d4d3..f8a4154e 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -72,15 +72,15 @@ DebugWindow::logic() // Get the current mouse position int mouseX, mouseY; SDL_GetMouseState(&mouseX, &mouseY); - int mouseTileX = mouseX / 32 + camera_x; - int mouseTileY = mouseY / 32 + camera_y; + //int mouseTileX = mouseX / 32 + camera_x; + //int mouseTileY = mouseY / 32 + camera_y; mFPSLabel->setCaption("[" + toString(fps) + " FPS"); mFPSLabel->adjustSize(); - mTileMouseLabel->setCaption("[Mouse: " + - toString(mouseTileX) + ", " + toString(mouseTileY) + "]"); - mTileMouseLabel->adjustSize(); + //mTileMouseLabel->setCaption("[Mouse: " + + // toString(mouseTileX) + ", " + toString(mouseTileY) + "]"); + //mTileMouseLabel->adjustSize(); Map *currentMap = engine->getCurrentMap(); if (currentMap != NULL) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 38b17781..fb7144a1 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -35,22 +35,14 @@ #endif #include "focushandler.h" -#include "popupmenu.h" #include "window.h" #include "windowcontainer.h" +#include "viewport.h" -#include "../being.h" -#include "../beingmanager.h" #include "../configlistener.h" #include "../configuration.h" -#include "../engine.h" -#include "../flooritemmanager.h" #include "../graphics.h" -#include "../localplayer.h" #include "../log.h" -#include "../main.h" -#include "../map.h" -#include "../npc.h" #include "../resources/image.h" #include "../resources/resourcemanager.h" @@ -61,7 +53,8 @@ // Guichan stuff Gui *gui; -gcn::SDLInput *guiInput; // GUI input +Viewport *viewport; /**< Viewport on the map. */ +gcn::SDLInput *guiInput; /**< GUI input. */ // Fonts used in showing hits gcn::Font *hitRedFont; @@ -91,9 +84,9 @@ class GuiConfigListener : public ConfigListener Gui::Gui(Graphics *graphics): mHostImageLoader(NULL), mMouseCursor(NULL), - mCustomCursor(false), - mPopupActive(false) + mCustomCursor(false) { + logger->log("Initializing GUI..."); // Set graphics setGraphics(graphics); @@ -122,7 +115,6 @@ Gui::Gui(Graphics *graphics): guiTop->setDimension(gcn::Rectangle(0, 0, graphics->getWidth(), graphics->getHeight())); guiTop->setOpaque(false); - guiTop->addMouseListener(this); Window::setWindowContainer(guiTop); setTop(guiTop); @@ -172,13 +164,15 @@ Gui::Gui(Graphics *graphics): mConfigListener = new GuiConfigListener(this); config.addListener("customcursor", mConfigListener); - mPopup = new PopupMenu(); + // Create the viewport + viewport = new Viewport(); + viewport->setDimension(gcn::Rectangle(0, 0, + graphics->getWidth(), graphics->getHeight())); + guiTop->add(viewport); } Gui::~Gui() { - delete mPopup; - config.removeListener("customcursor", mConfigListener); delete mConfigListener; @@ -193,6 +187,7 @@ Gui::~Gui() delete mGuiFont; delete speechFont; + delete viewport; delete mTop; delete mImageLoader; delete mHostImageLoader; @@ -230,113 +225,6 @@ Gui::draw() mGraphics->popClipArea(); } -void -Gui::mousePress(int mx, int my, int button) -{ - // Mouse pressed on window container (basically, the map) - - // Are we in-game yet? - if (state != STATE_GAME) - return; - - // Check if we are alive and kickin' - if (!player_node || player_node->mAction == Being::DEAD) - return; - - // Check if we are busy - if (current_npc) - return; - - int tilex = (mx + camera_x) / 32; - int tiley = (my + camera_y) / 32; - - // Right click might open a popup - if (button == gcn::MouseInput::RIGHT) - { - Being *being; - FloorItem *floorItem; - - if ((being = beingManager->findBeing(tilex, tiley)) && - being->getType() != Being::LOCALPLAYER) - { - showPopup(mx, my, being); - return; - } - else if((floorItem = floorItemManager->findByCoordinates(tilex, tiley))) - { - showPopup(mx, my, floorItem); - return; - } - } - - // If a popup is active, just remove it - if (mPopupActive) - { - mPopup->setVisible(false); - mPopupActive = false; - return; - } - - // Left click can cause different actions - if (button == gcn::MouseInput::LEFT) - { - Being *being; - FloorItem *item; - - // Interact with some being - if ((being = beingManager->findBeing(tilex, tiley))) - { - switch (being->getType()) - { - case Being::NPC: - dynamic_cast(being)->talk(); - break; - - case Being::MONSTER: - case Being::PLAYER: - if (being->mAction == Being::MONSTER_DEAD) - break; - - player_node->attack(being, true); - break; - - default: - break; - } - } - // Pick up some item - else if ((item = floorItemManager->findByCoordinates(tilex, tiley))) - { - player_node->pickUp(item); - } - // Just walk around - else if (engine->getCurrentMap() && - engine->getCurrentMap()->getWalk(tilex, tiley)) - { - // XXX XXX XXX REALLY UGLY! - Uint8 *keys = SDL_GetKeyState(NULL); - if (!(keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT])) - { - player_node->setDestination(mx + camera_x, my + camera_y); - player_node->stopAttack(); - } - } - } - - if (button == gcn::MouseInput::MIDDLE) - { - // Find the being nearest to the clicked position - Being *target = beingManager->findNearestLivingBeing( - tilex, tiley, - 20, Being::MONSTER); - - if (target) - { - player_node->setTarget(target); - } - } -} - void Gui::setUseCustomCursor(bool customCursor) { @@ -369,21 +257,3 @@ Gui::setUseCustomCursor(bool customCursor) } } } - -void Gui::showPopup(int x, int y, Item *item) -{ - mPopup->showPopup(x, y, item); - mPopupActive = true; -} - -void Gui::showPopup(int x, int y, FloorItem *floorItem) -{ - mPopup->showPopup(x, y, floorItem); - mPopupActive = true; -} - -void Gui::showPopup(int x, int y, Being *being) -{ - mPopup->showPopup(x, y, being); - mPopupActive = true; -} diff --git a/src/gui/gui.h b/src/gui/gui.h index c4c47a88..caf27744 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -25,17 +25,13 @@ #define _TMW_GUI #include -#include #include "../guichanfwd.h" -class Being; -class FloorItem; class GuiConfigListener; class Graphics; class Image; -class Item; -class PopupMenu; +class Viewport; /** * \defgroup GUI Core GUI related classes (widgets) @@ -50,7 +46,7 @@ class PopupMenu; * * \ingroup GUI */ -class Gui : public gcn::Gui, public gcn::MouseListener +class Gui : public gcn::Gui { public: /** @@ -76,12 +72,6 @@ class Gui : public gcn::Gui, public gcn::MouseListener void draw(); - /** - * Handles mouse press on map. - */ - void - mousePress(int mx, int my, int button); - /** * Return game font */ @@ -94,37 +84,17 @@ class Gui : public gcn::Gui, public gcn::MouseListener void setUseCustomCursor(bool customCursor); - /** - * Shows a popup for an item - * TODO Find some way to get rid of Item here - */ - void showPopup(int x, int y, Item *item); - - /** - * Shows a popup for a floor item - * TODO Find some way to get rid of FloorItem here - */ - void showPopup(int x, int y, FloorItem *floorItem); - - /** - * Shows a popup for a being - * TODO Find some way to get rid of Being here - */ - void showPopup(int x, int y, Being *being); - private: GuiConfigListener *mConfigListener; gcn::ImageLoader *mHostImageLoader; /**< For loading images in GL */ gcn::ImageLoader *mImageLoader; /**< For loading images */ - gcn::Font *mGuiFont; /**< The global GUI font */ + gcn::Font *mGuiFont; /**< The global GUI font */ Image *mMouseCursor; /**< Mouse cursor image */ bool mCustomCursor; /**< Show custom cursor */ - - PopupMenu *mPopup; /**< Popup window */ - bool mPopupActive; }; extern Gui *gui; /**< The GUI system */ +extern Viewport *viewport; /**< The viewport */ extern gcn::SDLInput *guiInput; /**< GUI input */ /** diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 452b7c16..7f9ba3b9 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -34,6 +34,7 @@ #include "item_amount.h" #include "itemcontainer.h" #include "scrollarea.h" +#include "viewport.h" #include "../item.h" #include "../localplayer.h" @@ -169,7 +170,7 @@ void InventoryWindow::mouseClick(int x, int y, int button, int count) */ int mx = x + getX(); int my = y + getY(); - gui->showPopup(mx, my, item); + viewport->showPopup(mx, my, item); } } diff --git a/src/gui/item_amount.cpp b/src/gui/item_amount.cpp index 30c899a8..5ebc0213 100644 --- a/src/gui/item_amount.cpp +++ b/src/gui/item_amount.cpp @@ -18,7 +18,7 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id $ + * $Id$ */ #include "item_amount.h" @@ -87,6 +87,7 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item): setContentSize(200, 80); setLocationRelativeTo(getParentWindow()); + setVisible(true); } void ItemAmountWindow::resetAmount() diff --git a/src/gui/login.cpp b/src/gui/login.cpp index 1d9b6e1e..b8d4df2b 100644 --- a/src/gui/login.cpp +++ b/src/gui/login.cpp @@ -102,6 +102,7 @@ LoginDialog::LoginDialog(LoginData *loginData): add(mRegisterButton); setLocationRelativeTo(getParent()); + setVisible(true); if (mUserField->getText().empty()) { mUserField->requestFocus(); diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp index 906fd61f..4f9623d7 100644 --- a/src/gui/ok_dialog.cpp +++ b/src/gui/ok_dialog.cpp @@ -51,6 +51,7 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg, add(okButton); setLocationRelativeTo(getParent()); + setVisible(true); okButton->requestFocus(); } diff --git a/src/gui/ok_dialog.h b/src/gui/ok_dialog.h index 06f703cc..8ae08955 100644 --- a/src/gui/ok_dialog.h +++ b/src/gui/ok_dialog.h @@ -46,7 +46,7 @@ class OkDialog : public Window, public gcn::ActionListener { /** * Called when receiving actions from the widgets. */ - void action(const std::string& eventId, gcn::Widget* widget); + void action(const std::string &eventId, gcn::Widget *widget); }; #endif diff --git a/src/gui/passwordfield.h b/src/gui/passwordfield.h index 15ca85c9..cae1f92e 100644 --- a/src/gui/passwordfield.h +++ b/src/gui/passwordfield.h @@ -21,8 +21,8 @@ * $Id$ */ -#ifndef __PASSWORDFIELD_H__ -#define __PASSWORDFIELD_H__ +#ifndef _TMW_PASSWORDFIELD_H_ +#define _TMW_PASSWORDFIELD_H_ #include "textfield.h" diff --git a/src/gui/playerbox.cpp b/src/gui/playerbox.cpp index 568c3350..5fbe79b7 100644 --- a/src/gui/playerbox.cpp +++ b/src/gui/playerbox.cpp @@ -23,7 +23,7 @@ #include "playerbox.h" -#include "../being.h" +#include "../player.h" #include "../graphics.h" #include "../resources/image.h" @@ -32,17 +32,11 @@ #include "../utils/dtor.h" -extern std::vector hairset; -extern Spriteset *playerset[2]; - int PlayerBox::instances = 0; ImageRect PlayerBox::background; -PlayerBox::PlayerBox(unsigned char sex): - mHairColor(0), - mHairStyle(0), - mSex(sex), - mShowPlayer(false) +PlayerBox::PlayerBox(const Player *player): + mPlayer(player) { setBorderSize(2); @@ -81,29 +75,18 @@ PlayerBox::~PlayerBox() } } -void PlayerBox::draw(gcn::Graphics *graphics) +void +PlayerBox::draw(gcn::Graphics *graphics) { - if (!mShowPlayer) { - return; - } - - // Draw character - dynamic_cast(graphics)->drawImage( - playerset[mSex]->get(0), 23, 12); - - // Draw his hair - if (mHairStyle > 0 && mHairColor < NR_HAIR_COLORS && - mHairStyle < NR_HAIR_STYLES) + if (mPlayer) { - int hf = 5 * mHairColor; - if (hf >= 0 && hf < (int)hairset[mHairStyle]->size()) { - dynamic_cast(graphics)->drawImage( - hairset[mHairStyle - 1]->get(hf), 35, 7); - } + // Draw character + mPlayer->draw(dynamic_cast(graphics), 40, 42); } } -void PlayerBox::drawBorder(gcn::Graphics *graphics) +void +PlayerBox::drawBorder(gcn::Graphics *graphics) { int w, h, bs; bs = getBorderSize(); diff --git a/src/gui/playerbox.h b/src/gui/playerbox.h index ec04eaf6..6bba1b51 100644 --- a/src/gui/playerbox.h +++ b/src/gui/playerbox.h @@ -27,10 +27,10 @@ #include class ImageRect; +class Player; /** - * A box showing a player. Draws the various hair styles a player can have - * currently. + * A box showing a player character. * * \ingroup GUI */ @@ -38,15 +38,24 @@ class PlayerBox : public gcn::ScrollArea { public: /** - * Constructor. + * Constructor. Takes the initial player character that this box should + * display, which defaults to NULL. */ - PlayerBox(unsigned char sex); + PlayerBox(const Player *player = NULL); /** * Destructor. */ ~PlayerBox(); + /** + * Sets a new player character to be displayed by this box. Setting the + * player to NULL causes the box not to draw any + * character. + */ + void + setPlayer(const Player *player) { mPlayer = player; } + /** * Draws the scroll area. */ @@ -57,12 +66,9 @@ class PlayerBox : public gcn::ScrollArea */ void drawBorder(gcn::Graphics *graphics); - unsigned char mHairColor; /**< The hair color index */ - unsigned char mHairStyle; /**< The hair style index */ - unsigned char mSex; /**< Sex */ - bool mShowPlayer; /**< Wether to show the player or not */ - private: + const Player *mPlayer; /**< The character used for display */ + static int instances; static ImageRect background; }; diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index ab81f7d0..c2959e1d 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -40,7 +40,7 @@ #include "../npc.h" #include "../resources/iteminfo.h" -#include "../resources/itemmanager.h" +#include "../resources/itemdb.h" extern std::string tradePartnerName; @@ -106,7 +106,7 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem) mBrowserBox->clearRows(); // Floor item can be picked up (single option, candidate for removal) - std::string name = itemDb->getItemInfo(mFloorItem->getItemId()).getName(); + std::string name = ItemDB::get(mFloorItem->getItemId()).getName(); mBrowserBox->addRow("@@pickup|Pick Up " + name + "@@"); //browserBox->addRow("@@look|Look To@@"); diff --git a/src/gui/register.cpp b/src/gui/register.cpp index 7cef62a2..70cd6dc4 100644 --- a/src/gui/register.cpp +++ b/src/gui/register.cpp @@ -97,6 +97,7 @@ RegisterDialog::RegisterDialog(LoginData *loginData): add(mCancelButton); setLocationRelativeTo(getParent()); + setVisible(true); mUserField->requestFocus(); mUserField->setCaretPosition(mUserField->getText().length()); } diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index fd63633c..499bbd05 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -37,7 +37,7 @@ #include "../npc.h" #include "../resources/iteminfo.h" -#include "../resources/itemmanager.h" +#include "../resources/itemdb.h" #include "../utils/tostring.h" @@ -232,6 +232,7 @@ void SellDialog::action(const std::string &eventId, gcn::Widget *widget) mMaxItems -= mAmountItems; mShopItems->getShop()->at(selectedItem).quantity = mMaxItems; + mPlayerMoney += (mAmountItems * mShopItems->at(selectedItem).price); mAmountItems = 0; mSlider->setValue(0); mSlider->setEnabled(mMaxItems != 0); @@ -274,7 +275,7 @@ void SellDialog::selectionChanged(const SelectionEvent &event) if (selectedItem > -1) { const ItemInfo &info = - itemDb->getItemInfo(mShopItems->at(selectedItem).id); + ItemDB::get(mShopItems->at(selectedItem).id); mItemDescLabel->setCaption("Description: " + info.getDescription()); mItemEffectLabel->setCaption("Effect: " + info.getEffect()); diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 39abd5ed..bd17bff7 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -174,6 +174,7 @@ ServerDialog::ServerDialog(LoginData *loginData): add(mCancelButton); setLocationRelativeTo(getParent()); + setVisible(true); if (mServerNameField->getText().empty()) { mServerNameField->requestFocus(); diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h index 5b265c17..d907f340 100644 --- a/src/gui/serverdialog.h +++ b/src/gui/serverdialog.h @@ -132,7 +132,7 @@ class ServerDialog : public Window, public gcn::ActionListener /** * Called when receiving actions from the widgets. */ - void action(const std::string& eventId, gcn::Widget* widget); + void action(const std::string &eventId, gcn::Widget *widget); private: gcn::TextField *mServerNameField; diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp index d9212728..685d88cf 100644 --- a/src/gui/setup_joystick.cpp +++ b/src/gui/setup_joystick.cpp @@ -42,7 +42,7 @@ Setup_Joystick::Setup_Joystick(): mCalibrateLabel->setPosition(10, 25); mCalibrateButton->setPosition(10, 30 + mCalibrateLabel->getHeight()); - mOriginalJoystickEnabled = (joystick ? joystick->isEnabled() : false); + mOriginalJoystickEnabled = (int)config.getValue("joystickEnabled", 0) != 0; mJoystickEnabled->setMarked(mOriginalJoystickEnabled); mJoystickEnabled->setEventId("joystickEnabled"); diff --git a/src/gui/shop.cpp b/src/gui/shop.cpp index 3f30732a..2d33e8a8 100644 --- a/src/gui/shop.cpp +++ b/src/gui/shop.cpp @@ -23,7 +23,7 @@ #include "shop.h" #include "../utils/tostring.h" -#include "../resources/itemmanager.h" +#include "../resources/itemdb.h" ShopItems::~ShopItems() { @@ -44,11 +44,11 @@ void ShopItems::addItem(short id, int price) { ITEM_SHOP item_shop; - item_shop.name = itemDb->getItemInfo(id).getName() + item_shop.name = ItemDB::get(id).getName() + " " + toString(price) + " GP"; item_shop.price = price; item_shop.id = id; - item_shop.image = itemDb->getItemInfo(id).getImage(); + item_shop.image = ItemDB::get(id).getImage(); mItemsShop.push_back(item_shop); } diff --git a/src/gui/textfield.h b/src/gui/textfield.h index 1ed802d7..4748830c 100644 --- a/src/gui/textfield.h +++ b/src/gui/textfield.h @@ -28,7 +28,6 @@ class ImageRect; - /** * A text field. * diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index 2ac56ae5..82262563 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -48,7 +48,7 @@ TradeWindow::TradeWindow(): mPartnerInventory(new Inventory()) { setWindowName("Trade"); - setDefaultSize(115, 197, 322, 150); + setDefaultSize(115, 197, 332, 209); mAddButton = new Button("Add", "add", this); mOkButton = new Button("Ok", "ok", this); @@ -95,33 +95,33 @@ TradeWindow::TradeWindow(): add(mMoneyField); add(mMoneyLabel); - mMoneyField->setPosition(8 + 60, getHeight() - 20); + gcn::Rectangle area = getChildrenArea(); + int width = area.width; + int height = area.height; + + mMoneyField->setPosition(8 + 60, height - 20); mMoneyField->setWidth(50); - mMoneyLabel->setPosition(8 + 60 + 50 + 6, getHeight() - 20); - mMoneyLabel2->setPosition(8, getHeight() - 20); + mMoneyLabel->setPosition(8 + 60 + 50 + 6, height - 20); + mMoneyLabel2->setPosition(8, height - 20); - mCancelButton->setPosition(getWidth() - 54, getHeight() - 49); - mTradeButton->setPosition(mCancelButton->getX() - 41 - , getHeight() - 49); - mOkButton->setPosition(mTradeButton->getX() - 24, - getHeight() - 49); - mAddButton->setPosition(mOkButton->getX() - 31, - getHeight() - 49); + mCancelButton->setPosition(width - 54, height - 49); + mTradeButton->setPosition(mCancelButton->getX() - 41, height - 49); + mOkButton->setPosition(mTradeButton->getX() - 24, height - 49); + mAddButton->setPosition(mOkButton->getX() - 31, height - 49); - mMyItemContainer->setSize(getWidth() - 24 - 12 - 1, - (INVENTORY_SIZE * 24) / (getWidth() / 24) - 1); - mMyScroll->setSize(getWidth() - 16, (getHeight() - 76) / 2); + mMyItemContainer->setSize(width - 24 - 12 - 1, + (INVENTORY_SIZE * 24) / (width / 24) - 1); + mMyScroll->setSize(width - 16, (height - 76) / 2); - mPartnerItemContainer->setSize(getWidth() - 24 - 12 - 1, - (INVENTORY_SIZE * 24) / (getWidth() / 24) - 1); - mPartnerScroll->setSize(getWidth() - 16, (getHeight() - 76) / 2); + mPartnerItemContainer->setSize(width - 24 - 12 - 1, + (INVENTORY_SIZE * 24) / (width / 24) - 1); + mPartnerScroll->setSize(width - 16, (height - 76) / 2); mItemNameLabel->setPosition(8, mPartnerScroll->getY() + mPartnerScroll->getHeight() + 4); mItemDescriptionLabel->setPosition(8, mItemNameLabel->getY() + mItemNameLabel->getHeight() + 4); - } TradeWindow::~TradeWindow() diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index c29906a1..73343483 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -192,7 +192,7 @@ int UpdaterWindow::updateProgress(void *ptr, if (progress > 1) progress = 1.0f; uw->setLabel( - uw->mCurrentFile + " (" + toString((int)progress * 100) + "%)"); + uw->mCurrentFile + " (" + toString((int) (progress * 100)) + "%)"); uw->setProgress(progress); if (state != STATE_UPDATE || uw->mDownloadStatus == UPDATE_ERROR) diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp new file mode 100644 index 00000000..d0525a2f --- /dev/null +++ b/src/gui/viewport.cpp @@ -0,0 +1,392 @@ +/* + * 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 "viewport.h" + +#include + +#include "gui.h" +#include "popupmenu.h" + +#include "../beingmanager.h" +#include "../configuration.h" +#include "../flooritemmanager.h" +#include "../graphics.h" +#include "../localplayer.h" +#include "../map.h" +#include "../npc.h" + +#include "../resources/monsterdb.h" + +#include "../utils/tostring.h" + +Viewport::Viewport(): + mMap(0), + mViewX(0.0f), + mViewY(0.0f), + mCameraX(0), + mCameraY(0), + mShowDebugPath(false), + mPopupActive(false) +{ + setOpaque(false); + addMouseListener(this); + + mScrollLaziness = (int) config.getValue("ScrollLaziness", 32); + mScrollRadius = (int) config.getValue("ScrollRadius", 32); + + config.addListener("ScrollLaziness", this); + config.addListener("ScrollRadius", this); + + mPopupMenu = new PopupMenu(); +} + +Viewport::~Viewport() +{ + delete mPopupMenu; +} + +void +Viewport::setMap(Map *map) +{ + mMap = map; +} + +void +Viewport::draw(gcn::Graphics *gcnGraphics) +{ + static int lastTick = tick_time; + + if (!mMap || !player_node) + return; + + Graphics *graphics = static_cast(gcnGraphics); + + // Avoid freaking out when tick_time overflows + if (tick_time < lastTick) + { + lastTick = tick_time; + } + + // Calculate viewpoint + int midTileX = graphics->getWidth() / 2; + int midTileY = graphics->getHeight() / 2; + + int player_x = player_node->mX - midTileX + player_node->getXOffset(); + int player_y = player_node->mY - midTileY + player_node->getYOffset(); + + if (mScrollLaziness < 1) + mScrollLaziness = 1; // Avoids division by zero + + // Apply lazy scrolling + while (lastTick < tick_time) + { + if (player_x > mViewX + mScrollRadius) + { + mViewX += (player_x - mViewX - mScrollRadius) / mScrollLaziness; + } + if (player_x < mViewX - mScrollRadius) + { + mViewX += (player_x - mViewX + mScrollRadius) / mScrollLaziness; + } + if (player_y > mViewY + mScrollRadius) + { + mViewY += (player_y - mViewY - mScrollRadius) / mScrollLaziness; + } + if (player_y < mViewY - mScrollRadius) + { + mViewY += (player_y - mViewY + mScrollRadius) / mScrollLaziness; + } + lastTick++; + } + + // Auto center when player is off screen + if ( player_x - mViewX > graphics->getWidth() / 2 + || mViewX - player_x > graphics->getWidth() / 2 + || mViewY - player_y > graphics->getHeight() / 2 + || player_y - mViewY > graphics->getHeight() / 2 + ) + { + mViewX = player_x; + mViewY = player_y; + }; + + if (mMap) { + if (mViewX < 0) { + mViewX = 0; + } + if (mViewY < 0) { + mViewY = 0; + } + if (mViewX > mMap->getWidth() * 32 - midTileX) { + mViewX = mMap->getWidth() * 32 - midTileX; + } + if (mViewY > mMap->getHeight() * 32 - midTileY) { + mViewY = mMap->getHeight() * 32 - midTileY; + } + } + + mCameraX = (int) mViewX; + mCameraY = (int) mViewY; + + // Draw tiles and sprites + if (mMap) + { + mMap->draw(graphics, mCameraX, mCameraY, 0); + mMap->draw(graphics, mCameraX, mCameraY, 1); + mMap->draw(graphics, mCameraX, mCameraY, 2); + mMap->drawOverlay(graphics, mViewX, mViewY, + (int) config.getValue("OverlayDetail", 2)); + } + + // Find a path from the player to the mouse, and draw it. This is for debug + // purposes. + if (mShowDebugPath && mMap) + { + // Get the current mouse position + int mouseX, mouseY; + SDL_GetMouseState(&mouseX, &mouseY); + + int mouseTileX = (mouseX + mCameraX) / 32; + int mouseTileY = (mouseY + mCameraY) / 32; + + Path debugPath = mMap->findPath( + player_node->mX / 32, player_node->mY / 32, + mouseTileX, mouseTileY); + + graphics->setColor(gcn::Color(255, 0, 0)); + for (PathIterator i = debugPath.begin(); i != debugPath.end(); i++) + { + int squareX = i->x * 32 - mCameraX + 12; + int squareY = i->y * 32 - mCameraY + 12; + + graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8)); + graphics->drawText( + toString(mMap->getMetaTile(i->x, i->y)->Gcost), + squareX + 4, squareY + 12, gcn::Graphics::CENTER); + } + } + + // Draw player nickname, speech, and emotion sprite as needed + Beings &beings = beingManager->getAll(); + for (BeingIterator i = beings.begin(); i != beings.end(); i++) + { + (*i)->drawSpeech(graphics, -mCameraX, -mCameraY); + (*i)->drawName(graphics, -mCameraX, -mCameraY); + (*i)->drawEmotion(graphics, -mCameraX, -mCameraY); + } + + // Draw target marker if needed + Being *target; + if ((target = player_node->getTarget())) + { + graphics->setFont(speechFont); + graphics->setColor(gcn::Color(255, 32, 32)); + int dy = (target->getType() == Being::PLAYER) ? 80 : 42; + + std::string mobName = ""; + + if (target->mJob >= 1002) + { + int mobId = target->mJob - 1002; + mobName = MonsterDB::get(mobId).getName(); + + graphics->drawText(mobName, + target->getPixelX() - mCameraX + 15, + target->getPixelY() - mCameraY - dy, + gcn::Graphics::CENTER); + } + } + + // Draw contained widgets + WindowContainer::draw(gcnGraphics); +} + +void +Viewport::logic() +{ + WindowContainer::logic(); + + if (!mMap || !player_node) + return; + + int mouseX, mouseY; + Uint8 button = SDL_GetMouseState(&mouseX, &mouseY); + + if (mPlayerFollowMouse && button & SDL_BUTTON(1) && + mWalkTime != player_node->mWalkTime) + { + player_node->setDestination(mouseX + mCameraX, + mouseY + mCameraY); + mWalkTime = player_node->mWalkTime; + } +} + +void +Viewport::mousePress(int mx, int my, int button) +{ + // Check if we are alive and kickin' + if (!mMap || !player_node || player_node->mAction == Being::DEAD) + return; + + // Check if we are busy + if (current_npc) + return; + + mPlayerFollowMouse = false; + + int tilex = (mx + mCameraX) / 32; + int tiley = (my + mCameraY) / 32; + + // Right click might open a popup + if (button == gcn::MouseInput::RIGHT) + { + Being *being; + FloorItem *floorItem; + + if ((being = beingManager->findBeing(tilex, tiley)) && + being->getType() != Being::LOCALPLAYER) + { + showPopup(mx, my, being); + return; + } + else if((floorItem = floorItemManager->findByCoordinates(tilex, tiley))) + { + showPopup(mx, my, floorItem); + return; + } + } + + // If a popup is active, just remove it + if (mPopupActive) + { + mPopupMenu->setVisible(false); + mPopupActive = false; + return; + } + + // Left click can cause different actions + if (button == gcn::MouseInput::LEFT) + { + Being *being; + FloorItem *item; + + // Interact with some being + if ((being = beingManager->findBeing(tilex, tiley))) + { + switch (being->getType()) + { + case Being::NPC: + dynamic_cast(being)->talk(); + break; + + case Being::MONSTER: + case Being::PLAYER: + if (being->mAction == Being::DEAD) + break; + + player_node->attack(being, true); + break; + + default: + break; + } + } + // Pick up some item + else if ((item = floorItemManager->findByCoordinates(tilex, tiley))) + { + player_node->pickUp(item); + } + // Just walk around + else if (mMap->getWalk(tilex, tiley)) + { + // XXX XXX XXX REALLY UGLY! + Uint8 *keys = SDL_GetKeyState(NULL); + if (!(keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT])) + { + player_node->setDestination(mx + mCameraX, my + mCameraY); + player_node->stopAttack(); + } + mPlayerFollowMouse = true; + } + } + + if (button == gcn::MouseInput::MIDDLE) + { + // Find the being nearest to the clicked position + Being *target = beingManager->findNearestLivingBeing( + tilex, tiley, + 20, Being::MONSTER); + + if (target) + { + player_node->setTarget(target); + } + } +} + +void +Viewport::mouseMotion(int mx, int my) +{ + if (!mMap || !player_node) + return; + + if (mPlayerFollowMouse && mWalkTime == player_node->mWalkTime) + { + player_node->setDestination(mx + mCameraX, my + mCameraY); + } +} + +void +Viewport::mouseRelease(int mx, int my, int button) +{ + mPlayerFollowMouse = false; +} + +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 +Viewport::optionChanged(const std::string &name) +{ + mScrollLaziness = (int) config.getValue("ScrollLaziness", 32); + mScrollRadius = (int) config.getValue("ScrollRadius", 32); +} diff --git a/src/gui/viewport.h b/src/gui/viewport.h new file mode 100644 index 00000000..df78b1da --- /dev/null +++ b/src/gui/viewport.h @@ -0,0 +1,145 @@ +/* + * 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_VIEWPORT_H_ +#define _TMW_VIEWPORT_H_ + +#include + +#include "windowcontainer.h" + +#include "../configlistener.h" + +class Map; +class Being; +class FloorItem; +class Item; +class PopupMenu; + +/** + * The viewport on the map. Displays the current map and handles mouse input + * and the popup menu. + * + * TODO: This class is planned to be extended to allow floating widgets on top + * of it such as NPC messages, which are positioned using map pixel + * coordinates. + */ +class Viewport : public WindowContainer, public gcn::MouseListener, + public ConfigListener +{ + public: + /** + * Constructor. + */ + Viewport(); + + /** + * Destructor. + */ + ~Viewport(); + + /** + * Sets the map displayed by the viewport. + */ + void + setMap(Map *map); + + /** + * Draws the viewport. + */ + void + draw(gcn::Graphics *graphics); + + /** + * Implements player to keep following mouse. + */ + void + logic(); + + /** + * Toggles whether the path debug graphics are shown + */ + void toggleDebugPath() { mShowDebugPath = !mShowDebugPath; } + + /** + * Handles mouse press on map. + */ + void + mousePress(int mx, int my, int button); + + /** + * Handles mouse move on map + */ + void + mouseMotion(int mx, int my); + + /** + * Handles mouse button release on map. + */ + void + mouseRelease(int mx, int my, int button); + + /** + * Shows a popup for an item. + * TODO Find some way to get rid of Item here + */ + void showPopup(int x, int y, Item *item); + + /** + * A relevant config option changed. + */ + void + optionChanged(const std::string &name); + + 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); + + + Map *mMap; /**< The current map. */ + + int mScrollRadius; + int mScrollLaziness; + float mViewX; /**< Current viewpoint in pixels. */ + float mViewY; /**< Current viewpoint in pixels. */ + int mCameraX; + int mCameraY; + bool mShowDebugPath; /**< Show a path from player to pointer. */ + + bool mPlayerFollowMouse; + int mWalkTime; + + PopupMenu *mPopupMenu; /**< Popup menu. */ + bool mPopupActive; +}; + +#endif diff --git a/src/gui/window.cpp b/src/gui/window.cpp index 13d42c78..1960d6ca 100644 --- a/src/gui/window.cpp +++ b/src/gui/window.cpp @@ -113,6 +113,9 @@ Window::Window(const std::string& caption, bool modal, Window *parent): { requestModalFocus(); } + + // Windows are invisible by default + setVisible(false); } Window::~Window() diff --git a/src/gui/window.h b/src/gui/window.h index 51c876e3..158035c0 100644 --- a/src/gui/window.h +++ b/src/gui/window.h @@ -36,7 +36,8 @@ class WindowContainer; /** - * A window. This window can be dragged around and has a title bar. + * A window. This window can be dragged around and has a title bar. Windows are + * invisible by default. * * \ingroup GUI */ diff --git a/src/gui/windowcontainer.h b/src/gui/windowcontainer.h index b860fa3c..df255f84 100644 --- a/src/gui/windowcontainer.h +++ b/src/gui/windowcontainer.h @@ -27,7 +27,8 @@ #include /** - * A window container. This container makes draggable windows possible. + * A window container. This container adds functionality for more convenient + * widget (windows in particular) destruction. * * \ingroup GUI */ diff --git a/src/item.h b/src/item.h index 1375886e..47cdb1a9 100644 --- a/src/item.h +++ b/src/item.h @@ -24,7 +24,7 @@ #ifndef _ITEM_H_ #define _ITEM_H_ -#include "resources/itemmanager.h" +#include "resources/itemdb.h" /** * Represents one or more instances of a certain item type. @@ -119,7 +119,7 @@ class Item * Returns information about this item type. */ const ItemInfo& - getInfo() const { return itemDb->getItemInfo(mId); } + getInfo() const { return ItemDB::get(mId); } protected: int mId; /**< Item type id. */ diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 6898dfb7..c887dd1c 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -30,6 +30,7 @@ #include "item.h" #include "main.h" #include "sound.h" +#include "log.h" #include "net/gameserver/player.h" @@ -65,9 +66,19 @@ void LocalPlayer::logic() void LocalPlayer::nextStep() { - if (mPath.empty() && mPickUpTarget) { - pickUp(mPickUpTarget); + if (mPath.empty()) + { + if (mPickUpTarget) + { + pickUp(mPickUpTarget); + } + + if (mWalkingDir) + { + walk(mWalkingDir); + } } + Player::nextStep(); } @@ -161,10 +172,15 @@ void LocalPlayer::pickUp(FloorItem *item) void LocalPlayer::walk(unsigned char dir) { + if (mWalkingDir != dir) + { + mWalkingDir = dir; + } + if (!mMap || !dir) return; - if (mAction == WALK) + if (mAction == WALK && !mPath.empty()) { // Just finish the current action, otherwise we get out of sync Being::setDestination(mX, mY); @@ -198,10 +214,8 @@ void LocalPlayer::walk(unsigned char dir) } else if (dir) { - // Update the player direction to where he wants to walk - // Warning: Not communicated to the server yet - // If the being can't move, just change direction + // TODO: Communicate this to the server (waiting on tmwserv) setDirection(dir); } } @@ -216,10 +230,16 @@ void LocalPlayer::setDestination(Uint16 x, Uint16 y) x = tx * 32 + fx; y = ty * 32 + fy; - Net::GameServer::Player::walk(x, y); + // Only send a new message to the server when destination changes + if (x != mDestX || y != mDestY) + { + mDestX = x; + mDestY = y; - mPickUpTarget = NULL; + Net::GameServer::Player::walk(x, y); + } + mPickUpTarget = NULL; Being::setDestination(x, y); } diff --git a/src/localplayer.h b/src/localplayer.h index dbf2a147..f632b1b9 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -47,6 +47,11 @@ class LocalPlayer : public Player virtual ~LocalPlayer(); virtual void logic(); + + /** + * Adds a new step when walking before calling super. Also, when + * specified it picks up an item at the end of a path. + */ virtual void nextStep(); /** @@ -151,7 +156,10 @@ class LocalPlayer : public Player FloorItem *mPickUpTarget; bool mTrading; - int mLastAction; /**< Time stamp of the last action, -1 if none */ + int mLastAction; /**< Time stamp of the last action, -1 if none. */ + int mWalkingDir; /**< The direction the player is walking in. */ + int mDestX; /**< X coordinate of destination. */ + int mDestY; /**< Y coordinate of destination. */ }; extern LocalPlayer *player_node; diff --git a/src/log.cpp b/src/log.cpp index 07eb55f7..3a3c91b8 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -21,7 +21,9 @@ #include "log.h" #ifdef WIN32 -#include + #include "utils/wingettimeofday.h" +#else + #include #endif #ifdef __APPLE__ #include @@ -64,7 +66,6 @@ void Logger::log(const char *log_text, ...) char* buf = new char[1024]; va_list ap; - time_t t; // Use a temporary buffer to fill in the variables va_start(ap, log_text); @@ -72,19 +73,23 @@ void Logger::log(const char *log_text, ...) va_end(ap); // Get the current system time - time(&t); + timeval tv; + gettimeofday(&tv, NULL); // Print the log entry std::stringstream timeStr; timeStr << "[" - << ((((t / 60) / 60) % 24 < 10) ? "0" : "") - << (int)(((t / 60) / 60) % 24) + << ((((tv.tv_sec / 60) / 60) % 24 < 10) ? "0" : "") + << (int)(((tv.tv_sec / 60) / 60) % 24) << ":" - << (((t / 60) % 60 < 10) ? "0" : "") - << (int)((t / 60) % 60) + << (((tv.tv_sec / 60) % 60 < 10) ? "0" : "") + << (int)((tv.tv_sec / 60) % 60) << ":" - << ((t % 60 < 10) ? "0" : "") - << (int)(t % 60) + << ((tv.tv_sec % 60 < 10) ? "0" : "") + << (int)(tv.tv_sec % 60) + << "." + << (((tv.tv_usec / 10000) % 100) < 10 ? "0" : "") + << (int)((tv.tv_usec / 10000) % 100) << "] "; mLogFile << timeStr.str() << buf << std::endl; diff --git a/src/main.cpp b/src/main.cpp index 59bb1566..90368b7d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,7 +76,10 @@ #include "net/gameserver/gameserver.h" +#include "resources/equipmentdb.h" #include "resources/image.h" +#include "resources/itemdb.h" +#include "resources/monsterdb.h" #include "resources/resourcemanager.h" #include "resources/spriteset.h" @@ -87,8 +90,6 @@ char n_character; std::string token; -std::vector hairset; -Spriteset *playerset[2]; Graphics *graphics; unsigned char state; @@ -171,6 +172,7 @@ void initHomeDir() void initConfiguration(const Options &options) { // Fill configuration with defaults + logger->log("Initializing configuration..."); config.setValue("host", "animesites.de"); config.setValue("port", 9601); config.setValue("hwaccel", 0); @@ -219,6 +221,7 @@ void initConfiguration(const Options &options) void init_engine() { // Initialize SDL + logger->log("Initializing SDL..."); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { std::cerr << "Could not initialize SDL: " << SDL_GetError() << std::endl; @@ -288,26 +291,6 @@ void init_engine() // Initialize for drawing graphics->_beginDraw(); - playerset[0] = resman->getSpriteset( - "graphics/sprites/player_male_base.png", 64, 64); - if (!playerset[0]) logger->error("Couldn't load male player spriteset!"); - playerset[1] = resman->getSpriteset( - "graphics/sprites/player_female_base.png", 64, 64); - if (!playerset[1]) logger->error("Couldn't load female player spriteset!"); - - - for (int i = 0; i < NR_HAIR_STYLES - 1; i++) - { - Spriteset *tmp = ResourceManager::getInstance()->getSpriteset( - "graphics/sprites/hairstyle" + toString(i + 1) + ".png", - 40, 40); - if (!tmp) { - logger->error("Unable to load hairstyle"); - } else { - hairset.push_back(tmp); - } - } - gui = new Gui(graphics); state = STATE_CHOOSE_SERVER; /**< Initial game state */ @@ -316,8 +299,9 @@ void init_engine() if (config.getValue("sound", 0) == 1) { sound.init(); } - sound.setSfxVolume((int)config.getValue("sfxVolume", defaultSfxVolume)); - sound.setMusicVolume((int)config.getValue("musicVolume", + sound.setSfxVolume((int) config.getValue("sfxVolume", + defaultSfxVolume)); + sound.setMusicVolume((int) config.getValue("musicVolume", defaultMusicVolume)); } catch (const char *err) { @@ -325,6 +309,11 @@ void init_engine() errorMessage = err; logger->log("Warning: %s", err); } + + // Load XML databases + EquipmentDB::load(); + ItemDB::load(); + MonsterDB::load(); } /** Clear the engine */ @@ -334,19 +323,17 @@ void exit_engine() delete gui; delete graphics; - std::for_each(hairset.begin(), hairset.end(), - std::mem_fun(&Spriteset::decRef)); - hairset.clear(); - - playerset[0]->decRef(); - playerset[1]->decRef(); - // Shutdown libxml xmlCleanupParser(); // Shutdown sound sound.close(); + // Unload XML databases + EquipmentDB::unload(); + ItemDB::unload(); + MonsterDB::unload(); + ResourceManager::deleteInstance(); } @@ -599,7 +586,7 @@ int main(int argc, char *argv[]) gui->logic(); Net::flush(); - if (state > STATE_CONNECT_ACCOUNT && state < STATE_GAME) + if (state > STATE_CONNECT_ACCOUNT && state < STATE_GAME) { if (!accountServerConnection->isConnected()) { diff --git a/src/map.cpp b/src/map.cpp index 1cdc1077..1bd8f235 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -282,35 +282,35 @@ Map::setWalk(int x, int y, bool walkable) bool Map::getWalk(int x, int y) { - // Check for being walkable - if (tileCollides(x, y)) { - return false; - } + return !tileCollides(x, y) && !occupied(x, y); +} - /* - // Check for collision with a being +bool +Map::occupied(int x, int y) +{ Beings &beings = beingManager->getAll(); - for (BeingIterator i = beings.begin(); i != beings.end(); i++) { + for (BeingIterator i = beings.begin(); i != beings.end(); i++) + { // job 45 is a portal, they don't collide - if ((*i)->mX / 32 == x && (*i)->mY / 32 == y && (*i)->mJob != 45) { - return false; + if ((*i)->mX / 32 == x && (*i)->mY / 32 == y && (*i)->mJob != 45) + { + return true; } } - */ - return true; + return false; } bool Map::tileCollides(int x, int y) { - // You can't walk outside of the map - if (x < 0 || y < 0 || x >= mWidth || y >= mHeight) { - return true; - } + return !(contains(x, y) && mMetaTiles[x + y * mWidth].walkable); +} - // Check if the tile is walkable - return !mMetaTiles[x + y * mWidth].walkable; +bool +Map::contains(int x, int y) +{ + return x >= 0 && y >= 0 && x < mWidth && y < mHeight; } void @@ -355,8 +355,9 @@ Map::findPath(int startX, int startY, int destX, int destY) // Declare open list, a list with open tiles sorted on F cost std::priority_queue openList; - // Return empty path when destination not walkable - if (!getWalk(destX, destY)) return path; + // Return empty path when destination collides + if (tileCollides(destX, destY)) + return path; // Reset starting tile's G cost to 0 MetaTile *startTile = getMetaTile(startX, startY); @@ -395,16 +396,15 @@ Map::findPath(int startX, int startY, int destX, int destY) // Skip if if we're checking the same tile we're leaving from, // or if the new location falls outside of the map boundaries - if ((dx == 0 && dy == 0) || - (x < 0 || y < 0 || x >= mWidth || y >= mHeight)) + if ((dx == 0 && dy == 0) || !contains(x, y)) { continue; } MetaTile *newTile = getMetaTile(x, y); - // Skip if the tile is on the closed list or is not walkable - if (newTile->whichList == mOnClosedList || !getWalk(x, y)) + // Skip if the tile is on the closed list or collides + if (newTile->whichList == mOnClosedList || tileCollides(x, y)) { continue; } @@ -441,6 +441,13 @@ Map::findPath(int startX, int startY, int destX, int destY) ++Gcost; } + // It costs extra to walk through a being (needs to be enough + // to make it more attractive to walk around). + if (occupied(x, y)) + { + Gcost += 30; + } + // Skip if Gcost becomes too much // Warning: probably not entirely accurate if (Gcost > 20 * basicCost) diff --git a/src/map.h b/src/map.h index 961326b8..15b9b0dc 100644 --- a/src/map.h +++ b/src/map.h @@ -129,7 +129,7 @@ class Map : public Properties MetaTile *getMetaTile(int x, int y); /** - * Set walkability flag for a tile + * Set walkability flag for a tile. */ void setWalk(int x, int y, bool walkable); @@ -199,6 +199,16 @@ class Map : public Properties Tileset* getTilesetWithGid(int gid); + /** + * Tells whether a tile is occupied by a being. + */ + bool occupied(int x, int y); + + /** + * Tells whether the given coordinates fall within the map boundaries. + */ + bool contains(int x, int y); + int mWidth, mHeight; int mTileWidth, mTileHeight; MetaTile *mMetaTiles; diff --git a/src/monster.cpp b/src/monster.cpp index a4317e5e..f2e4d93d 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -25,6 +25,9 @@ #include "animatedsprite.h" #include "game.h" +#include "sound.h" + +#include "resources/monsterdb.h" #include "utils/tostring.h" @@ -32,7 +35,8 @@ 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); + mSprites[BASE_SPRITE] = new AnimatedSprite( + "graphics/sprites/" + MonsterDB::get(job - 1002).getSprite()); } Being::Type @@ -41,3 +45,36 @@ Monster::getType() const return MONSTER; } +void +Monster::setAction(Uint8 action) +{ + SpriteAction currentAction = ACTION_INVALID; + + switch (action) + { + case WALK: + currentAction = ACTION_WALK; + break; + case DEAD: + currentAction = ACTION_DEAD; + sound.playSfx(MonsterDB::get(mJob - 1002).getSound(EVENT_DIE)); + break; + case ATTACK: + currentAction = ACTION_ATTACK; + sound.playSfx(MonsterDB::get(mJob - 1002).getSound(EVENT_HIT)); + mSprites[BASE_SPRITE]->reset(); + break; + case STAND: + currentAction = ACTION_STAND; + break; + case HURT: + // Not implemented yet + break; + } + + if (currentAction != ACTION_INVALID) + { + mSprites[BASE_SPRITE]->play(currentAction); + mAction = action; + } +} diff --git a/src/monster.h b/src/monster.h index 0314a035..7f129e14 100644 --- a/src/monster.h +++ b/src/monster.h @@ -31,6 +31,8 @@ class Monster : public Being public: Monster(Uint16 id, Uint16 job, Map *map); + virtual void setAction(Uint8 action); + virtual Type getType() const; }; diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp index 2d68dd28..6d8ff6c6 100644 --- a/src/net/beinghandler.cpp +++ b/src/net/beinghandler.cpp @@ -66,6 +66,7 @@ void BeingHandler::handleMessage(MessageIn &msg) /* Uint32 id; Uint16 job, speed; + Uint16 headBottom, headTop, headMid; Sint16 param1; Sint8 type; Being *srcBeing, *dstBeing; @@ -124,7 +125,8 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing->mJob = job; dstBeing->setHairStyle(msg.readShort()); dstBeing->setWeapon(msg.readShort()); - dstBeing->setVisibleEquipment(3, msg.readShort()); // head bottom + dstBeing->setVisibleEquipment( + Being::BOTTOMCLOTHES_SPRITE, msg.readShort()); if (msg.getId() == SMSG_BEING_MOVE) { @@ -132,8 +134,9 @@ void BeingHandler::handleMessage(MessageIn &msg) } msg.readShort(); // shield - dstBeing->setVisibleEquipment(4, msg.readShort()); // head top - dstBeing->setVisibleEquipment(5, msg.readShort()); // head mid + 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 @@ -156,7 +159,9 @@ void BeingHandler::handleMessage(MessageIn &msg) } else { - //msg.readCoordinates(dstBeing->mX, dstBeing->mY, dstBeing->mDirection); + //Uint8 dir; + //msg->readCoordinates(dstBeing->mX, dstBeing->mY, dir); + //dstBeing->setDirection(dir); } msg.readByte(); // unknown @@ -173,19 +178,7 @@ void BeingHandler::handleMessage(MessageIn &msg) if (msg.readByte() == 1) { - // Death - switch (dstBeing->getType()) - { - case Being::MONSTER: - dstBeing->setAction(Being::MONSTER_DEAD); - dstBeing->mFrame = 0; - dstBeing->mWalkTime = tick_time; - break; - - default: - dstBeing->setAction(Being::DEAD); - break; - } + dstBeing->setAction(Being::DEAD); } else { @@ -219,15 +212,7 @@ void BeingHandler::handleMessage(MessageIn &msg) if (srcBeing != NULL && srcBeing != player_node) { - // buggy - if (srcBeing->getType() == Being::MONSTER) - { - srcBeing->setAction(Being::MONSTER_ATTACK); - } - else - { - srcBeing->setAction(Being::ATTACK); - } + srcBeing->setAction(Being::ATTACK); srcBeing->mFrame = 0; srcBeing->mWalkTime = tick_time; } @@ -275,27 +260,35 @@ void BeingHandler::handleMessage(MessageIn &msg) } int type = msg.readByte(); + int id = msg.readByte(); switch (type) { case 1: - dstBeing->setHairStyle(msg.readByte()); + dstBeing->setHairStyle(id); break; case 2: - dstBeing->setWeapon(msg.readByte()); + dstBeing->setWeapon(id); + break; + case 3: // Change lower headgear for eAthena, pants for us + dstBeing->setVisibleEquipment( + Being::BOTTOMCLOTHES_SPRITE, + id); + break; + case 4: // Change upper headgear for eAthena, hat for us + dstBeing->setVisibleEquipment( + Being::HAT_SPRITE, + id); break; - case 3: - case 4: - case 5: - // Equip/unequip head 3. Bottom 4. Top 5. Middle - dstBeing->setVisibleEquipment(type, msg.readByte()); - // First 3 slots of mVisibleEquipments are reserved for - // later use, probably accessories. + case 5: // Change middle headgear for eathena, armor for us + dstBeing->setVisibleEquipment( + Being::TOPCLOTHES_SPRITE, + id); break; case 6: - dstBeing->setHairColor(msg.readByte()); + dstBeing->setHairColor(id); break; default: - printf("c3: %i\n", msg.readByte()); // unsupported + logger->log("c3: %i\n", id); // unsupported break; } } @@ -331,15 +324,15 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing->setHairStyle(msg.readShort()); dstBeing->setWeaponById(msg.readShort()); // item id 1 msg.readShort(); // item id 2 - dstBeing->setVisibleEquipment(3, msg.readShort()); // head bottom + headBottom = msg.readShort(); if (msg.getId() == SMSG_PLAYER_MOVE) { msg.readLong(); // server tick } - dstBeing->setVisibleEquipment(4, msg.readShort()); // head top - dstBeing->setVisibleEquipment(5, msg.readShort()); // head mid + headTop = msg.readShort(); + headMid = msg.readShort(); dstBeing->setHairColor(msg.readShort()); msg.readShort(); // unknown msg.readShort(); // head dir @@ -348,6 +341,10 @@ void BeingHandler::handleMessage(MessageIn &msg) msg.readShort(); // manner msg.readByte(); // karma dstBeing->setSex(1 - msg.readByte()); // sex + dstBeing->setVisibleEquipment( + Being::BOTTOMCLOTHES_SPRITE, headBottom); + dstBeing->setVisibleEquipment(Being::HAT_SPRITE, headTop); + dstBeing->setVisibleEquipment(Being::TOPCLOTHES_SPRITE, headMid); if (msg.getId() == SMSG_PLAYER_MOVE) { @@ -359,7 +356,9 @@ void BeingHandler::handleMessage(MessageIn &msg) } else { - //msg.readCoordinates(dstBeing->mX, dstBeing->mY, dstBeing->mDirection); + //Uint8 dir; + //msg->readCoordinates(dstBeing->mX, dstBeing->mY, dir); + //dstBeing->setDirection(dir); } msg.readByte(); // unknown @@ -386,7 +385,7 @@ void BeingHandler::handleMessage(MessageIn &msg) case 0x0119: // Change in players look - printf("0x0119 %li %i %i %x %i\n", msg.readLong(), + logger->log("0x0119 %li %i %i %x %i\n", msg.readLong(), msg.readShort(), msg.readShort(), msg.readShort(), msg.readByte()); break; diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp index 3f7e8709..f003d77a 100644 --- a/src/net/inventoryhandler.cpp +++ b/src/net/inventoryhandler.cpp @@ -92,7 +92,7 @@ void InventoryHandler::handleMessage(MessageIn &msg) if (msg.readByte()> 0) { chatWindow->chatLog("Unable to pick up item", BY_SERVER); } else { - const ItemInfo &itemInfo = itemDb->getItemInfo(itemId); + const ItemInfo &itemInfo = ItemDB::get(itemId); chatWindow->chatLog("You picked up a " + itemInfo.getName(), BY_SERVER); player_node->addInvItem(index, itemId, amount, equipType != 0); diff --git a/src/net/npchandler.cpp b/src/net/npchandler.cpp index 9c89e71f..02204a84 100644 --- a/src/net/npchandler.cpp +++ b/src/net/npchandler.cpp @@ -49,20 +49,22 @@ NPCHandler::NPCHandler() void NPCHandler::handleMessage(MessageIn &msg) { + int id; + switch (msg.getId()) { case SMSG_NPC_CHOICE: msg.readShort(); // length - current_npc = dynamic_cast( - beingManager->findBeing(msg.readLong())); + id = msg.readLong(); + current_npc = dynamic_cast(beingManager->findBeing(id)); 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())); + id = msg.readLong(); + current_npc = dynamic_cast(beingManager->findBeing(id)); npcTextDialog->addText(msg.readString(msg.getLength() - 8)); npcListDialog->setVisible(false); npcTextDialog->setVisible(true); diff --git a/src/net/playerhandler.cpp b/src/net/playerhandler.cpp index 6eb80d59..37291c0a 100644 --- a/src/net/playerhandler.cpp +++ b/src/net/playerhandler.cpp @@ -46,7 +46,8 @@ OkDialog *deathNotice = NULL; namespace { struct WeightListener : public gcn::ActionListener { - void action(const std::string &eventId, gcn::Widget *widget) { + void action(const std::string &eventId, gcn::Widget *widget) + { weightNotice = NULL; } } weightListener; @@ -57,8 +58,10 @@ namespace { */ // TODO Move somewhere else namespace { - struct DeathListener : public gcn::ActionListener { - void action(const std::string &eventId, gcn::Widget *widget) { + struct DeathListener : public gcn::ActionListener + { + void action(const std::string &eventId, gcn::Widget *widget) + { player_node->revive(); deathNotice = NULL; } @@ -114,10 +117,11 @@ void PlayerHandler::handleMessage(MessageIn &msg) player_node->mMaxWeight / 2) { weightNotice = new OkDialog("Message", - "You are carrying more then half your " - "weight. You are unable to regain " - "health."); - weightNotice->addActionListener(&weightListener); + "You are carrying more then half " + "your weight. You are unable to " + "regain health."); + weightNotice->addActionListener( + &weightListener); } player_node->mTotalWeight = value; break; diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp index d9bea775..17dea606 100644 --- a/src/net/skillhandler.cpp +++ b/src/net/skillhandler.cpp @@ -26,6 +26,8 @@ #include "messagein.h" #include "protocol.h" +#include "../log.h" + #include "../gui/chat.h" #include "../gui/skill.h" @@ -85,7 +87,7 @@ void SkillHandler::handleMessage(MessageIn &msg) if (action.success != SKILL_FAILED && action.bskill == BSKILL_EMOTE) { - printf("Action: %d/%d", action.bskill, action.success); + logger->log("Action: %d/%d", action.bskill, action.success); } chatWindow->chatLog(action); break; diff --git a/src/npc.cpp b/src/npc.cpp index 3bd4371b..3c142889 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -24,6 +24,9 @@ #include "npc.h" #include "animatedsprite.h" +#include "graphics.h" + +#include "gui/gui.h" class Spriteset; extern Spriteset *npcset; @@ -33,7 +36,8 @@ NPC *current_npc = 0; NPC::NPC(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { - mSprites[BASE_SPRITE] = new AnimatedSprite("graphics/sprites/npc.xml", job-100); + mSprites[BASE_SPRITE] = new AnimatedSprite("graphics/sprites/npc.xml", + job - 100); } Being::Type @@ -42,6 +46,17 @@ NPC::getType() const return Being::NPC; } +void +NPC::drawName(Graphics *graphics, Sint32 offsetX, Sint32 offsetY) +{ + int px = mPx + offsetX; + int py = mPy + offsetY; + + graphics->setFont(speechFont); + graphics->setColor(gcn::Color(200, 200, 255)); + graphics->drawText(mName, px + 15, py + 30, gcn::Graphics::CENTER); +} + void NPC::talk() { diff --git a/src/npc.h b/src/npc.h index 3b61123b..cf5defbc 100644 --- a/src/npc.h +++ b/src/npc.h @@ -26,12 +26,18 @@ #include "being.h" +class Graphics; + class NPC : public Being { public: NPC(Uint16 id, Uint16 job, Map *map); - virtual Type getType() const; + virtual Type + getType() const; + + virtual void + drawName(Graphics *graphics, Sint32 offsetX, Sint32 offsetY); void talk(); void nextDialog(); diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp index 05bbb6b3..ec6c1ee3 100644 --- a/src/openglgraphics.cpp +++ b/src/openglgraphics.cpp @@ -52,6 +52,9 @@ OpenGLGraphics::~OpenGLGraphics() bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel) { + logger->log("Setting video mode %dx%d %s", + w, h, fs ? "fullscreen" : "windowed"); + int displayFlags = SDL_ANYFORMAT | SDL_OPENGL; mFullscreen = fs; diff --git a/src/player.cpp b/src/player.cpp index 0acf8262..63ed5455 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -28,6 +28,8 @@ #include "graphics.h" #include "log.h" +#include "resources/equipmentdb.h" + #include "utils/tostring.h" #include "gui/gui.h" @@ -35,9 +37,6 @@ Player::Player(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { - // Load the weapon sprite. - // When there are more different weapons this should be moved to the - // setWeapon Method. setWeapon(0); } @@ -70,52 +69,72 @@ Player::setSex(Uint8 sex) if (sex != mSex) { - delete mSprites[BASE_SPRITE]; + Being::setSex(sex); + + // Reload base sprite + AnimatedSprite *newBaseSprite; if (sex == 0) { - mSprites[BASE_SPRITE] = new AnimatedSprite( - "graphics/sprites/player_male_base.xml", 0); + newBaseSprite = new AnimatedSprite( + "graphics/sprites/player_male_base.xml"); } else { - mSprites[BASE_SPRITE] = new AnimatedSprite( - "graphics/sprites/player_female_base.xml", 0); + newBaseSprite = new AnimatedSprite( + "graphics/sprites/player_female_base.xml"); } - Being::setSex(sex); - resetAnimations(); + delete mSprites[BASE_SPRITE]; + mSprites[BASE_SPRITE] = newBaseSprite; + + // Reload equipment + for (int i = 1; i < VECTOREND_SPRITE; i++) + { + if (i != HAIR_SPRITE && mEquipmentSpriteIDs.at(i) != 0) + { + AnimatedSprite *newEqSprite = new AnimatedSprite( + "graphics/sprites/" + EquipmentDB::get( + mEquipmentSpriteIDs.at(i))->getSprite(sex)); + delete mSprites[i]; + mSprites[i] = newEqSprite; + } + } } } - void Player::setWeapon(Uint16 weapon) { if (weapon != mWeapon) { - delete mSprites[WEAPON_SPRITE]; - mSprites[WEAPON_SPRITE] = NULL; + AnimatedSprite *newWeaponSprite = NULL; switch (weapon) { case 0: - mSprites[WEAPON_SPRITE] = new AnimatedSprite("graphics/sprites/weapon-fist.xml", 0); + newWeaponSprite = + new AnimatedSprite("graphics/sprites/weapon-fist.xml"); break; case 1: - mSprites[WEAPON_SPRITE] = new AnimatedSprite("graphics/sprites/weapon-dagger.xml", 0); + newWeaponSprite = + new AnimatedSprite("graphics/sprites/weapon-dagger.xml"); break; case 2: - mSprites[WEAPON_SPRITE] = new AnimatedSprite("graphics/sprites/weapon-bow.xml", 0); + newWeaponSprite = + new AnimatedSprite("graphics/sprites/weapon-bow.xml"); break; case 3: - mSprites[WEAPON_SPRITE] = new AnimatedSprite("graphics/sprites/weapon-scythe.xml", 0); + 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) { @@ -128,7 +147,6 @@ Player::setHairColor(Uint16 color) delete mSprites[HAIR_SPRITE]; mSprites[HAIR_SPRITE] = newHairSprite; - resetAnimations(); setAction(mAction); } @@ -148,7 +166,6 @@ Player::setHairStyle(Uint16 style) delete mSprites[HAIR_SPRITE]; mSprites[HAIR_SPRITE] = newHairSprite; - resetAnimations(); setAction(mAction); } @@ -157,55 +174,35 @@ Player::setHairStyle(Uint16 style) } void -Player::setVisibleEquipment(Uint8 slot, Uint8 id) +Player::setVisibleEquipment(Uint8 slot, int id) { - // Translate eAthena specific slot - Uint8 position = 0; - switch (slot) { - case 3: - position = BOTTOMCLOTHES_SPRITE; - break; - case 4: - position = HAT_SPRITE; - break; - case 5: - position = TOPCLOTHES_SPRITE; - break; - } - // id = 0 means unequip if (id == 0) { - delete mSprites[position]; - mSprites[position] = NULL; + delete mSprites[slot]; + mSprites[slot] = NULL; } else { - char stringId[4]; - sprintf(stringId, "%03i", id); + AnimatedSprite *equipmentSprite; + + if (mSex == 0) + { + equipmentSprite = new AnimatedSprite( + "graphics/sprites/" + EquipmentDB::get(id)->getSprite(0)); + } + else { + equipmentSprite = new AnimatedSprite( + "graphics/sprites/" + EquipmentDB::get(id)->getSprite(1)); + } - AnimatedSprite *equipmentSprite = new AnimatedSprite( - "graphics/sprites/item" + toString(stringId) + ".xml", 0); equipmentSprite->setDirection(getSpriteDirection()); - delete mSprites[position]; - mSprites[position] = equipmentSprite; - resetAnimations(); + delete mSprites[slot]; + mSprites[slot] = equipmentSprite; setAction(mAction); } Being::setVisibleEquipment(slot, id); } - -void -Player::resetAnimations() -{ - for (int i = 0; i < VECTOREND_SPRITE; i++) - { - if (mSprites[i] != NULL) - { - mSprites[i]->reset(); - } - } -} diff --git a/src/player.h b/src/player.h index 3c061be6..b062a55f 100644 --- a/src/player.h +++ b/src/player.h @@ -26,12 +26,14 @@ #include "being.h" -#include - class Graphics; class Map; -class AnimatedSprite; +/** + * A player being. Players have their name drawn beneath them. This class also + * implements player-specific loading of base sprite, hair sprite and equipment + * sprites. + */ class Player : public Being { public: @@ -56,18 +58,10 @@ class Player : public Being setHairStyle(Uint16 style); virtual void - setVisibleEquipment(Uint8 slot, Uint8 id); + setVisibleEquipment(Uint8 slot, int id); virtual void setWeapon(Uint16 weapon); - - private: - /** - * Resets all animations associated with this player. This is used to - * synchronize the animations after a new one has been added. - */ - void - resetAnimations(); }; #endif diff --git a/src/resources/equipmentdb.cpp b/src/resources/equipmentdb.cpp new file mode 100644 index 00000000..78ae3b6a --- /dev/null +++ b/src/resources/equipmentdb.cpp @@ -0,0 +1,158 @@ +/* + * 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() +{ + 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 ( xmlNodePtr equipmentNode = rootNode->xmlChildrenNode; + equipmentNode != NULL; + equipmentNode = equipmentNode->next) + { + + if (!xmlStrEqual(equipmentNode->name, BAD_CAST "equipment")) + { + continue; + } + + EquipmentInfo *currentInfo = new EquipmentInfo(); + + currentInfo->setSlot (XML::getProperty(equipmentNode, "slot", 0)); + + //iterate s + for ( xmlNodePtr spriteNode = equipmentNode->xmlChildrenNode; + spriteNode != NULL; + spriteNode = spriteNode->next) + { + 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 new file mode 100644 index 00000000..b8618f5f --- /dev/null +++ b/src/resources/equipmentdb.h @@ -0,0 +1,52 @@ +/* + * 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" + +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 new file mode 100644 index 00000000..93a1cb42 --- /dev/null +++ b/src/resources/equipmentinfo.h @@ -0,0 +1,52 @@ +/* + * 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/image.cpp b/src/resources/image.cpp index eb3a2409..48818f6f 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -68,9 +68,17 @@ Image* Image::load(void *buffer, unsigned int bufferSize, { // Load the raw file data from the buffer in an RWops structure SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize); + SDL_Surface *tmpImage; // Use SDL_Image to load the raw image data and have it free the data - SDL_Surface *tmpImage = IMG_Load_RW(rw, 1); + if (!idPath.compare(idPath.length() - 4, 4, ".tga")) + { + tmpImage = IMG_LoadTyped_RW(rw, 1, const_cast("TGA")); + } + else + { + tmpImage = IMG_Load_RW(rw, 1); + } if (tmpImage == NULL) { logger->log("Error, image load failed: %s", IMG_GetError()); diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp new file mode 100644 index 00000000..b91e34cc --- /dev/null +++ b/src/resources/itemdb.cpp @@ -0,0 +1,170 @@ +/* + * 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 "itemdb.h" + +#include + +#include "iteminfo.h" +#include "resourcemanager.h" + +#include "../log.h" + +#include "../utils/dtor.h" +#include "../utils/xml.h" + +namespace +{ + ItemDB::ItemInfos mItemInfos; + ItemInfo mUnknown; +} + + +void ItemDB::load() +{ + logger->log("Initializing item database..."); + mUnknown.setName("Unknown item"); + + ResourceManager *resman = ResourceManager::getInstance(); + int size; + char *data = (char*)resman->loadFile("items.xml", size); + + if (!data) { + logger->error("ItemDB: Could not find items.xml!"); + } + + xmlDocPtr doc = xmlParseMemory(data, size); + free(data); + + if (!doc) + { + logger->error("ItemDB: Error while parsing item database (items.xml)!"); + } + + xmlNodePtr node = xmlDocGetRootElement(doc); + if (!node || !xmlStrEqual(node->name, BAD_CAST "items")) + { + logger->error("ItemDB: items.xml is not a valid database file!"); + } + + for (node = node->xmlChildrenNode; node != NULL; node = node->next) + { + if (!xmlStrEqual(node->name, BAD_CAST "item")) { + continue; + } + + int id = XML::getProperty(node, "id", 0); + int art = XML::getProperty(node, "art", 0); + int type = XML::getProperty(node, "type", 0); + int weight = XML::getProperty(node, "weight", 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", ""); + + if (id && name != "") + { + ItemInfo *itemInfo = new ItemInfo(); + itemInfo->setImage(image); + itemInfo->setArt(art); + itemInfo->setName(name); + itemInfo->setDescription(description); + itemInfo->setEffect(effect); + itemInfo->setType(type); + itemInfo->setWeight(weight); + itemInfo->setSlot(slot); + mItemInfos[id] = itemInfo; + } + + + if (id == 0) + { + logger->log("ItemDB: An item has no ID in items.xml!"); + } + if (name == "") + { + logger->log("ItemDB: Missing name for item %d!", id); + } + + if (image == "") + { + logger->log("ItemDB: Missing image parameter for item: %i. %s", + id, name.c_str()); + } + /* + if (art == 0) + { + logger->log("Item Manager: Missing art parameter for item: %i. %s", + id, name.c_str()); + } + if (description == "") + { + logger->log("ItemDB: Missing description parameter for item: %i. %s", + id, name.c_str()); + } + if (effect == "") + { + logger->log("ItemDB: Missing effect parameter for item: %i. %s", + id, name.c_str()); + } + if (type == 0) + { + logger->log("Item Manager: Missing type parameter for item: %i. %s", + id, name.c_str()); + } + */ + if (weight == 0) + { + logger->log("Item Manager: Missing weight parameter for item: %i. %s", + id, name.c_str()); + } + /* + if (slot == 0) + { + logger->log("Item Manager: Missing slot parameter for item: %i. %s", + id, name.c_str()); + } + */ + } + + xmlFreeDoc(doc); +} + +void ItemDB::unload() +{ + for (ItemInfoIterator i = mItemInfos.begin(); i != mItemInfos.end(); i++) + { + delete i->second; + } + mItemInfos.clear(); +} + +const ItemInfo& +ItemDB::get(int id) +{ + ItemInfoIterator i = mItemInfos.find(id); + + return (i != mItemInfos.end()) ? *(i->second) : mUnknown; +} diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h new file mode 100644 index 00000000..5922984a --- /dev/null +++ b/src/resources/itemdb.h @@ -0,0 +1,53 @@ +/* + * 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: itemdb.h 2650 2006-09-03 15:00:47Z b_lindeijer $ + */ + +#ifndef _TMW_ITEM_MANAGER_H +#define _TMW_ITEM_MANAGER_H + +#include "iteminfo.h" + +#include + +/** + * The namespace that holds the item information + */ +namespace ItemDB +{ + /** + * Loads the item data from Items.xml + */ + void load(); + + /** + * Frees item data + */ + void unload(); + + const ItemInfo& get(int id); + + // Items database + typedef std::map ItemInfos; + typedef ItemInfos::iterator ItemInfoIterator; +} + +#endif diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index 9a04bb2e..e4f851bb 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -33,8 +33,6 @@ class Image; */ class ItemInfo { - friend class ItemManager; - public: /** * Constructor. @@ -49,6 +47,11 @@ class ItemInfo { } + /** + * Destructor. + */ + ~ItemInfo(); + void setArt(short art) { mArt = art; } @@ -101,11 +104,6 @@ class ItemInfo getSlot() const { return mSlot; } protected: - /** - * Destructor. - */ - ~ItemInfo(); - std::string mImageName; /* TODO (BL): I do not think the item info should keep a reference to diff --git a/src/resources/itemmanager.cpp b/src/resources/itemmanager.cpp deleted file mode 100644 index 7d0b13f2..00000000 --- a/src/resources/itemmanager.cpp +++ /dev/null @@ -1,173 +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 "itemmanager.h" - -#include - -#include "iteminfo.h" -#include "resourcemanager.h" - -#include "../log.h" - -#include "../utils/dtor.h" - -#define READ_PROP(node, prop, name, target, cast) \ - prop = xmlGetProp(node, BAD_CAST name); \ - if (prop) { \ - target = cast((const char*)prop); \ - xmlFree(prop); \ - } - -ItemManager::ItemManager() -{ - mUnknown.setName("Unknown item"); - - ResourceManager *resman = ResourceManager::getInstance(); - int size; - char *data = (char*)resman->loadFile("items.xml", size); - - if (!data) { - logger->error("Item Manager: Could not find items.xml!"); - } - - xmlDocPtr doc = xmlParseMemory(data, size); - free(data); - - if (!doc) - { - logger->error("Item Manager: Error while parsing item database (items.xml)!"); - } - - xmlNodePtr node = xmlDocGetRootElement(doc); - if (!node || !xmlStrEqual(node->name, BAD_CAST "items")) - { - logger->error("Item Manager: items.xml is not a valid database file!"); - } - - for (node = node->xmlChildrenNode; node != NULL; node = node->next) - { - int id = 0, art = 0, type = 0, weight = 0, slot = 0; - std::string name = "", description = "", effect = "", image = ""; - - if (!xmlStrEqual(node->name, BAD_CAST "item")) { - continue; - } - - xmlChar *prop = NULL; - READ_PROP(node, prop, "id", id, atoi); - READ_PROP(node, prop, "image", image, ); - READ_PROP(node, prop, "art", art, atoi); - READ_PROP(node, prop, "name", name, ); - READ_PROP(node, prop, "description", description, ); - READ_PROP(node, prop, "effect", effect, ); - READ_PROP(node, prop, "type", type, atoi); - READ_PROP(node, prop, "weight", weight, atoi); - READ_PROP(node, prop, "slot", slot, atoi); - - - if (id && name != "") - { - ItemInfo *itemInfo = new ItemInfo(); - itemInfo->setImage(image); - itemInfo->setArt(art); - itemInfo->setName(name); - itemInfo->setDescription(description); - itemInfo->setEffect(effect); - itemInfo->setType(type); - itemInfo->setWeight(weight); - itemInfo->setSlot(slot); - mItemInfos[id] = itemInfo; - } - - - if (id == 0) - { - logger->log("Item Manager: An item has no ID in items.xml!"); - } - if (name == "") - { - logger->log("Item Manager: An item has no name in items.xml!"); - } - - if (image == "") - { - logger->log("Item Manager: Missing image parameter for item: %i. %s", - id, name.c_str()); - } - /*if (art == 0) - { - logger->log("Item Manager: Missing art parameter for item: %i. %s", - id, name.c_str()); - }*/ - if (description == "") - { - logger->log("Item Manager: Missing description parameter for item: %i. %s", - id, name.c_str()); - } - if (effect == "") - { - logger->log("Item Manager: Missing effect parameter for item: %i. %s", - id, name.c_str()); - } - /*if (type == 0) - { - logger->log("Item Manager: Missing type parameter for item: %i. %s", - id, name.c_str()); - }*/ - if (weight == 0) - { - logger->log("Item Manager: Missing weight parameter for item: %i. %s", - id, name.c_str()); - } - if (slot == 0) - { - logger->log("Item Manager: Missing slot parameter for item: %i. %s", - id, name.c_str()); - } - - /*logger->log("Item: %i %i %i %s %s %i %i %i", id, - getImage(id), getArt(id), getName(id).c_str(), - getDescription(id).c_str(), getType(id), getWeight(id), - getSlot(id));*/ - } - - xmlFreeDoc(doc); -} - -ItemManager::~ItemManager() -{ - for (ItemInfoIterator i = mItemInfos.begin(); i != mItemInfos.end(); i++) - { - delete i->second; - } - mItemInfos.clear(); -} - -const ItemInfo& -ItemManager::getItemInfo(int id) -{ - ItemInfoIterator i = mItemInfos.find(id); - - return (i != mItemInfos.end()) ? *(i->second) : mUnknown; -} diff --git a/src/resources/itemmanager.h b/src/resources/itemmanager.h deleted file mode 100644 index b1f2b95c..00000000 --- a/src/resources/itemmanager.h +++ /dev/null @@ -1,59 +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_ITEM_MANAGER_H -#define _TMW_ITEM_MANAGER_H - -#include "iteminfo.h" - -#include - -/** - * Defines a class to load items database. - */ -class ItemManager -{ - public: - /** - * Constructor. - */ - ItemManager(); - - /** - * Destructor. - */ - ~ItemManager(); - - const ItemInfo& getItemInfo(int id); - - protected: - // Items database - typedef std::map ItemInfos; - typedef ItemInfos::iterator ItemInfoIterator; - ItemInfos mItemInfos; - ItemInfo mUnknown; -}; - -extern ItemManager *itemDb; - -#endif diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp index 2aea3dc5..09a6eb74 100644 --- a/src/resources/mapreader.cpp +++ b/src/resources/mapreader.cpp @@ -36,6 +36,7 @@ #include "../tileset.h" #include "../utils/tostring.h" +#include "../utils/xml.h" const unsigned int DEFAULT_TILE_WIDTH = 32; const unsigned int DEFAULT_TILE_HEIGHT = 32; @@ -205,10 +206,10 @@ MapReader::readMap(xmlNodePtr node, const std::string &path) prop = xmlGetProp(node, BAD_CAST "version"); xmlFree(prop); - int w = getProperty(node, "width", 0); - int h = getProperty(node, "height", 0); - int tilew = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); - int tileh = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); + int w = XML::getProperty(node, "width", 0); + int h = XML::getProperty(node, "height", 0); + int tilew = XML::getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); + int tileh = XML::getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); int layerNr = 0; Map *map = new Map(w, h, tilew, tileh); @@ -308,7 +309,7 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer) int binLen; unsigned char *binData = - php_base64_decode(charData, strlen((char*)charData), &binLen); + php3_base64_decode(charData, strlen((char*)charData), &binLen); delete[] charData; @@ -354,7 +355,7 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer) if (!xmlStrEqual(n2->name, BAD_CAST "tile")) continue; - int gid = getProperty(n2, "gid", -1); + int gid = XML::getProperty(n2, "gid", -1); map->setTileWithGid(x, y, layer, gid); x++; @@ -387,9 +388,9 @@ MapReader::readTileset(xmlNodePtr node, return NULL; } - int firstGid = getProperty(node, "firstgid", 0); - int tw = getProperty(node, "tilewidth", map->getTileWidth()); - int th = getProperty(node, "tileheight", map->getTileHeight()); + int firstGid = XML::getProperty(node, "firstgid", 0); + int tw = XML::getProperty(node, "tilewidth", map->getTileWidth()); + int th = XML::getProperty(node, "tileheight", map->getTileHeight()); for (node = node->xmlChildrenNode; node; node = node->next) { if (!xmlStrEqual(node->name, BAD_CAST "image")) @@ -422,16 +423,3 @@ MapReader::readTileset(xmlNodePtr node, return NULL; } - -int -MapReader::getProperty(xmlNodePtr node, const char* name, int def) -{ - int &ret = def; - - xmlChar *prop = xmlGetProp(node, BAD_CAST name); - if (prop) { - ret = atoi((char*)prop); - xmlFree(prop); - } - return ret; -} diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp new file mode 100644 index 00000000..fb03f6c1 --- /dev/null +++ b/src/resources/monsterdb.cpp @@ -0,0 +1,151 @@ +/* + * 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 "monsterdb.h" + +#include "resourcemanager.h" + +#include "../log.h" + +#include "../utils/dtor.h" +#include "../utils/xml.h" + +namespace +{ + MonsterDB::MonsterInfos mMonsterInfos; + MonsterInfo mUnknown; +} + +void +MonsterDB::load() +{ + mUnknown.setSprite("error.xml"); + mUnknown.setName("unnamed"); + + logger->log("Initializing monster database..."); + + ResourceManager *resman = ResourceManager::getInstance(); + int size; + char *data = (char*)resman->loadFile("monsters.xml", size); + + if (!data) + { + logger->error("Monster Database: Could not find monsters.xml!"); + } + + xmlDocPtr doc = xmlParseMemory(data, size); + free(data); + + if (!doc) + { + logger->error("Monster Database: Error while parsing monster database (monsters.xml)!"); + } + + xmlNodePtr rootNode = xmlDocGetRootElement(doc); + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "monsters")) + { + logger->error("Monster Database: monster.xml is not a valid database file!"); + } + + //iterate s + for ( xmlNodePtr monsterNode = rootNode->xmlChildrenNode; + monsterNode != NULL; + monsterNode = monsterNode->next) + { + + if (!xmlStrEqual(monsterNode->name, BAD_CAST "monster")) + { + continue; + } + + MonsterInfo *currentInfo = new MonsterInfo(); + + currentInfo->setName (XML::getProperty(monsterNode, "name", "unnamed")); + + //iterate s and s + for ( xmlNodePtr spriteNode = monsterNode->xmlChildrenNode; + spriteNode != NULL; + spriteNode = spriteNode->next) + { + if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite")) + { + currentInfo->setSprite((const char*) spriteNode->xmlChildrenNode->content); + } + + if (xmlStrEqual(spriteNode->name, BAD_CAST "sound")) + { + std::string event = XML::getProperty(spriteNode, "event", ""); + const char *filename; + filename = (const char*) spriteNode->xmlChildrenNode->content; + + if (event == "hit") + { + currentInfo->addSound(EVENT_HIT, filename); + } + else if (event == "miss") + { + currentInfo->addSound(EVENT_MISS, filename); + } + else if (event == "hurt") + { + currentInfo->addSound(EVENT_HURT, filename); + } + else if (event == "die") + { + currentInfo->addSound(EVENT_DIE, filename); + } + else + { + logger->log("MonsterDB: Warning, sound effect %s for unknown event %s of monster %s", + filename, event.c_str(), currentInfo->getName().c_str()); + } + } + } + mMonsterInfos[XML::getProperty(monsterNode, "id", 0)] = currentInfo; + } +} + +void +MonsterDB::unload() +{ + for_each ( mMonsterInfos.begin(), mMonsterInfos.end(), + make_dtor(mMonsterInfos)); + mMonsterInfos.clear(); +} + + +const MonsterInfo& +MonsterDB::get (int id) +{ + MonsterInfoIterator i = mMonsterInfos.find(id); + + if (i == mMonsterInfos.end()) + { + logger->log("MonsterDB: Warning, unknown monster ID %d requested", id); + return mUnknown; + } + else + { + return *(i->second); + } +} diff --git a/src/resources/monsterdb.h b/src/resources/monsterdb.h new file mode 100644 index 00000000..b105665a --- /dev/null +++ b/src/resources/monsterdb.h @@ -0,0 +1,45 @@ +/* + * 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_MONSTER_DB_H +#define _TMW_MONSTER_DB_H + +#include + +#include "monsterinfo.h" + +namespace MonsterDB +{ + void + load(); + + void + unload(); + + const MonsterInfo& get (int id); + + typedef std::map MonsterInfos; + typedef MonsterInfos::iterator MonsterInfoIterator; +} + +#endif diff --git a/src/resources/monsterinfo.cpp b/src/resources/monsterinfo.cpp new file mode 100644 index 00000000..43aac32a --- /dev/null +++ b/src/resources/monsterinfo.cpp @@ -0,0 +1,70 @@ +/* + * 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: monsterinfo.cpp 2650 2006-09-03 15:00:47Z b_lindeijer $ + */ + +#include "monsterinfo.h" + +#include "../utils/dtor.h" + +MonsterInfo::MonsterInfo(): + mSprite("error.xml") +{ + +} + +MonsterInfo::~MonsterInfo() +{ + //kill vectors in mSoundEffects + for_each ( mSounds.begin(), mSounds.end(), + make_dtor(mSounds)); + mSounds.clear(); +} + + +void +MonsterInfo::addSound (SoundEvent event, std::string filename) +{ + if (mSounds.find(event) == mSounds.end()) + { + mSounds[event] = new std::vector; + } + + mSounds[event]->push_back("sfx/" + filename); +} + + +std::string +MonsterInfo::getSound (SoundEvent event) const +{ + std::map* >::const_iterator i; + + i = mSounds.find(event); + + if (i == mSounds.end()) + { + return ""; + } + else + { + return i->second->at(rand()%i->second->size()); + } +} diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h new file mode 100644 index 00000000..413dafa0 --- /dev/null +++ b/src/resources/monsterinfo.h @@ -0,0 +1,74 @@ +/* + * 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: monsterinfo.h 2650 2006-09-03 15:00:47Z b_lindeijer $ + */ + +#ifndef _TMW_MONSTERINFO_H_ +#define _TMW_MONSTERINFO_H_ + +#include +#include +#include + + +enum SoundEvent +{ + EVENT_HIT, + EVENT_MISS, + EVENT_HURT, + EVENT_DIE +}; + + +class MonsterInfo +{ + public: + MonsterInfo(); + + ~MonsterInfo(); + + void + setName(std::string name) { mName = name; } ; + + void + setSprite(std::string filename) { mSprite = filename; } + + void + addSound (SoundEvent event, std::string filename); + + const std::string& + getName () const { return mName; }; + + const std::string& + getSprite () const { return mSprite; }; + + std::string + getSound (SoundEvent event) const; + + private: + + std::string mName; + std::string mSprite; + + std::map* > mSounds; +}; + +#endif diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index bb51d023..45067302 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -32,6 +32,7 @@ #include "music.h" #include "soundeffect.h" #include "spriteset.h" +#include "spritedef.h" #include "../log.h" @@ -40,15 +41,33 @@ ResourceManager *ResourceManager::instance = NULL; ResourceManager::ResourceManager() { + logger->log("Initializing resource manager..."); } ResourceManager::~ResourceManager() { - // Release any remaining spritesets first because they depend on images + // Release any remaining spritedefs first because they depend on spritesets ResourceIterator iter = mResources.begin(); while (iter != mResources.end()) { - if (dynamic_cast(iter->second) != NULL) + if (dynamic_cast(iter->second) != 0) + { + cleanUp(iter->second); + ResourceIterator toErase = iter; + ++iter; + mResources.erase(toErase); + } + else + { + ++iter; + } + } + + // Release any remaining spritesets first because they depend on images + iter = mResources.begin(); + while (iter != mResources.end()) + { + if (dynamic_cast(iter->second) != 0) { cleanUp(iter->second); ResourceIterator toErase = iter; @@ -83,7 +102,7 @@ ResourceManager::cleanUp(Resource *res) bool ResourceManager::setWriteDir(const std::string &path) { - return (bool)PHYSFS_setWriteDir(path.c_str()); + return (bool) PHYSFS_setWriteDir(path.c_str()); } void @@ -96,7 +115,7 @@ ResourceManager::addToSearchPath(const std::string &path, bool append) bool ResourceManager::mkdir(const std::string &path) { - return (bool)PHYSFS_mkdir(path.c_str()); + return (bool) PHYSFS_mkdir(path.c_str()); } bool @@ -158,9 +177,9 @@ ResourceManager::get(const E_RESOURCE_TYPE &type, const std::string &idPath) free(buffer); - if (resource) { + if (resource) + { resource->incRef(); - mResources[idPath] = resource; } @@ -215,6 +234,27 @@ ResourceManager::getSpriteset(const std::string &imagePath, int w, int h) return spriteset; } +SpriteDef* +ResourceManager::getSprite(const std::string &path, int variant) +{ + std::stringstream ss; + ss << path << "[" << variant << "]"; + const std::string idPath = ss.str(); + + ResourceIterator resIter = mResources.find(idPath); + + if (resIter != mResources.end()) { + resIter->second->incRef(); + return dynamic_cast(resIter->second); + } + + SpriteDef *sprite = new SpriteDef(idPath, path, variant); + sprite->incRef(); + mResources[idPath] = sprite; + + return sprite; +} + void ResourceManager::release(const std::string &idPath) { @@ -246,18 +286,13 @@ ResourceManager::deleteInstance() void* ResourceManager::loadFile(const std::string &fileName, int &fileSize) { - // If the file doesn't exist indicate failure - if (!PHYSFS_exists(fileName.c_str())) { - logger->log("Warning: %s not found!", fileName.c_str()); - return NULL; - } - // Attempt to open the specified file using PhysicsFS PHYSFS_file *file = PHYSFS_openRead(fileName.c_str()); // If the handler is an invalid pointer indicate failure if (file == NULL) { - logger->log("Warning: %s failed to load!", fileName.c_str()); + logger->log("Warning: Failed to load %s: %s", + fileName.c_str(), PHYSFS_getLastError()); return NULL; } diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h index 0086b167..d458f96e 100644 --- a/src/resources/resourcemanager.h +++ b/src/resources/resourcemanager.h @@ -34,6 +34,7 @@ class Image; class Music; class SoundEffect; class Spriteset; +class SpriteDef; /** * A class for loading and managing resources. @@ -113,21 +114,21 @@ class ResourceManager get(const E_RESOURCE_TYPE &type, const std::string &idPath); /** - * Convenience wrapper around ResourceManager::create for loading + * Convenience wrapper around ResourceManager::get for loading * images. */ Image* getImage(const std::string &idPath); /** - * Convenience wrapper around ResourceManager::create for loading + * Convenience wrapper around ResourceManager::get for loading * songs. */ Music* getMusic(const std::string &idPath); /** - * Convenience wrapper around ResourceManager::create for loading + * Convenience wrapper around ResourceManager::get for loading * samples. */ SoundEffect* @@ -137,7 +138,15 @@ class ResourceManager * Creates a spriteset based on the image referenced by the given * path and the supplied sprite sizes */ - Spriteset* getSpriteset(const std::string &imagePath, int w, int h); + Spriteset* + getSpriteset(const std::string &imagePath, int w, int h); + + /** + * Creates a sprite definition based on a given path and the supplied + * variant. + */ + SpriteDef* + getSprite(const std::string &path, int variant = 0); /** * Releases a resource, removing it from the set of loaded resources. diff --git a/src/resources/soundeffect.cpp b/src/resources/soundeffect.cpp index 3340e5ea..bb35218e 100644 --- a/src/resources/soundeffect.cpp +++ b/src/resources/soundeffect.cpp @@ -23,6 +23,8 @@ #include "soundeffect.h" +#include "../log.h" + SoundEffect::SoundEffect(const std::string &idPath, Mix_Chunk *soundEffect): Resource(idPath), mChunk(soundEffect) @@ -41,13 +43,18 @@ SoundEffect::load(void *buffer, unsigned int bufferSize, // Load the raw file data from the buffer in an RWops structure SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize); - // Use Mix_LoadWAV_RW to load the raw music data - Mix_Chunk *tmpSoundEffect = Mix_LoadWAV_RW(rw, 0); - - // Now free the SDL_RWops data - SDL_FreeRW(rw); + // Load the music data and free the RWops structure + Mix_Chunk *tmpSoundEffect = Mix_LoadWAV_RW(rw, 1); - return new SoundEffect(idPath, tmpSoundEffect); + if (tmpSoundEffect) + { + return new SoundEffect(idPath, tmpSoundEffect); + } + else + { + logger->log("Error while loading sound effect (%s)", idPath.c_str()); + return NULL; + } } bool diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp new file mode 100644 index 00000000..bd273b3b --- /dev/null +++ b/src/resources/spritedef.cpp @@ -0,0 +1,381 @@ +/* + * 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 "spritedef.h" + +#include "../animation.h" +#include "../action.h" +#include "../graphics.h" +#include "../log.h" + +#include "resourcemanager.h" +#include "spriteset.h" +#include "image.h" + +#include "../utils/xml.h" + +SpriteDef::SpriteDef(const std::string &idPath, + const std::string &file, int variant): + Resource(idPath), + mAction(NULL), + mDirection(DIRECTION_DOWN), + mLastTime(0) +{ + load(file, variant); +} + +Action* +SpriteDef::getAction(SpriteAction action) const +{ + Actions::const_iterator i = mActions.find(action); + + if (i == mActions.end()) + { + logger->log("Warning: no action \"%u\" defined!", action); + return NULL; + } + + return i->second; +} + +void +SpriteDef::load(const std::string &animationFile, int variant) +{ + int size; + ResourceManager *resman = ResourceManager::getInstance(); + char *data = (char*) resman->loadFile(animationFile.c_str(), size); + + if (!data) { + logger->error("Animation: Could not find " + animationFile + "!"); + } + + xmlDocPtr doc = xmlParseMemory(data, size); + free(data); + + if (!doc) { + logger->error( + "Animation: Error while parsing animation definition file!"); + } + + xmlNodePtr node = xmlDocGetRootElement(doc); + if (!node || !xmlStrEqual(node->name, BAD_CAST "sprite")) { + logger->error( + "Animation: this is not a valid animation definition file!"); + } + + // Get the variant + int variant_num = XML::getProperty(node, "variants", 0); + int variant_offset = 0; + + if (variant_num > 0 && variant < variant_num) + { + variant_offset = variant * XML::getProperty(node, "variant_offset", 0); + } + + for (node = node->xmlChildrenNode; node != NULL; node = node->next) + { + if (xmlStrEqual(node->name, BAD_CAST "imageset")) + { + loadImageSet(node); + } + else if (xmlStrEqual(node->name, BAD_CAST "action")) + { + loadAction(node, variant_offset); + } + else if (xmlStrEqual(node->name, BAD_CAST "include")) + { + includeSprite(node); + } + } + + xmlFreeDoc(doc); + + // Complete missing actions + substituteAction(ACTION_STAND, ACTION_DEFAULT); + substituteAction(ACTION_WALK, ACTION_STAND); + substituteAction(ACTION_WALK, ACTION_RUN); + substituteAction(ACTION_ATTACK, ACTION_STAND); + substituteAction(ACTION_ATTACK_SWING, ACTION_ATTACK); + substituteAction(ACTION_ATTACK_STAB, ACTION_ATTACK_SWING); + substituteAction(ACTION_ATTACK_BOW, ACTION_ATTACK_STAB); + substituteAction(ACTION_ATTACK_THROW, ACTION_ATTACK_SWING); + substituteAction(ACTION_CAST_MAGIC, ACTION_ATTACK_SWING); + substituteAction(ACTION_USE_ITEM, ACTION_CAST_MAGIC); + substituteAction(ACTION_SIT, ACTION_STAND); + substituteAction(ACTION_SLEEP, ACTION_SIT); + substituteAction(ACTION_HURT, ACTION_STAND); + substituteAction(ACTION_DEAD, ACTION_HURT); +} + +void +SpriteDef::loadImageSet(xmlNodePtr node) +{ + int width = XML::getProperty(node, "width", 0); + int height = XML::getProperty(node, "height", 0); + std::string name = XML::getProperty(node, "name", ""); + std::string imageSrc = XML::getProperty(node, "src", ""); + + ResourceManager *resman = ResourceManager::getInstance(); + Spriteset *spriteset = resman->getSpriteset(imageSrc, width, height); + + if (!spriteset) + { + logger->error("Couldn't load imageset!"); + } + + mSpritesets[name] = spriteset; +} + +void +SpriteDef::loadAction(xmlNodePtr node, int variant_offset) +{ + const std::string actionName = XML::getProperty(node, "name", ""); + const std::string imagesetName = XML::getProperty(node, "imageset", ""); + + SpritesetIterator si = mSpritesets.find(imagesetName); + if (si == mSpritesets.end()) + { + logger->log("Warning: imageset \"%s\" not defined in %s", + imagesetName.c_str(), getIdPath().c_str()); + return; + } + Spriteset *imageset = si->second; + + SpriteAction actionType = makeSpriteAction(actionName); + if (actionType == ACTION_INVALID) + { + logger->log("Warning: Unknown action \"%s\" defined in %s", + actionName.c_str(), getIdPath().c_str()); + return; + } + Action *action = new Action(); + mActions[actionType] = action; + + // When first action set it as default direction + if (mActions.empty()) + { + mActions[ACTION_DEFAULT] = action; + } + + // Load animations + for (xmlNodePtr animationNode = node->xmlChildrenNode; + animationNode != NULL; + animationNode = animationNode->next) + { + if (xmlStrEqual(animationNode->name, BAD_CAST "animation")) + { + loadAnimation(animationNode, action, imageset, variant_offset); + } + } +} + +void +SpriteDef::loadAnimation(xmlNodePtr animationNode, + Action *action, Spriteset *imageset, + int variant_offset) +{ + std::string directionName = + XML::getProperty(animationNode, "direction", ""); + SpriteDirection directionType = makeSpriteDirection(directionName); + + if (directionType == DIRECTION_INVALID) + { + logger->log("Warning: Unknown direction \"%s\" used in %s", + directionName.c_str(), getIdPath().c_str()); + return; + } + + Animation *animation = new Animation(); + action->setAnimation(directionType, animation); + + // Get animation phases + for (xmlNodePtr phaseNode = animationNode->xmlChildrenNode; + phaseNode != NULL; + phaseNode = phaseNode->next) + { + int delay = XML::getProperty(phaseNode, "delay", 0); + int offsetX = XML::getProperty(phaseNode, "offsetX", 0); + int offsetY = XML::getProperty(phaseNode, "offsetY", 0); + offsetY -= imageset->getHeight() - 32; + offsetX -= imageset->getWidth() / 2 - 16; + + if (xmlStrEqual(phaseNode->name, BAD_CAST "frame")) + { + int index = XML::getProperty(phaseNode, "index", -1); + + if (index < 0) + { + logger->log("No valid value for 'index'"); + continue; + } + + Image *img = imageset->get(index + variant_offset); + + if (!img) + { + logger->log("No image at index " + (index + variant_offset)); + continue; + } + + animation->addPhase(img, delay, offsetX, offsetY); + } + else if (xmlStrEqual(phaseNode->name, BAD_CAST "sequence")) + { + int start = XML::getProperty(phaseNode, "start", -1); + int end = XML::getProperty(phaseNode, "end", -1); + + if (start < 0 || end < 0) + { + logger->log("No valid value for 'start' or 'end'"); + continue; + } + + while (end >= start) + { + Image *img = imageset->get(start + variant_offset); + + if (!img) + { + logger->log("No image at index " + + (start + variant_offset)); + continue; + } + + animation->addPhase(img, delay, offsetX, offsetY); + start++; + } + } + else if (xmlStrEqual(phaseNode->name, BAD_CAST "end")) + { + animation->addTerminator(); + } + } // for phaseNode +} + +void +SpriteDef::includeSprite(xmlNodePtr includeNode) +{ + std::string filename = XML::getProperty(includeNode, "file", ""); + ResourceManager *resman = ResourceManager::getInstance(); + SpriteDef *sprite = resman->getSprite("graphics/sprites/" + filename); + + // TODO: Somehow implement actually including it + sprite->decRef(); +} + +void +SpriteDef::substituteAction(SpriteAction complete, SpriteAction with) +{ + if (mActions.find(complete) == mActions.end()) + { + Actions::iterator i = mActions.find(with); + if (i != mActions.end()) { + mActions[complete] = i->second; + } + } +} + +SpriteDef::~SpriteDef() +{ + for (SpritesetIterator i = mSpritesets.begin(); + i != mSpritesets.end(); ++i) + { + i->second->decRef(); + } +} + +SpriteAction +SpriteDef::makeSpriteAction(const std::string& action) +{ + if (action == "" || action == "default") { + return ACTION_DEFAULT; + } + if (action == "stand") { + return ACTION_STAND; + } + else if (action == "walk") { + return ACTION_WALK; + } + else if (action == "run") { + return ACTION_RUN; + } + else if (action == "attack") { + return ACTION_ATTACK; + } + else if (action == "attack_swing") { + return ACTION_ATTACK_SWING; + } + else if (action == "attack_stab") { + return ACTION_ATTACK_STAB; + } + else if (action == "attack_bow") { + return ACTION_ATTACK_BOW; + } + else if (action == "attack_throw") { + return ACTION_ATTACK_THROW; + } + else if (action == "cast_magic") { + return ACTION_CAST_MAGIC; + } + else if (action == "use_item") { + return ACTION_USE_ITEM; + } + else if (action == "sit") { + return ACTION_SIT; + } + else if (action == "sleep") { + return ACTION_SLEEP; + } + else if (action == "hurt") { + return ACTION_HURT; + } + else if (action == "dead") { + return ACTION_DEAD; + } + else { + return ACTION_INVALID; + } +} + +SpriteDirection +SpriteDef::makeSpriteDirection(const std::string& direction) +{ + if (direction == "" || direction == "default") { + return DIRECTION_DEFAULT; + } + else if (direction == "up") { + return DIRECTION_UP; + } + else if (direction == "left") { + return DIRECTION_LEFT; + } + else if (direction == "right") { + return DIRECTION_RIGHT; + } + else if (direction == "down") { + return DIRECTION_DOWN; + } + else { + return DIRECTION_INVALID; + }; +} diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h new file mode 100644 index 00000000..64414259 --- /dev/null +++ b/src/resources/spritedef.h @@ -0,0 +1,158 @@ +/* + * 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_SPRITEDEF_H +#define _TMW_SPRITEDEF_H + +#include "resource.h" + +#include +#include + +#include + +class Action; +class Graphics; +class Spriteset; +struct AnimationPhase; +class Animation; + +enum SpriteAction +{ + ACTION_DEFAULT = 0, + ACTION_STAND, + ACTION_WALK, + ACTION_RUN, + ACTION_ATTACK, + ACTION_ATTACK_SWING, + ACTION_ATTACK_STAB, + ACTION_ATTACK_BOW, + ACTION_ATTACK_THROW, + ACTION_CAST_MAGIC, + ACTION_USE_ITEM, + ACTION_SIT, + ACTION_SLEEP, + ACTION_HURT, + ACTION_DEAD, + ACTION_INVALID +}; + +enum SpriteDirection +{ + DIRECTION_DEFAULT = 0, + DIRECTION_DOWN, + DIRECTION_UP, + DIRECTION_LEFT, + DIRECTION_RIGHT, + DIRECTION_INVALID +}; + +/** + * Defines a class to load an animation. + */ +class SpriteDef : public Resource +{ + public: + /** + * Constructor. + */ + SpriteDef(const std::string &idPath, + const std::string &file, int variant); + + /** + * Destructor. + */ + ~SpriteDef(); + + /** + * Returns the specified action. + */ + Action* + getAction(SpriteAction action) const; + + private: + /** + * Loads a sprite definition file. + */ + void + load(const std::string &file, int variant); + + /** + * Loads an imageset element. + */ + void + loadImageSet(xmlNodePtr node); + + /** + * Loads an action element. + */ + void + loadAction(xmlNodePtr node, int variant_offset); + + /** + * Loads an animation element. + */ + void + loadAnimation(xmlNodePtr animationNode, + Action *action, Spriteset *imageset, + int variant_offset); + + /** + * Include another sprite into this one. + */ + void + includeSprite(xmlNodePtr includeNode); + + /** + * When there are no animations defined for the action "complete", its + * animations become a copy of those of the action "with". + */ + void + substituteAction(SpriteAction complete, SpriteAction with); + + /** + * Converts a string into a SpriteAction enum. + */ + static SpriteAction + makeSpriteAction(const std::string &action); + + /** + * Converts a string into a SpriteDirection enum. + */ + static SpriteDirection + makeSpriteDirection(const std::string &direction); + + + typedef std::map Spritesets; + typedef Spritesets::iterator SpritesetIterator; + + typedef std::map Actions; + + Spritesets mSpritesets; + Actions mActions; + Action *mAction; + SpriteDirection mDirection; + int mLastTime; +}; + +#endif diff --git a/src/resources/spriteset.h b/src/resources/spriteset.h index c51e6a75..7f6b42df 100644 --- a/src/resources/spriteset.h +++ b/src/resources/spriteset.h @@ -32,7 +32,9 @@ class Image; /** - * Stores a complete set of sprites. + * Stores a set of subimages originating from a single image. + * + * TODO: Should probably be renamed to ImageSet or TileSet. */ class Spriteset : public Resource { @@ -40,7 +42,7 @@ class Spriteset : public Resource /* * Cuts the passed image in a grid of sub images. */ - Spriteset(const std::string& idPath, Image *img, int w, int h); + Spriteset(const std::string &idPath, Image *img, int w, int h); /** * Destructor. diff --git a/src/sound.cpp b/src/sound.cpp index 182be3d6..8ba8fe99 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -191,15 +191,15 @@ void Sound::fadeOutMusic(int ms) } } -void Sound::playSfx(const char *path) +void Sound::playSfx(const std::string &path) { - if (!mInstalled) return; + if (!mInstalled || path.length() == 0) return; ResourceManager *resman = ResourceManager::getInstance(); SoundEffect *sample = resman->getSoundEffect(path); if (sample) { + logger->log("Sound::playSfx() Playing: %s", path.c_str()); sample->play(0, 120); - logger->log("Sound::playSfx() Playing: %s", path); } } diff --git a/src/sound.h b/src/sound.h index 39901121..07db0587 100644 --- a/src/sound.h +++ b/src/sound.h @@ -26,6 +26,8 @@ #include +#include + /** Sound engine * * \ingroup CORE @@ -105,7 +107,7 @@ class Sound { * * \param path Full path to file */ - void playSfx(const char *path); + void playSfx(const std::string &path); private: bool mInstalled; diff --git a/src/sprite.h b/src/sprite.h index 282091cc..51811149 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -47,7 +47,7 @@ class Sprite * partly with the clipping rectangle support. */ virtual void - draw(Graphics *graphics, int offsetX, int offsetY) = 0; + draw(Graphics *graphics, int offsetX, int offsetY) const = 0; /** * Returns the pixel Y coordinate of the sprite. diff --git a/src/utils/wingettimeofday.h b/src/utils/wingettimeofday.h new file mode 100644 index 00000000..0f8b767a --- /dev/null +++ b/src/utils/wingettimeofday.h @@ -0,0 +1,111 @@ +/* + * The Mana World Server + * 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 + */ + +#ifndef _TMWSERV_WINGETTIMEOFDAY_H_ +#define _TMWSERV_WINGETTIMEOFDAY_H_ + +#ifdef WIN32 + +#include + +/* + * the function gettimeofday() is available on UNIX but not on windows. + * this header defines a windows implementation as a + * GetSystemTimeAsFileTime() wrapper. + */ + +int gettimeofday(struct timeval* tv, void *tz) +/*--------------------------------------------------------------- + * Copyright (c) 1999,2000,2001,2002,2003 + * The Board of Trustees of the University of Illinois + * All Rights Reserved. + *--------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software (Iperf) and associated + * documentation files (the "Software"), to deal in the Software + * without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and + * the following disclaimers. + * + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials + * provided with the distribution. + * + * + * Neither the names of the University of Illinois, NCSA, + * nor the names of its contributors may be used to endorse + * or promote products derived from this Software without + * specific prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ________________________________________________________________ + * National Laboratory for Applied Network Research + * National Center for Supercomputing Applications + * University of Illinois at Urbana-Champaign + * http://www.ncsa.uiuc.edu + * ________________________________________________________________ + * + * gettimeofday.c + * by Mark Gates + * ------------------------------------------------------------------- + * A (hack) implementation of gettimeofday for Windows. + * Since I send sec/usec in UDP packets, this made the most sense. + * ------------------------------------------------------------------- */ +{ + FILETIME time; + double timed; + + GetSystemTimeAsFileTime( &time ); + + // Apparently Win32 has units of 1e-7 sec (tenths of microsecs) + // 4294967296 is 2^32, to shift high word over + // 11644473600 is the number of seconds between + // the Win32 epoch 1601-Jan-01 and the Unix epoch 1970-Jan-01 + // Tests found floating point to be 10x faster than 64bit int math. + + timed = ((time.dwHighDateTime * 4294967296e-7) - 11644473600.0) + + (time.dwLowDateTime * 1e-7); + + tv->tv_sec = (long) timed; + tv->tv_usec = (long) ((timed - tv->tv_sec) * 1e6); + + return 0; +} + + +#endif // WIN32 +#endif diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp new file mode 100644 index 00000000..7c917dc0 --- /dev/null +++ b/src/utils/xml.cpp @@ -0,0 +1,54 @@ +/* + * 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 "xml.h" + +namespace XML +{ + int + getProperty(xmlNodePtr node, const char* name, int def) + { + int &ret = def; + + xmlChar *prop = xmlGetProp(node, BAD_CAST name); + if (prop) { + ret = atoi((char*)prop); + xmlFree(prop); + } + + return ret; + } + + std::string + getProperty(xmlNodePtr node, const char *name, const std::string &def) + { + xmlChar *prop = xmlGetProp(node, BAD_CAST name); + if (prop) { + std::string val = (char*)prop; + xmlFree(prop); + return val; + } + + return def; + } +} diff --git a/src/utils/xml.h b/src/utils/xml.h new file mode 100644 index 00000000..54ed9951 --- /dev/null +++ b/src/utils/xml.h @@ -0,0 +1,46 @@ +/* + * 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_XML_H +#define _TMW_XML_H + +#include + +#include + +namespace XML +{ + /** + * Gets an integer property from an xmlNodePtr. + */ + int + getProperty(xmlNodePtr node, const char *name, int def); + + /** + * Gets a string property from an xmlNodePtr. + */ + std::string + getProperty(xmlNodePtr node, const char *name, const std::string &def); +} + +#endif diff --git a/tmw.cbp b/tmw.cbp index b8931cf6..d36a8bd0 100644 --- a/tmw.cbp +++ b/tmw.cbp @@ -21,31 +21,35 @@ - - - - - - + + + + + - + - - - - - + + + + + + + + + + + + + + - + - + - + - + + + + + + + + + + + + + + + + + -- cgit v1.2.3-70-g09d2 From 36d28236321b6a2824ad4f394faeabbf79626808 Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Tue, 31 Jul 2007 21:29:00 +0000 Subject: Removed legacy inventory code. Added display of equipment. --- ChangeLog | 14 +++ src/Makefile.am | 2 - src/equipment.cpp | 23 +---- src/equipment.h | 36 ++------ src/game.cpp | 3 - src/game.h | 1 - src/gui/equipmentwindow.cpp | 13 ++- src/gui/inventorywindow.cpp | 14 +-- src/gui/itemcontainer.cpp | 2 +- src/gui/popupmenu.cpp | 14 +-- src/gui/trade.cpp | 8 +- src/gui/trade.h | 2 +- src/inventory.cpp | 11 +-- src/inventory.h | 4 +- src/item.cpp | 10 ++ src/item.h | 33 +------ src/localplayer.cpp | 17 +--- src/localplayer.h | 4 +- src/net/buysellhandler.cpp | 8 +- src/net/equipmenthandler.cpp | 214 ------------------------------------------- src/net/equipmenthandler.h | 37 -------- src/net/inventoryhandler.cpp | 95 ++----------------- src/net/protocol.h | 69 +------------- src/net/skillhandler.cpp | 6 +- src/net/tradehandler.cpp | 2 +- 25 files changed, 74 insertions(+), 568 deletions(-) delete mode 100644 src/net/equipmenthandler.cpp delete mode 100644 src/net/equipmenthandler.h (limited to 'src/net/skillhandler.cpp') diff --git a/ChangeLog b/ChangeLog index ac47b98c..d3c7072e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2007-07-31 Guillaume Melquiond + + * src/net/equipmenthandler.cpp, src/net/equipmenthandler.h, + src/Makefile.am, src/game.h, src/game.cpp: Deleted dead handler. + * src/net/buysellhandler.cpp, src/net/skillhandler.cpp, + src/net/protocol.h: No need to compile legacy handlers. + * src/localplayer.cpp, src/item.cpp, src/inventory.h, + src/gui/trade.cpp, src/gui/equipmentwindow.cpp, src/item.h, + src/gui/inventorywindow.cpp, src/gui/itemcontainer.cpp, + src/gui/trade.h, src/gui/popupmenu.cpp, src/inventory.cpp, + src/equipment.h, src/net/tradehandler.cpp, src/equipment.cpp, + src/localplayer.h: Removed legacy inventory code. + * src/net/inventoryhandler.cpp: Added display of equipment. + 2007-07-29 Björn Steinbrink * CMake/Modules/FindLibXml2.cmake, CMake/Modules/FindLibcurl.cmake, diff --git a/src/Makefile.am b/src/Makefile.am index 92c1b1b2..0ccdd777 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -142,8 +142,6 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ net/chathandler.cpp \ net/connection.h \ net/connection.cpp \ - net/equipmenthandler.h \ - net/equipmenthandler.cpp \ net/internal.h \ net/internal.cpp \ net/inventoryhandler.h \ diff --git a/src/equipment.cpp b/src/equipment.cpp index 6cd4d967..1dfc7d02 100644 --- a/src/equipment.cpp +++ b/src/equipment.cpp @@ -21,29 +21,12 @@ * $Id$ */ -#include "equipment.h" - #include -#include "item.h" - -Equipment::Equipment(): - mArrows(0) -{ - std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*)0); -} +#include "equipment.h" -void -Equipment::removeEquipment(Item *item) +Equipment::Equipment() { - Item **i = std::find(mEquipment, mEquipment+EQUIPMENT_SIZE, item); - if (i != mEquipment+EQUIPMENT_SIZE) { - *i = 0; - } + std::fill_n(mEquipment, EQUIPMENT_SIZE, 0); } -void Equipment::setEquipment(int index, Item *item) -{ - mEquipment[index] = item; - item->setEquipped(true); -} diff --git a/src/equipment.h b/src/equipment.h index db9cf27d..f178e0ca 100644 --- a/src/equipment.h +++ b/src/equipment.h @@ -39,41 +39,17 @@ class Equipment /** * Get equipment at the given slot. */ - Item* - getEquipment(int index) { return mEquipment[index]; } + int getEquipment(int index) + { return mEquipment[index]; } /** * Set equipment at the given slot. */ - void - setEquipment(int index, Item *item); + void setEquipment(int index, int id) + { mEquipment[index] = id; } - /** - * Remove equipment from the given slot. - */ - void - removeEquipment(int index) { mEquipment[index] = 0; } - - /** - * Remove the given item from equipment. - */ - void removeEquipment(Item *item); - - /** - * Get the item used in the arrow slot. - */ - Item* - getArrows() { return mArrows; } - - /** - * Set the item used in the arrow slot. - */ - void - setArrows(Item *arrows) { mArrows = arrows; } - - protected: - Item *mEquipment[EQUIPMENT_SIZE]; - Item *mArrows; + private: + int mEquipment[EQUIPMENT_SIZE]; }; #endif diff --git a/src/game.cpp b/src/game.cpp index 7385549b..495f9a8d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -69,7 +69,6 @@ #include "net/beinghandler.h" #include "net/buysellhandler.h" #include "net/chathandler.h" -#include "net/equipmenthandler.h" #include "net/inventoryhandler.h" #include "net/itemhandler.h" #include "net/network.h" @@ -227,7 +226,6 @@ Game::Game(): mBeingHandler(new BeingHandler()), mBuySellHandler(new BuySellHandler()), mChatHandler(new ChatHandler()), - mEquipmentHandler(new EquipmentHandler()), mInventoryHandler(new InventoryHandler()), mItemHandler(new ItemHandler()), mNpcHandler(new NPCHandler()), @@ -271,7 +269,6 @@ Game::Game(): Net::registerHandler(mBeingHandler.get()); Net::registerHandler(mBuySellHandler.get()); Net::registerHandler(mChatHandler.get()); - Net::registerHandler(mEquipmentHandler.get()); Net::registerHandler(mInventoryHandler.get()); Net::registerHandler(mItemHandler.get()); Net::registerHandler(mNpcHandler.get()); diff --git a/src/game.h b/src/game.h index 408b933b..d1b438bd 100644 --- a/src/game.h +++ b/src/game.h @@ -63,7 +63,6 @@ class Game : public ConfigListener MessageHandlerPtr mBeingHandler; MessageHandlerPtr mBuySellHandler; MessageHandlerPtr mChatHandler; - MessageHandlerPtr mEquipmentHandler; MessageHandlerPtr mInventoryHandler; MessageHandlerPtr mItemHandler; MessageHandlerPtr mNpcHandler; diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 1ae887bc..27c97ea0 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -50,9 +50,6 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) // Draw window graphics Window::draw(graphics); - Item *item; - Image *image; - // Rectangles around items are black graphics->setColor(gcn::Color(0, 0, 0)); @@ -60,17 +57,17 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) graphics->drawRectangle(gcn::Rectangle(10 + 36 * (i % 4), 36 * (i / 4) + 25, 32, 32)); - if (!(item = mEquipment->getEquipment(i))) { - continue; - } + int item = mEquipment->getEquipment(i); + if (!item) continue; - image = item->getInfo().getImage(); + Image *image = Item(item).getInfo().getImage(); static_cast(graphics)-> drawImage(image, 36 * (i % 4) + 10, 36 * (i / 4) + 25); } graphics->drawRectangle(gcn::Rectangle(160, 25, 32, 32)); + /* if (!(item = mEquipment->getArrows())) { return; } @@ -80,4 +77,6 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) static_cast(graphics)->drawImage(image, 160, 25); graphics->drawText(toString(item->getQuantity()), 170, 62, gcn::Graphics::CENTER); + */ + return; } diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 2018c75a..2ad35095 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -109,12 +109,7 @@ void InventoryWindow::action(const gcn::ActionEvent &event) if (event.getId() == "use") { if (item->isEquipment()) { - if (item->isEquipped()) { - player_node->unequipItem(item); - } - else { - player_node->equipItem(item); - } + player_node->equipItem(item); } else { player_node->useItem(item); @@ -215,12 +210,7 @@ void InventoryWindow::updateButtons() if ((item = mItems->getItem()) && item->isEquipment()) { - if (item->isEquipped()) { - mUseButton->setCaption("Unequip"); - } - else { - mUseButton->setCaption("Equip"); - } + mUseButton->setCaption("Equip"); } else { mUseButton ->setCaption("Use"); diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index 0e5bcce9..444be2a2 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -116,7 +116,7 @@ ItemContainer::draw(gcn::Graphics *graphics) // Draw item caption graphics->drawText( - (item->isEquipped() ? "Eq." : toString(item->getQuantity())), + toString(item->getQuantity()), itemX + gridWidth / 2, itemY + gridHeight - 11, gcn::Graphics::CENTER); diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index cc764d35..f308bbfd 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -168,14 +168,7 @@ void PopupMenu::handleLink(const std::string& link) assert(mItem); if (mItem->isEquipment()) { - if (mItem->isEquipped()) - { - player_node->unequipItem(mItem); - } - else - { - player_node->equipItem(mItem); - } + player_node->equipItem(mItem); } else { @@ -221,10 +214,7 @@ void PopupMenu::showPopup(int x, int y, Item *item) if (item->isEquipment()) { - if (item->isEquipped()) - mBrowserBox->addRow("@@use|Unequip@@"); - else - mBrowserBox->addRow("@@use|Equip@@"); + mBrowserBox->addRow("@@use|Equip@@"); } else mBrowserBox->addRow("@@use|Use@@"); diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index 37faafdf..337bd7ea 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -137,12 +137,12 @@ void TradeWindow::addMoney(int amount) mMoneyLabel->adjustSize(); } -void TradeWindow::addItem(int id, bool own, int quantity, bool equipment) +void TradeWindow::addItem(int id, bool own, int quantity) { if (own) { - mMyInventory->addItem(id, quantity, equipment); + mMyInventory->addItem(id, quantity); } else { - mPartnerInventory->addItem(id, quantity, equipment); + mPartnerInventory->addItem(id, quantity); } } @@ -217,7 +217,7 @@ void TradeWindow::receivedOk(bool own) void TradeWindow::tradeItem(Item *item, int quantity) { Net::GameServer::Player::tradeItem(item->getInvIndex(), quantity); - addItem(item->getId(), true, quantity, item->isEquipment()); + addItem(item->getId(), true, quantity); item->increaseQuantity(-quantity); } diff --git a/src/gui/trade.h b/src/gui/trade.h index 1c64c255..bffda13f 100644 --- a/src/gui/trade.h +++ b/src/gui/trade.h @@ -64,7 +64,7 @@ class TradeWindow : public Window, gcn::ActionListener, SelectionListener /** * Add an item to the trade window. */ - void addItem(int id, bool own, int quantity, bool equipment); + void addItem(int id, bool own, int quantity); /** * Remove a item from the trade window. diff --git a/src/inventory.cpp b/src/inventory.cpp index ac0bce18..11c52421 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -49,7 +49,7 @@ Inventory::~Inventory() Item* Inventory::getItem(int index) { - if (index < 0 || index > INVENTORY_SIZE) + if (index < 0 || index >= INVENTORY_SIZE) { return 0; } @@ -57,16 +57,15 @@ Item* Inventory::getItem(int index) return &mItems[index]; } -void Inventory::addItem(int id, int quantity, bool equipment) +void Inventory::addItem(int id, int quantity) { - addItem(getFreeSlot(), id, quantity, equipment); + addItem(getFreeSlot(), id, quantity); } -void Inventory::addItem(int index, int id, int quantity, bool equipment) +void Inventory::addItem(int index, int id, int quantity) { mItems[index].setId(id); mItems[index].increaseQuantity(quantity); - mItems[index].setEquipment(equipment); } @@ -75,7 +74,6 @@ void Inventory::clear() for (int i = 0; i < INVENTORY_SIZE; i++) { mItems[i].setId(-1); mItems[i].setQuantity(0); - mItems[i].setEquipped(false); } } @@ -85,7 +83,6 @@ void Inventory::removeItem(int id) if (mItems[i].getId() == id) { mItems[i].setId(-1); mItems[i].setQuantity(0); - mItems[i].setEquipped(false); } } } diff --git a/src/inventory.h b/src/inventory.h index 32ae393e..ce537f34 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -49,12 +49,12 @@ class Inventory /** * Adds a new item in a free slot. */ - void addItem(int id, int quantity, bool equipment); + void addItem(int id, int quantity); /** * Adds a new item at a given position. */ - void addItem(int index, int id, int quantity, bool equipment); + void addItem(int index, int id, int quantity); /** * Remove a item from the inventory. diff --git a/src/item.cpp b/src/item.cpp index 3cea30e5..487f17da 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -21,3 +21,13 @@ * $Id$ */ +#include "item.h" + +Item::Item(int id, int quantity) : + mId(id), + mQuantity(quantity) +{ + // Either type or slot, both are unused anyway. -- silene + mEquipment = getInfo().getType(); +} + diff --git a/src/item.h b/src/item.h index 47cdb1a9..2a60bf3a 100644 --- a/src/item.h +++ b/src/item.h @@ -35,19 +35,7 @@ class Item /** * Constructor. */ - Item(int id = -1, int quantity = 0, - bool equipment = false, bool equipped = false): - mId(id), - mQuantity(quantity), - mEquipment(equipment), - mEquipped(equipped) - { - } - - /** - * Destructor. - */ - ~Item() {} + Item(int id = -1, int quantity = 0); /** * Sets the item id, identifying the item type. @@ -79,30 +67,12 @@ class Item int getQuantity() const { return mQuantity; } - /** - * Sets whether this item is considered equipment. - */ - void - setEquipment(bool equipment) { mEquipment = equipment; } - /** * Returns whether this item is considered equipment. */ bool isEquipment() const { return mEquipment; } - /** - * Sets whether this item is equipped. - */ - void - setEquipped(bool equipped) { mEquipped = equipped; } - - /** - * Returns whether this item is equipped. - */ - bool - isEquipped() const { return mEquipped; } - /** * Sets the inventory index of this item. */ @@ -125,7 +95,6 @@ class Item int mId; /**< Item type id. */ int mQuantity; /**< Number of items. */ bool mEquipment; /**< Item is equipment. */ - bool mEquipped; /**< Item is equipped. */ int mInvIndex; /**< Inventory index. */ }; diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 5945127f..b4fc5957 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -95,16 +95,6 @@ void LocalPlayer::clearInventory() mInventory->clear(); } -void LocalPlayer::addInvItem(int id, int quantity, bool equipment) -{ - mInventory->addItem(id, quantity, equipment); -} - -void LocalPlayer::addInvItem(int index, int id, int quantity, bool equipment) -{ - mInventory->addItem(index, id, quantity, equipment); -} - Item* LocalPlayer::getInvItem(int index) { return mInventory->getItem(index); @@ -115,11 +105,8 @@ void LocalPlayer::equipItem(Item *item) Net::GameServer::Player::equip(item->getInvIndex()); } -void LocalPlayer::unequipItem(Item *item) +void LocalPlayer::unequipItem(int slot) { - if (!item) - return; - // XXX Convert for new server /* MessageOut outMsg(CMSG_PLAYER_UNEQUIP); @@ -127,7 +114,7 @@ void LocalPlayer::unequipItem(Item *item) */ // Tidy equipment directly to avoid weapon still shown bug, by instance - mEquipment->removeEquipment(item); + mEquipment->setEquipment(slot, 0); } void LocalPlayer::useItem(Item *item) diff --git a/src/localplayer.h b/src/localplayer.h index c3a74b52..edadd7a0 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -134,8 +134,6 @@ class LocalPlayer : public Player virtual Type getType() const; void clearInventory(); - void addInvItem(int id, int quantity, bool equipment); - void addInvItem(int index, int id, int quantity, bool equipment); Item* getInvItem(int index); /** @@ -146,7 +144,7 @@ class LocalPlayer : public Player /** * Unequips an item. */ - void unequipItem(Item *item); + void unequipItem(int slot); void useItem(Item *item); void dropItem(Item *item, int quantity); diff --git a/src/net/buysellhandler.cpp b/src/net/buysellhandler.cpp index 45dfb9ad..2f22b0e6 100644 --- a/src/net/buysellhandler.cpp +++ b/src/net/buysellhandler.cpp @@ -44,11 +44,6 @@ extern Window *buySellDialog; BuySellHandler::BuySellHandler() { static const Uint16 _messages[] = { - SMSG_NPC_BUY_SELL_CHOICE, - SMSG_NPC_BUY, - SMSG_NPC_SELL, - SMSG_NPC_BUY_RESPONSE, - SMSG_NPC_SELL_RESPONSE, 0 }; handledMessages = _messages; @@ -56,9 +51,9 @@ BuySellHandler::BuySellHandler() void BuySellHandler::handleMessage(MessageIn &msg) { - int n_items; switch (msg.getId()) { +#if 0 case SMSG_NPC_BUY_SELL_CHOICE: buyDialog->setVisible(false); buyDialog->reset(); @@ -126,5 +121,6 @@ void BuySellHandler::handleMessage(MessageIn &msg) chatWindow->chatLog("Unable to sell", BY_SERVER); } break; +#endif } } diff --git a/src/net/equipmenthandler.cpp b/src/net/equipmenthandler.cpp deleted file mode 100644 index c0072a45..00000000 --- a/src/net/equipmenthandler.cpp +++ /dev/null @@ -1,214 +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 "equipmenthandler.h" - -#include "messagein.h" -#include "protocol.h" - -#include "../being.h" -#include "../beingmanager.h" -#include "../equipment.h" -#include "../item.h" -#include "../localplayer.h" -#include "../log.h" - -#include "../gui/chat.h" - -EquipmentHandler::EquipmentHandler() -{ - static const Uint16 _messages[] = { - SMSG_PLAYER_EQUIPMENT, - SMSG_PLAYER_EQUIP, - 0x01d7, - SMSG_PLAYER_UNEQUIP, - SMSG_PLAYER_ARROW_EQUIP, - SMSG_PLAYER_ATTACK_RANGE, - 0 - }; - handledMessages = _messages; -} - -void EquipmentHandler::handleMessage(MessageIn &msg) -{ - Sint32 itemCount; - Sint16 index, equipPoint, itemId; - Sint8 type; - int mask, position; - Being *being; - Item *item; - - switch (msg.getId()) - { - case SMSG_PLAYER_EQUIPMENT: - 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 - - player_node->addInvItem(index, itemId, 1, true); - - if (equipPoint) - { - mask = 1; - position = 0; - while (!(equipPoint & mask)) - { - mask <<= 1; - position++; - } - item = player_node->getInvItem(index); - player_node->mEquipment->setEquipment(position, item); - } - } - break; - - case SMSG_PLAYER_EQUIP: - index = msg.readShort(); - equipPoint = msg.readShort(); - type = msg.readByte(); - - logger->log("Equipping: %i %i %i", index, equipPoint, type); - - if (!type) { - chatWindow->chatLog("Unable to equip.", BY_SERVER); - break; - } - - if (!equipPoint) { - // No point given, no point in searching - break; - } - - // Unequip any existing equipped item in this position - mask = 1; - position = 0; - while (!(equipPoint & mask)) { - mask <<= 1; - position++; - } - logger->log("Position %i", position); - item = player_node->mEquipment->getEquipment(position); - if (item) { - item->setEquipped(false); - } - - item = player_node->getInvItem(index); - player_node->mEquipment->setEquipment(position, item); - player_node->setWeaponById(item->getId()); - break; - - case 0x01d7: - // Equipment related - being = beingManager->findBeing(msg.readLong()); - msg.readByte(); // equip point - itemId = msg.readShort(); - msg.readShort(); // item id 2 - - if (!being) - break; - - being->setWeaponById(itemId); - break; - - case SMSG_PLAYER_UNEQUIP: - index = msg.readShort(); - equipPoint = msg.readShort(); - type = msg.readByte(); - - if (!type) { - chatWindow->chatLog("Unable to unequip.", BY_SERVER); - break; - } - - if (!equipPoint) { - // No point given, no point in searching - break; - } - - mask = 1; - position = 0; - while (!(equipPoint & mask)) { - mask <<= 1; - position++; - } - - item = player_node->getInvItem(index); - - if (!item) - break; - - item->setEquipped(false); - - switch (item->getId()) { - case 529: - case 1199: - player_node->mEquipment->setArrows(NULL); - break; - case 521: - case 522: - case 530: - case 536: - case 1200: - case 1201: - player_node->setWeapon(0); - // TODO: Why this break? Shouldn't a weapon be - // unequipped in inventory too? - break; - default: - player_node->mEquipment->removeEquipment(position); - break; - } - logger->log("Unequipping: %i %i(%i) %i", - index, equipPoint, type, position); - break; - - case SMSG_PLAYER_ATTACK_RANGE: - player_node->setAttackRange(msg.readShort()); - break; - - case SMSG_PLAYER_ARROW_EQUIP: - itemId = msg.readShort(); - - if (itemId <= 1) - break; - - item = player_node->getInvItem(itemId); - if (!item) - break; - - item->setEquipped(true); - player_node->mEquipment->setArrows(item); - logger->log("Arrows equipped: %i", itemId); - break; - } -} diff --git a/src/net/equipmenthandler.h b/src/net/equipmenthandler.h deleted file mode 100644 index c9c65d67..00000000 --- a/src/net/equipmenthandler.h +++ /dev/null @@ -1,37 +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_NET_EQUIPMENTHANDLER_H -#define _TMW_NET_EQUIPMENTHANDLER_H - -#include "messagehandler.h" - -class EquipmentHandler : public MessageHandler -{ - public: - EquipmentHandler(); - - void handleMessage(MessageIn &msg); -}; - -#endif diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp index 40febee2..ce01c3dc 100644 --- a/src/net/inventoryhandler.cpp +++ b/src/net/inventoryhandler.cpp @@ -28,22 +28,17 @@ #include "messagein.h" #include "protocol.h" -#include "../resources/iteminfo.h" +#include "../equipment.h" +#include "../inventory.h" #include "../item.h" #include "../localplayer.h" #include "../gui/chat.h" +#include "../resources/iteminfo.h" InventoryHandler::InventoryHandler() { static const Uint16 _messages[] = { - /* - SMSG_PLAYER_INVENTORY, - SMSG_PLAYER_INVENTORY_ADD, - SMSG_PLAYER_INVENTORY_REMOVE, - SMSG_PLAYER_INVENTORY_USE, - SMSG_ITEM_USE_RESPONSE, - */ GPMSG_INVENTORY_FULL, GPMSG_INVENTORY, 0 @@ -64,90 +59,18 @@ void InventoryHandler::handleMessage(MessageIn &msg) { int slot = msg.readByte(); int id = msg.readShort(); - if (slot >= 32) + if (slot < EQUIPMENT_SIZE) + { + player_node->mEquipment->setEquipment(slot, id); + } + else if (slot >= 32 && slot < 32 + INVENTORY_SIZE) { - int amount = msg.readByte(); + int amount = id ? msg.readByte() : 0; Item *it = player_node->getInvItem(slot - 32); it->setId(id); it->setQuantity(amount); } }; break; - - -#if 0 - 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; - - for (int loop = 0; loop < number; loop++) - { - index = msg.readShort(); - itemId = msg.readShort(); - msg.readByte(); // type - msg.readByte(); // identify flag - amount = msg.readShort(); - - player_node->addInvItem(index, itemId, amount, false); - - // Trick because arrows are not considered equipment - if (itemId == 1199 || itemId == 529) - { - player_node->getInvItem(index)->setEquipment(true); - } - } - 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) { - chatWindow->chatLog("Unable to pick up item", BY_SERVER); - } else { - const ItemInfo &itemInfo = ItemDB::get(itemId); - chatWindow->chatLog("You picked up a " + - itemInfo.getName(), BY_SERVER); - player_node->addInvItem(index, itemId, amount, equipType != 0); - } - break; - - case SMSG_PLAYER_INVENTORY_REMOVE: - 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 - - player_node->getInvItem(index)->setQuantity(amount); - break; - - case SMSG_ITEM_USE_RESPONSE: - index = msg.readShort(); - amount = msg.readShort(); - - if (msg.readByte() == 0) { - chatWindow->chatLog("Failed to use item", BY_SERVER); - } else { - player_node->getInvItem(index)->setQuantity(amount); - } - break; -#endif - } } diff --git a/src/net/protocol.h b/src/net/protocol.h index 8af31dbb..a524304a 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -24,74 +24,6 @@ #ifndef _TMW_PROTOCOL_ #define _TMW_PROTOCOL_ -// Packets from server to client -#define SMSG_LOGIN_SUCCESS 0x0073 /**< Contains starting location */ -#define SMSG_PLAYER_UPDATE_1 0x01d8 -#define SMSG_PLAYER_UPDATE_2 0x01d9 -#define SMSG_PLAYER_MOVE 0x01da /**< A nearby player moves */ -#define SMSG_PLAYER_STAT_UPDATE_1 0x00b0 -#define SMSG_PLAYER_STAT_UPDATE_2 0x00b1 -#define SMSG_PLAYER_STAT_UPDATE_3 0x0141 -#define SMSG_PLAYER_STAT_UPDATE_4 0x00bc -#define SMSG_PLAYER_STAT_UPDATE_5 0x00bd -#define SMSG_PLAYER_STAT_UPDATE_6 0x00be -#define SMSG_WHO_ANSWER 0x00c2 -#define SMSG_PLAYER_WARP 0x0091 /**< Warp player to map/location */ -#define SMSG_PLAYER_INVENTORY 0x01ee -#define SMSG_PLAYER_INVENTORY_ADD 0x00a0 -#define SMSG_PLAYER_INVENTORY_REMOVE 0x00af -#define SMSG_PLAYER_INVENTORY_USE 0x01c8 -#define SMSG_PLAYER_EQUIPMENT 0x00a4 -#define SMSG_PLAYER_EQUIP 0x00aa -#define SMSG_PLAYER_UNEQUIP 0x00ac -#define SMSG_PLAYER_ATTACK_RANGE 0x013a -#define SMSG_PLAYER_ARROW_EQUIP 0x013c -#define SMSG_PLAYER_ARROW_MESSAGE 0x013b -#define SMSG_PLAYER_SKILLS 0x010f -#define SMSG_SKILL_FAILED 0x0110 -#define SMSG_ITEM_USE_RESPONSE 0x00a8 -#define SMSG_ITEM_VISIBLE 0x009d /**< An item is on the floor */ -#define SMSG_ITEM_DROPPED 0x009e /**< An item is dropped */ -#define SMSG_ITEM_REMOVE 0x00a1 /**< An item disappers */ -#define SMSG_BEING_VISIBLE 0x0078 -#define SMSG_BEING_MOVE 0x007b /**< A nearby monster moves */ -#define SMSG_BEING_REMOVE 0x0080 -#define SMSG_BEING_CHANGE_LOOKS 0x00c3 -#define SMSG_BEING_LEVELUP 0x019b -#define SMSG_BEING_EMOTION 0x00c0 -#define SMSG_BEING_ACTION 0x008a /**< Attack, sit, stand up, ... */ -#define SMSG_BEING_CHAT 0x008d /**< A being talks */ -#define SMSG_BEING_NAME_RESPONSE 0x0095 /**< Has to be requested */ -#define SMSG_NPC_MESSAGE 0x00b4 -#define SMSG_NPC_NEXT 0x00b5 -#define SMSG_NPC_CLOSE 0x00b6 -#define SMSG_NPC_CHOICE 0x00b7 /**< Display a choice */ -#define SMSG_NPC_BUY_SELL_CHOICE 0x00c4 -#define SMSG_NPC_BUY 0x00c6 -#define SMSG_NPC_SELL 0x00c7 -#define SMSG_NPC_BUY_RESPONSE 0x00ca -#define SMSG_NPC_SELL_RESPONSE 0x00cb -#define SMSG_PLAYER_CHAT 0x008e /**< Player talks */ -#define SMSG_GM_CHAT 0x009a /**< GM announce */ -#define SMSG_WALK_RESPONSE 0x0087 - -// Packets from client to server -#define CMSG_ITEM_PICKUP 0x009f -#define CMSG_MAP_LOADED 0x007d -#define CMSG_NPC_BUY_REQUEST 0x00c8 -#define CMSG_NPC_BUY_SELL_REQUEST 0x00c5 -#define CMSG_CHAT_MESSAGE 0x008c -#define CMSG_NPC_LIST_CHOICE 0x00b8 -#define CMSG_NPC_NEXT_REQUEST 0x00b9 -#define CMSG_NPC_SELL_REQUEST 0x00c9 -#define CMSG_SKILL_LEVELUP_REQUEST 0x0112 -#define CMSG_STAT_UPDATE_REQUEST 0x00bb -#define CMSG_NPC_TALK 0x0090 -#define CMSG_PLAYER_INVENTORY_USE 0x00a7 -#define CMSG_PLAYER_INVENTORY_DROP 0x00a2 -#define CMSG_PLAYER_EQUIP 0x00a9 -#define CMSG_PLAYER_UNEQUIP 0x00ab - /** * Enumerated type for communicated messages * - PAMSG_*: from client to account server @@ -146,6 +78,7 @@ enum { PGMSG_PICKUP = 0x0110, // W*2 position PGMSG_DROP = 0x0111, // B slot, B amount PGMSG_EQUIP = 0x0112, // B slot + PGMSG_UNEQUIP = 0x0113, // B slot GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }* GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }* GPMSG_PLAYER_ATTRIBUTE_UPDATE = 0x0130, // { W attribute, W value }* diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp index 17dea606..50150ca8 100644 --- a/src/net/skillhandler.cpp +++ b/src/net/skillhandler.cpp @@ -34,8 +34,6 @@ SkillHandler::SkillHandler() { static const Uint16 _messages[] = { - SMSG_PLAYER_SKILLS, - SMSG_SKILL_FAILED, 0 }; handledMessages = _messages; @@ -43,10 +41,9 @@ SkillHandler::SkillHandler() void SkillHandler::handleMessage(MessageIn &msg) { - int skillCount; - switch (msg.getId()) { +#if 0 case SMSG_PLAYER_SKILLS: msg.readShort(); // length skillCount = (msg.getLength() - 4) / 37; @@ -91,5 +88,6 @@ void SkillHandler::handleMessage(MessageIn &msg) } chatWindow->chatLog(action); break; +#endif } } diff --git a/src/net/tradehandler.cpp b/src/net/tradehandler.cpp index 3bf312fc..edf1dff7 100644 --- a/src/net/tradehandler.cpp +++ b/src/net/tradehandler.cpp @@ -220,7 +220,7 @@ void TradeHandler::handleMessage(MessageIn &msg) { int type = msg.readShort(); int amount = msg.readByte(); - tradeWindow->addItem(type, false, amount, false); + tradeWindow->addItem(type, false, amount); } break; case GPMSG_TRADE_START: -- 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/skillhandler.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 5ff0cd265460ef3fcc30f663094dc2c99b9926e9 Mon Sep 17 00:00:00 2001 From: Philipp Sehmisch Date: Mon, 28 Jan 2008 07:57:49 +0000 Subject: Added weapon skill system and leveling system. --- ChangeLog | 19 ++++++ src/CMakeLists.txt | 2 - src/Makefile.am | 2 - src/game.cpp | 3 - src/game.h | 1 - src/gui/skill.cpp | 125 ++++++++++++------------------------- src/gui/skill.h | 21 ++----- src/gui/status.cpp | 139 ++++++++++++++++++++++++++---------------- src/gui/status.h | 7 ++- src/localplayer.cpp | 66 +++++++++++++++----- src/localplayer.h | 88 +++++++++++++++++--------- src/net/charserverhandler.cpp | 4 +- src/net/gameserver/player.cpp | 14 +++++ src/net/gameserver/player.h | 2 + src/net/playerhandler.cpp | 128 ++++++++++++++++++++++++++++++++++++++ src/net/protocol.h | 16 ++++- src/net/skillhandler.cpp | 93 ---------------------------- src/net/skillhandler.h | 37 ----------- src/particle.cpp | 6 +- src/particle.h | 4 +- src/resources/itemdb.cpp | 6 +- src/resources/iteminfo.cpp | 2 +- src/resources/iteminfo.h | 23 +++---- 23 files changed, 448 insertions(+), 360 deletions(-) delete mode 100644 src/net/skillhandler.cpp delete mode 100644 src/net/skillhandler.h (limited to 'src/net/skillhandler.cpp') diff --git a/ChangeLog b/ChangeLog index 9286fb40..83b8ffac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2007-01-28 Philipp Sehmisch + + * src/game.cpp, src/game.h, src/net/skillhandler.cpp, + src/net/skillhandler.h, src/Makefile.am, src/CMakeLists.txt: + Removed skill handler (relict from eAthena) + * src/gui/skill.cpp, src/gui/skill.h: Implemented provisorical + dialog for viewing skill experience and skill levels. + * src/gui/status.cpp, src/gui/status.h: Implemented raising and + correcting of attributes in the character status GUI. + * src/localplayer.cpp, src/localplayer.h, + src/net/charserverhandler.cpp, src/net/gameserver/player.cpp, + src/net/gameserver/player.h, src/net/playerhandler.cpp, + src/net/protocol.h: Implemented netcode for skill system and + attribute increase system. + * src/resources/itemdp.cpp, src/resources/iteminfo.cpp, + src/resources/iteminfo.h: Updated skill palette to the latest + design decisions. + * data/items.xml: Fixed a few messed up slot numbers. + 2008-01-26 Bjørn Lindeijer * src/gui/truetypefont.cpp: Image alpha should also be set to 1, in diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a6606c33..4d774f1b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -226,8 +226,6 @@ SET(SRCS net/playerhandler.cpp net/playerhandler.h net/protocol.h - net/skillhandler.cpp - net/skillhandler.h net/tradehandler.cpp net/tradehandler.h net/accountserver/account.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 31c17edb..a3a7bc1b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -178,8 +178,6 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \ net/playerhandler.cpp \ net/playerhandler.h \ net/protocol.h \ - net/skillhandler.cpp \ - net/skillhandler.h \ net/tradehandler.cpp \ net/tradehandler.h \ net/accountserver/account.cpp \ diff --git a/src/game.cpp b/src/game.cpp index 4bf42a2d..1ad99268 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -77,7 +77,6 @@ #include "net/network.h" #include "net/npchandler.h" #include "net/playerhandler.h" -#include "net/skillhandler.h" #include "net/tradehandler.h" #include "resources/imagewriter.h" @@ -236,7 +235,6 @@ Game::Game(): mItemHandler(new ItemHandler()), mNpcHandler(new NPCHandler()), mPlayerHandler(new PlayerHandler()), - mSkillHandler(new SkillHandler()), mTradeHandler(new TradeHandler()), mLogicCounterId(0), mSecondsCounterId(0) { @@ -279,7 +277,6 @@ Game::Game(): Net::registerHandler(mItemHandler.get()); Net::registerHandler(mNpcHandler.get()); Net::registerHandler(mPlayerHandler.get()); - Net::registerHandler(mSkillHandler.get()); Net::registerHandler(mTradeHandler.get()); } diff --git a/src/game.h b/src/game.h index d1b438bd..fc7e33df 100644 --- a/src/game.h +++ b/src/game.h @@ -67,7 +67,6 @@ class Game : public ConfigListener MessageHandlerPtr mItemHandler; MessageHandlerPtr mNpcHandler; MessageHandlerPtr mPlayerHandler; - MessageHandlerPtr mSkillHandler; MessageHandlerPtr mTradeHandler; SDL_TimerID mLogicCounterId; diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp index c553863f..8c47c4ad 100644 --- a/src/gui/skill.cpp +++ b/src/gui/skill.cpp @@ -24,6 +24,7 @@ #include #include +#include #include "skill.h" @@ -35,32 +36,8 @@ #include "../localplayer.h" #include "../utils/dtor.h" - -const char *skill_db[] = { - // 0-99 - "", "Basic", "Sword", "Two hand", "HP regeneration", "Bash", "Provoke", "Magnum", "Endure", "MP regeneration", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "MAX weight", "Discount", "Overcharge", "", - "Identify", "", "", "", "", "", "", "", "Double", "Miss", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - // 100-199 - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "First aid", "Play as dead", "Moving recovery", "Fatal blow", "Auto berserk", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", -}; - +#include "../utils/toString.h" +#include "../utils/gettext.h" SkillDialog::SkillDialog(): Window("Skills") @@ -68,25 +45,32 @@ SkillDialog::SkillDialog(): setCloseButton(true); setDefaultSize(windowContainer->getWidth() - 255, 25, 240, 240); - mSkillListBox = new ListBox(this); - ScrollArea *skillScrollArea = new ScrollArea(mSkillListBox); - - mSkillListBox->setActionEventId("skill"); - - skillScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - skillScrollArea->setDimension(gcn::Rectangle(5, 5, 230, 180)); + mSkillNameLabels.resize(CHAR_SKILL_NB); + mSkillLevelLabels.resize(CHAR_SKILL_NB); + mSkillExpLabels.resize(CHAR_SKILL_NB); - add(skillScrollArea); + for (int a=0; a < CHAR_SKILL_NB; a++) + { + mSkillNameLabels.at(a) = new gcn::Label(""); + mSkillNameLabels.at(a)->setPosition(1, a*10); + add(mSkillNameLabels.at(a)); + mSkillLevelLabels.at(a) = new gcn::Label(""); + mSkillLevelLabels.at(a)->setPosition(75, a*10); + add(mSkillLevelLabels.at(a)); + mSkillExpLabels.at(a) = new gcn::Label(""); + mSkillExpLabels.at(a)->setPosition(150, a*10); + add(mSkillExpLabels.at(a)); + } - mSkillListBox->addActionListener(this); + update(); setLocationRelativeTo(getParent()); - loadWindowState("Skills"); + loadWindowState(_("Skills")); } SkillDialog::~SkillDialog() { - cleanList(); + } void SkillDialog::action(const gcn::ActionEvent &event) @@ -100,60 +84,29 @@ void SkillDialog::action(const gcn::ActionEvent &event) } } -void SkillDialog::update() +void SkillDialog::draw(gcn::Graphics *g) { -} + update(); -int SkillDialog::getNumberOfElements() -{ - return mSkillList.size(); + Window::draw(g); } -std::string SkillDialog::getElementAt(int i) +void SkillDialog::update() { - if (i >= 0 && i < (int)mSkillList.size()) + for (int a = 0; a < CHAR_SKILL_NB; a++) { - char tmp[128]; - sprintf(tmp, "%s Lv: %i Sp: %i", - skill_db[mSkillList[i]->id], - mSkillList[i]->lv, - mSkillList[i]->sp); - return tmp; + int baseLevel = player_node->getAttributeBase(a + CHAR_SKILL_BEGIN); + int effLevel = player_node->getAttributeEffective(a + CHAR_SKILL_BEGIN); + std::string skillLevel("Lvl:" + toString(effLevel) + " / " + toString(baseLevel)); + + std::pair exp = player_node->getExperience(a); + std::string sExp (toString(exp.first) + " / " + toString(exp.second)); + + mSkillNameLabels.at(a)->setCaption("Skill" + toString(a)); + mSkillNameLabels.at(a)->adjustSize(); + mSkillLevelLabels.at(a)->setCaption(skillLevel); + mSkillLevelLabels.at(a)->adjustSize(); + mSkillExpLabels.at(a)->setCaption(sExp); + mSkillExpLabels.at(a)->adjustSize(); } - return ""; -} - -bool SkillDialog::hasSkill(int id) -{ - for (unsigned int i = 0; i < mSkillList.size(); i++) { - if (mSkillList[i]->id == id) { - return true; - } - } - return false; -} - -void SkillDialog::addSkill(int id, int lvl, int mp) -{ - SKILL *tmp = new SKILL(); - tmp->id = id; - tmp->lv = lvl; - tmp->sp = mp; - mSkillList.push_back(tmp); -} - -void SkillDialog::setSkill(int id, int lvl, int mp) -{ - for (unsigned int i = 0; i < mSkillList.size(); i++) { - if (mSkillList[i]->id == id) { - mSkillList[i]->lv = lvl; - mSkillList[i]->sp = mp; - } - } -} - -void SkillDialog::cleanList() -{ - for_each(mSkillList.begin(), mSkillList.end(), make_dtor(mSkillList)); - mSkillList.clear(); } diff --git a/src/gui/skill.h b/src/gui/skill.h index f1a14d50..55d94d82 100644 --- a/src/gui/skill.h +++ b/src/gui/skill.h @@ -33,18 +33,13 @@ #include "../guichanfwd.h" -struct SKILL { - short id; /**< Index into "skill_db" array */ - short lv, sp; -}; /** * The skill dialog. * * \ingroup Interface */ -class SkillDialog : public Window, public gcn::ActionListener, - public gcn::ListModel +class SkillDialog : public Window, public gcn::ActionListener { public: /** @@ -61,18 +56,14 @@ class SkillDialog : public Window, public gcn::ActionListener, void update(); - int getNumberOfElements(); - std::string getElementAt(int); + void setExp(int id, int exp); - bool hasSkill(int id); - void addSkill(int id, int lv, int sp); - void setSkill(int id, int lv, int sp); - void cleanList(); + void draw(gcn::Graphics *g); private: - gcn::ListBox *mSkillListBox; - - std::vector mSkillList; + std::vector mSkillNameLabels; + std::vector mSkillLevelLabels; + std::vector mSkillExpLabels; }; extern SkillDialog *skillDialog; diff --git a/src/gui/status.cpp b/src/gui/status.cpp index b0a92665..b9ebfecf 100644 --- a/src/gui/status.cpp +++ b/src/gui/status.cpp @@ -87,7 +87,6 @@ StatusWindow::StatusWindow(LocalPlayer *player): // Static Labels gcn::Label *mStatsTitleLabel = new gcn::Label("Stats"); gcn::Label *mStatsTotalLabel = new gcn::Label("Total"); - gcn::Label *mStatsCostLabel = new gcn::Label("Cost"); // Derived Stats /* @@ -111,37 +110,44 @@ StatusWindow::StatusWindow(LocalPlayer *player): for (int i = 0; i < 6; i++) { mStatsLabel[i] = new gcn::Label(); mStatsDisplayLabel[i] = new gcn::Label(); - mPointsLabel[i] = new gcn::Label("0"); } - mRemainingStatsPointsLabel = new gcn::Label(); + mCharacterPointsLabel = new gcn::Label(); + mCorrectionPointsLabel = new gcn::Label(); // Set button events Id - mStatsButton[0] = new Button("+", "STR", this); - mStatsButton[1] = new Button("+", "AGI", this); - mStatsButton[2] = new Button("+", "DEX", this); - mStatsButton[3] = new Button("+", "VIT", this); - mStatsButton[4] = new Button("+", "INT", this); - mStatsButton[5] = new Button("+", "WIL", this); - mStatsButton[6] = new Button("+", "CHR", this); + mStatsPlus[0] = new Button("+", "STR+", this); + mStatsPlus[1] = new Button("+", "AGI+", this); + mStatsPlus[2] = new Button("+", "DEX+", this); + mStatsPlus[3] = new Button("+", "VIT+", this); + mStatsPlus[4] = new Button("+", "INT+", this); + mStatsPlus[5] = new Button("+", "WIL+", this); + + mStatsMinus[0] = new Button("-", "STR-", this); + mStatsMinus[1] = new Button("-", "AGI-", this); + mStatsMinus[2] = new Button("-", "DEX-", this); + mStatsMinus[3] = new Button("-", "VIT-", this); + mStatsMinus[4] = new Button("-", "INT-", this); + mStatsMinus[5] = new Button("-", "WIL-", this); + // Set position mStatsTitleLabel->setPosition(mHpLabel->getX(), mHpLabel->getY() + 23 ); mStatsTotalLabel->setPosition(110, mStatsTitleLabel->getY() + 15); int totalLabelY = mStatsTotalLabel->getY(); - mStatsCostLabel->setPosition(170, totalLabelY); for (int i = 0; i < 6; i++) { mStatsLabel[i]->setPosition(5, mStatsTotalLabel->getY() + (i * 23) + 15); - mStatsDisplayLabel[i]->setPosition(85, + mStatsMinus[i]->setPosition(85, totalLabelY + (i * 23) + 15); + mStatsDisplayLabel[i]->setPosition(125, totalLabelY + (i * 23) + 15); - mStatsButton[i]->setPosition(145, totalLabelY + (i * 23) + 10); - mPointsLabel[i]->setPosition(165, totalLabelY + (i * 23) + 15); + mStatsPlus[i]->setPosition(185, totalLabelY + (i * 23) + 15); } - mRemainingStatsPointsLabel->setPosition(5, mPointsLabel[6]->getY() + 25); + mCharacterPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 25); + mCorrectionPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 35); /* mStatsAttackLabel->setPosition(220, mStatsLabel[0]->getY()); mStatsDefenseLabel->setPosition(220, mStatsLabel[1]->getY()); @@ -162,13 +168,12 @@ StatusWindow::StatusWindow(LocalPlayer *player): // Assemble add(mStatsTitleLabel); add(mStatsTotalLabel); - add(mStatsCostLabel); for(int i = 0; i < 6; i++) { add(mStatsLabel[i]); add(mStatsDisplayLabel[i]); - add(mStatsButton[i]); - add(mPointsLabel[i]); + add(mStatsPlus[i]); + add(mStatsMinus[i]); }/* add(mStatsAttackLabel); add(mStatsDefenseLabel); @@ -186,14 +191,19 @@ StatusWindow::StatusWindow(LocalPlayer *player): add(mStatsEvadePoints); add(mStatsReflexPoints);*/ - add(mRemainingStatsPointsLabel); + add(mCharacterPointsLabel); + add(mCorrectionPointsLabel); } void StatusWindow::update() { // Status Part // ----------- - mLvlLabel->setCaption("Level: " + toString(mPlayer->getLevel())); + mLvlLabel->setCaption( "Level: " + + toString(mPlayer->getLevel()) + + " (" + + toString(mPlayer->getLevelProgress()) + + "%)"); mLvlLabel->adjustSize(); mMoneyLabel->setCaption("Money: " + toString(mPlayer->getMoney()) + " GP"); @@ -232,8 +242,8 @@ void StatusWindow::update() "Intelligence", "Willpower" }; - int statusPoints = mPlayer->getAttributeIncreasePoints(); - + int characterPoints = mPlayer->getCharacterPoints(); + int correctionPoints = mPlayer->getCorrectionPoints(); // Update labels for (int i = 0; i < 6; i++) { @@ -246,11 +256,16 @@ void StatusWindow::update() mStatsLabel[i]->adjustSize(); mStatsDisplayLabel[i]->adjustSize(); - mStatsButton[i]->setEnabled(statusPoints); + mStatsPlus[i]->setEnabled(characterPoints); + mStatsMinus[i]->setEnabled(correctionPoints); } - mRemainingStatsPointsLabel->setCaption("Remaining Status Points: " + - toString(statusPoints)); - mRemainingStatsPointsLabel->adjustSize(); + mCharacterPointsLabel->setCaption("Character Points: " + + toString(characterPoints)); + mCharacterPointsLabel->adjustSize(); + + mCorrectionPointsLabel->setCaption("Correction Points: " + + toString(correctionPoints)); + mCorrectionPointsLabel->adjustSize(); /* // Derived Stats Points @@ -304,31 +319,53 @@ void StatusWindow::action(const gcn::ActionEvent &event) const std::string &eventId = event.getId(); // Stats Part - if (eventId.length() == 3) + if (eventId == "STR+") + { + mPlayer->raiseAttribute(LocalPlayer::STR); + } + else if (eventId == "AGI+") + { + mPlayer->raiseAttribute(LocalPlayer::AGI); + } + else if (eventId == "DEX+") + { + mPlayer->raiseAttribute(LocalPlayer::DEX); + } + else if (eventId == "VIT+") + { + mPlayer->raiseAttribute(LocalPlayer::VIT); + } + else if (eventId == "INT+") + { + mPlayer->raiseAttribute(LocalPlayer::INT); + } + else if (eventId == "WIL+") + { + mPlayer->raiseAttribute(LocalPlayer::WIL); + } + + else if (eventId == "STR-") + { + mPlayer->lowerAttribute(LocalPlayer::STR); + } + else if (eventId == "AGI-") + { + mPlayer->lowerAttribute(LocalPlayer::AGI); + } + else if (eventId == "DEX-") + { + mPlayer->lowerAttribute(LocalPlayer::DEX); + } + else if (eventId == "VIT-") + { + mPlayer->lowerAttribute(LocalPlayer::VIT); + } + else if (eventId == "INT-") + { + mPlayer->lowerAttribute(LocalPlayer::INT); + } + else if (eventId == "WIL-") { - if (eventId == "STR") - { - mPlayer->raiseAttribute(LocalPlayer::STR); - } - else if (eventId == "AGI") - { - mPlayer->raiseAttribute(LocalPlayer::AGI); - } - else if (eventId == "DEX") - { - mPlayer->raiseAttribute(LocalPlayer::DEX); - } - else if (eventId == "VIT") - { - mPlayer->raiseAttribute(LocalPlayer::VIT); - } - else if (eventId == "INT") - { - mPlayer->raiseAttribute(LocalPlayer::INT); - } - else if (eventId == "WIL") - { - mPlayer->raiseAttribute(LocalPlayer::WIL); - } + mPlayer->lowerAttribute(LocalPlayer::WIL); } } diff --git a/src/gui/status.h b/src/gui/status.h index f3475263..6e613495 100644 --- a/src/gui/status.h +++ b/src/gui/status.h @@ -91,14 +91,15 @@ class StatusWindow : public Window, public gcn::ActionListener * Stats captions. */ gcn::Label *mStatsLabel[6]; - gcn::Label *mPointsLabel[6]; gcn::Label *mStatsDisplayLabel[6]; - gcn::Label *mRemainingStatsPointsLabel; + gcn::Label *mCharacterPointsLabel; + gcn::Label *mCorrectionPointsLabel; /** * Stats buttons. */ - gcn::Button *mStatsButton[6]; + gcn::Button *mStatsPlus[6]; + gcn::Button *mStatsMinus[6]; }; extern StatusWindow *statusWindow; diff --git a/src/localplayer.cpp b/src/localplayer.cpp index d01b613e..12de3de4 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -49,17 +49,21 @@ LocalPlayer::LocalPlayer(): mAttackRange(0), mInventory(new Inventory), mEquipment(new Equipment), - mAttributeBase(NB_CHARACTER_ATTRIBUTES, 0), - mAttributeEffective(NB_CHARACTER_ATTRIBUTES, 0), - mAttributeIncreasePoints(0), - mLevel(1), mMoney(0), + mAttributeBase(NB_CHARACTER_ATTRIBUTES, -1), + mAttributeEffective(NB_CHARACTER_ATTRIBUTES, -1), + mExpCurrent(CHAR_SKILL_NB, -1), + mExpNext(CHAR_SKILL_NB, -1), + mCharacterPoints(-1), + mCorrectionPoints(-1), + mLevel(1), mLevelProgress(0), + mMoney(0), mTotalWeight(1), mMaxWeight(1), mHP(1), mMaxHP(1), - mXp(0), mTarget(NULL), mPickUpTarget(NULL), mTrading(false), mLastAction(-1), mWalkingDir(0), - mDestX(0), mDestY(0) + mDestX(0), mDestY(0), + mExpMessageTime(0) { } @@ -74,6 +78,21 @@ void LocalPlayer::logic() mLastAction = -1; } + // Show XP messages + if(!mExpMessages.empty()) + { + if (mExpMessageTime == 0) + { + particleEngine->addTextRiseFadeOutEffect(mExpMessages.front(), + 0, 128, 255, + speechFont, + mPx + 16, mPy - 16); + mExpMessages.pop_front(); + mExpMessageTime = 30; + } + mExpMessageTime--; + } + Being::logic(); } @@ -326,7 +345,6 @@ void LocalPlayer::attack() else { sound.playSfx("sfx/fist-swish.ogg"); } - Net::GameServer::Player::attack(getSpriteDirection()); } @@ -346,19 +364,35 @@ void LocalPlayer::revive() void LocalPlayer::raiseAttribute(size_t attr) { + // we assume that the server allows the change. When not we will undo it later. + mCharacterPoints--; mAttributeBase.at(attr)++; - // TODO: Inform the server about our desire to raise the attribute + Net::GameServer::Player::raiseAttribute(attr + CHAR_ATTR_BEGIN); } -void LocalPlayer::setXp(int xp) +void LocalPlayer::lowerAttribute(size_t attr) { - if (mMap && xp > mXp) - { - const std::string text = toString(xp - mXp) + " xp"; + // we assume that the server allows the change. When not we will undo it later. + mCorrectionPoints--; + mCharacterPoints++; + mAttributeBase.at(attr)--; + Net::GameServer::Player::lowerAttribute(attr + CHAR_ATTR_BEGIN); +} - // Show XP number - particleEngine->addTextRiseFadeOutEffect(text, hitYellowFont, - mPx + 16, mPy - 16); +void LocalPlayer::setExperience(int skill, int current, int next) +{ + int diff = current - mExpCurrent.at(skill); + if (mMap && mExpCurrent.at(skill) != -1 && diff > 0) + { + const std::string text = toString(diff) + " xp skill" + toString(skill); + mExpMessages.push_back(text); } - mXp = xp; + + mExpCurrent.at(skill) = current; + mExpNext.at(skill) = next; +} + +std::pair LocalPlayer::getExperience(int skill) +{ + return std::pair (mExpCurrent.at(skill), mExpNext.at(skill)); } diff --git a/src/localplayer.h b/src/localplayer.h index 9deb2475..fca6f993 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -82,30 +82,39 @@ enum CHAR_ATTR_END, CHAR_ATTR_NB = CHAR_ATTR_END - CHAR_ATTR_BEGIN, - CHAR_SKILL_WEAPON_BEGIN = CHAR_ATTR_END, + CHAR_SKILL_BEGIN = CHAR_ATTR_END, + + CHAR_SKILL_WEAPON_BEGIN = CHAR_SKILL_BEGIN, CHAR_SKILL_WEAPON_NONE = CHAR_SKILL_WEAPON_BEGIN, CHAR_SKILL_WEAPON_KNIFE, CHAR_SKILL_WEAPON_SWORD, - CHAR_SKILL_WEAPON_SPEAR, - CHAR_SKILL_WEAPON_JAVELIN, - CHAR_SKILL_WEAPON_ROD, + CHAR_SKILL_WEAPON_POLEARM, CHAR_SKILL_WEAPON_STAFF, CHAR_SKILL_WEAPON_WHIP, - CHAR_SKILL_WEAPON_PROJECTILE, - CHAR_SKILL_WEAPON_BOOMERANG, CHAR_SKILL_WEAPON_BOW, - CHAR_SKILL_WEAPON_SICKLE, - CHAR_SKILL_WEAPON_CROSSBOW, - CHAR_SKILL_WEAPON_STICK, - CHAR_SKILL_WEAPON_HAMMER, + CHAR_SKILL_WEAPON_SHOOTING, + CHAR_SKILL_WEAPON_MACE, CHAR_SKILL_WEAPON_AXE, - CHAR_SKILL_WEAPON_HAND_PROJECTILE, + CHAR_SKILL_WEAPON_THROWN, CHAR_SKILL_WEAPON_END, CHAR_SKILL_WEAPON_NB = CHAR_SKILL_WEAPON_END - CHAR_SKILL_WEAPON_BEGIN, - // Magic skills should follow. + CHAR_SKILL_MAGIC_BEGIN = CHAR_SKILL_WEAPON_END, + CHAR_SKILL_MAGIC_IAMJUSTAPLACEHOLDER = CHAR_SKILL_MAGIC_BEGIN, + // add magic skills here + CHAR_SKILL_MAGIC_END, + CHAR_SKILL_MAGIC_NB = CHAR_SKILL_MAGIC_END - CHAR_SKILL_MAGIC_BEGIN, + + CHAR_SKILL_CRAFT_BEGIN = CHAR_SKILL_MAGIC_END, + CHAR_SKILL_CRAFT_IAMJUSTAPLACEHOLDER = CHAR_SKILL_CRAFT_BEGIN, + // add crafting skills here + CHAR_SKILL_CRAFT_END, + CHAR_SKILL_CRAFT_NB = CHAR_SKILL_CRAFT_END - CHAR_SKILL_CRAFT_BEGIN, + + CHAR_SKILL_END = CHAR_SKILL_CRAFT_END, + CHAR_SKILL_NB = CHAR_SKILL_END - CHAR_SKILL_BEGIN, - NB_CHARACTER_ATTRIBUTES = CHAR_SKILL_WEAPON_END + NB_CHARACTER_ATTRIBUTES = CHAR_SKILL_END }; @@ -235,8 +244,16 @@ class LocalPlayer : public Player */ void setWalkingDir(int dir); + /** + * Uses a character point to raise an attribute + */ void raiseAttribute(size_t attr); + /** + * Uses a correction point to lower an attribute + */ + void lowerAttribute(size_t attr); + void toggleSit(); void emote(Uint8 emotion); @@ -245,17 +262,6 @@ 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 @@ -275,6 +281,12 @@ class LocalPlayer : public Player void setLevel(int value) { mLevel = value; } + void setLevelProgress(int percent) + { mLevelProgress = percent; } + + int getLevelProgress() const + { return mLevelProgress; } + int getMoney() const { return mMoney; } @@ -299,8 +311,21 @@ class LocalPlayer : public Player void setAttributeEffective(int num, int value) { mAttributeEffective[num] = value; } - int getAttributeIncreasePoints() const - { return mAttributeIncreasePoints; } + int getCharacterPoints() const + { return mCharacterPoints; } + + void setCharacterPoints(int n) + { mCharacterPoints = n; } + + int getCorrectionPoints() const + { return mCorrectionPoints; } + + void setCorrectionPoints(int n) + { mCorrectionPoints = n; } + + void setExperience(int skill, int current, int next); + + std::pair getExperience(int skill); float mLastAttackTime; /**< Used to synchronize the charge dialog */ @@ -313,14 +338,17 @@ class LocalPlayer : public Player // Character status: std::vector mAttributeBase; std::vector mAttributeEffective; - int mAttributeIncreasePoints; + std::vector mExpCurrent; + std::vector mExpNext; + int mCharacterPoints; + int mCorrectionPoints; int mLevel; + int mLevelProgress; int mMoney; int mTotalWeight; int mMaxWeight; int mHP; int mMaxHP; - int mXp; /**< Experience points. */ Being *mTarget; FloorItem *mPickUpTarget; @@ -330,6 +358,10 @@ class LocalPlayer : public Player int mWalkingDir; /**< The direction the player is walking in. */ int mDestX; /**< X coordinate of destination. */ int mDestY; /**< Y coordinate of destination. */ + + std::list mExpMessages; /**< Queued exp messages*/ + int mExpMessageTime; + }; extern LocalPlayer *player_node; diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp index bbfa82a4..c83b68f1 100644 --- a/src/net/charserverhandler.cpp +++ b/src/net/charserverhandler.cpp @@ -215,7 +215,9 @@ LocalPlayer* CharServerHandler::readPlayerData(MessageIn &msg, int &slot) tempPlayer->setGender(msg.readInt8()); int hs = msg.readInt8(), hc = msg.readInt8(); tempPlayer->setHairStyle(hs, hc); - tempPlayer->setLevel(msg.readInt8()); + tempPlayer->setLevel(msg.readInt16()); + tempPlayer->setCharacterPoints(msg.readInt16()); + tempPlayer->setCorrectionPoints(msg.readInt16()); tempPlayer->setMoney(msg.readInt32()); for (int i = 0; i < 7; i++) diff --git a/src/net/gameserver/player.cpp b/src/net/gameserver/player.cpp index bb3567d3..67edc7ad 100644 --- a/src/net/gameserver/player.cpp +++ b/src/net/gameserver/player.cpp @@ -154,3 +154,17 @@ void Net::GameServer::Player::tradeWithNPC(int item, int amount) msg.writeInt16(amount); Net::GameServer::connection->send(msg); } + +void Net::GameServer::Player::raiseAttribute(int attribute) +{ + MessageOut msg(PGMSG_RAISE_ATTRIBUTE); + msg.writeInt8(attribute); + Net::GameServer::connection->send(msg); +} + +void Net::GameServer::Player::lowerAttribute(int attribute) +{ + MessageOut msg(PGMSG_LOWER_ATTRIBUTE); + msg.writeInt8(attribute); + Net::GameServer::connection->send(msg); +} diff --git a/src/net/gameserver/player.h b/src/net/gameserver/player.h index b5f3e6d7..7ebb2830 100644 --- a/src/net/gameserver/player.h +++ b/src/net/gameserver/player.h @@ -51,6 +51,8 @@ namespace Net void tradeItem(int slot, int amount); void tradeMoney(int amount); void tradeWithNPC(int item, int amount); + void raiseAttribute(int attribute); + void lowerAttribute(int attribute); } } } diff --git a/src/net/playerhandler.cpp b/src/net/playerhandler.cpp index f6f7a8fa..951d6d4e 100644 --- a/src/net/playerhandler.cpp +++ b/src/net/playerhandler.cpp @@ -29,6 +29,7 @@ #include "../engine.h" #include "../localplayer.h" #include "../log.h" +#include "../particle.h" #include "../npc.h" #include "../gui/buy.h" @@ -90,6 +91,11 @@ PlayerHandler::PlayerHandler() GPMSG_PLAYER_MAP_CHANGE, GPMSG_PLAYER_SERVER_CHANGE, GPMSG_PLAYER_ATTRIBUTE_CHANGE, + GPMSG_PLAYER_EXP_CHANGE, + GPMSG_LEVELUP, + GPMSG_LEVEL_PROGRESS, + GPMSG_RAISE_ATTRIBUTE_RESPONSE, + GPMSG_LOWER_ATTRIBUTE_RESPONSE, 0 }; handledMessages = _messages; @@ -128,6 +134,14 @@ void PlayerHandler::handleMessage(MessageIn &msg) } else if (stat < NB_CHARACTER_ATTRIBUTES) { + if (stat >= CHAR_SKILL_BEGIN && stat < CHAR_SKILL_END + && player_node->getAttributeBase(stat) < base + && player_node->getAttributeBase(stat) > -1) + { + Particle* effect = particleEngine->addEffect("graphics/particles/skillup.particle.xml", 0, 0); + player_node->controlParticle(effect); + } + player_node->setAttributeBase(stat, base); player_node->setAttributeEffective(stat, value); } @@ -138,6 +152,120 @@ void PlayerHandler::handleMessage(MessageIn &msg) } } } break; + + case GPMSG_PLAYER_EXP_CHANGE: + { + logger->log("EXP Update"); + while (msg.getUnreadLength()) + { + int skill = msg.readInt8(); + int current = msg.readInt32(); + int next = msg.readInt32(); + + if (skill < CHAR_SKILL_NB) + { + player_node->setExperience(skill, current, next); + } + else + { + logger->log("Warning: server wants to update experience of unknown " + "skill %d to %d / %d", skill, current, next); + } + } + } break; + + case GPMSG_LEVELUP: + { + player_node->setLevel(msg.readInt16()); + player_node->setCharacterPoints(msg.readInt16()); + player_node->setCorrectionPoints(msg.readInt16()); + Particle* effect = particleEngine->addEffect("graphics/particles/levelup.particle.xml", 0, 0); + player_node->controlParticle(effect); + } break; + + + case GPMSG_LEVEL_PROGRESS: + { + logger->log("Level Progress Update"); + player_node->setLevelProgress(msg.readInt8()); + } break; + + + case GPMSG_RAISE_ATTRIBUTE_RESPONSE: + { + int errCode = msg.readInt8(); + int attrNum = msg.readInt8() - CHAR_ATTR_BEGIN; + switch (errCode) + { + case ATTRIBMOD_OK: + { + // feel(acknowledgment); + } break; + case ATTRIBMOD_INVALID_ATTRIBUTE: + { + logger->log("Warning: Server denied increase of attribute %d (unknown attribute) ", attrNum); + } break; + case ATTRIBMOD_NO_POINTS_LEFT: + { + // when the server says "you got no points" it + // has to be correct. The server is always right! + // undo attribute change and set points to 0 + logger->log("Warning: Server denied increase of attribute %d (no points left) ", attrNum); + int attrValue = player_node->getAttributeBase(attrNum) - 1; + player_node->setCharacterPoints(0); + player_node->setAttributeBase(attrNum, attrValue); + } break; + case ATTRIBMOD_DENIED: + { + // undo attribute change + logger->log("Warning: Server denied increase of attribute %d (reason unknown) ", attrNum); + int points = player_node->getCharacterPoints() - 1; + player_node->setCharacterPoints(points); + int attrValue = player_node->getAttributeBase(attrNum) - 1; + player_node->setAttributeBase(attrNum, attrValue); + } break; + } + } break; + + case GPMSG_LOWER_ATTRIBUTE_RESPONSE: + { + int errCode = msg.readInt8(); + int attrNum = msg.readInt8() - CHAR_ATTR_BEGIN; + switch (errCode) + { + case ATTRIBMOD_OK: + { + // feel(acknowledgment); + } break; + case ATTRIBMOD_INVALID_ATTRIBUTE: + { + logger->log("Warning: Server denied reduction of attribute %d (unknown attribute) ", attrNum); + } break; + case ATTRIBMOD_NO_POINTS_LEFT: + { + // when the server says "you got no points" it + // has to be correct. The server is always right! + // undo attribute change and set points to 0 + logger->log("Warning: Server denied reduction of attribute %d (no points left) ", attrNum); + int attrValue = player_node->getAttributeBase(attrNum) + 1; + player_node->setCorrectionPoints(0); + player_node->setAttributeBase(attrNum, attrValue); + break; + } break; + case ATTRIBMOD_DENIED: + { + // undo attribute change + logger->log("Warning: Server denied reduction of attribute %d (reason unknown) ", attrNum); + int charaPoints = player_node->getCharacterPoints() - 1; + player_node->setCharacterPoints(charaPoints); + int correctPoints = player_node->getCharacterPoints() + 1; + player_node->setCorrectionPoints(correctPoints); + int attrValue = player_node->getAttributeBase(attrNum) + 1; + player_node->setAttributeBase(attrNum, attrValue); + } break; + } + + } break; /* case SMSG_PLAYER_ARROW_MESSAGE: { diff --git a/src/net/protocol.h b/src/net/protocol.h index d8b9fcb2..e6f5869b 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -49,7 +49,7 @@ enum { APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error PAMSG_CHAR_DELETE = 0x0022, // B index APMSG_CHAR_DELETE_RESPONSE = 0x0023, // B error - APMSG_CHAR_INFO = 0x0024, // B index, S name, B gender, B hair style, B hair color, B level, W money, W*6 stats + APMSG_CHAR_INFO = 0x0024, // B index, S name, B gender, B hair style, B hair color, W level, W character points, W correction points, D money, W*6 stats PAMSG_CHAR_SELECT = 0x0026, // B index APMSG_CHAR_SELECT_RESPONSE = 0x0027, // B error, B*32 token, S game address, W game port, S chat address, W chat port PAMSG_EMAIL_CHANGE = 0x0030, // S email @@ -83,6 +83,13 @@ enum { GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }* GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }* GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { B attribute, W base value, W modified value }* + GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { B skill, D exp got, D exp needed }* + GPMSG_LEVELUP = 0x0150, // W new level + GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup + PGMSG_RAISE_ATTRIBUTE = 0x0160, // B attribute + GPMSG_RAISE_ATTRIBUTE_RESPONSE = 0x0161, // B error, B attribute + PGMSG_LOWER_ATTRIBUTE = 0x0170, // B attribute + GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, B attribute GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position // player: S name, B hair style, B hair color, B gender, B item bitmask, { W item id }* // monster: W type id @@ -183,6 +190,13 @@ enum { CREATE_TOO_MUCH_CHARACTERS }; +// Character attribute modification specific return value +enum AttribmodResponseCode { + ATTRIBMOD_OK = ERRMSG_OK, + ATTRIBMOD_INVALID_ATTRIBUTE = 0x40, + ATTRIBMOD_NO_POINTS_LEFT, + ATTRIBMOD_DENIED +}; // Object type enumeration enum { // A simple item diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp deleted file mode 100644 index 8a19fe45..00000000 --- a/src/net/skillhandler.cpp +++ /dev/null @@ -1,93 +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 "skillhandler.h" - -#include "messagein.h" -#include "protocol.h" - -#include "../log.h" - -#include "../gui/chat.h" -#include "../gui/skill.h" - -SkillHandler::SkillHandler() -{ - static const Uint16 _messages[] = { - 0 - }; - handledMessages = _messages; -} - -void SkillHandler::handleMessage(MessageIn &msg) -{ - switch (msg.getId()) - { -#if 0 - case SMSG_PLAYER_SKILLS: - msg.readInt16(); // length - skillCount = (msg.getLength() - 4) / 37; - skillDialog->cleanList(); - - for (int k = 0; k < skillCount; k++) - { - 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.readInt8(); - - if (level != 0 || up != 0) - { - if (skillDialog->hasSkill(skillId)) { - skillDialog->setSkill(skillId, level, sp); - } - else { - skillDialog->addSkill(skillId, level, sp); - } - } - } - break; - - case SMSG_SKILL_FAILED: - // Action failed (ex. sit because you have not reached the - // right level) - CHATSKILL action; - 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) - { - logger->log("Action: %d/%d", action.bskill, action.success); - } - chatWindow->chatLog(action); - break; -#endif - } -} diff --git a/src/net/skillhandler.h b/src/net/skillhandler.h deleted file mode 100644 index 8c0653d4..00000000 --- a/src/net/skillhandler.h +++ /dev/null @@ -1,37 +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_NET_SKILLHANDLER_H -#define _TMW_NET_SKILLHANDLER_H - -#include "messagehandler.h" - -class SkillHandler : public MessageHandler -{ - public: - SkillHandler(); - - void handleMessage(MessageIn &msg); -}; - -#endif diff --git a/src/particle.cpp b/src/particle.cpp index 93fc7893..dac8c62e 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -329,10 +329,12 @@ Particle::addTextSplashEffect(const std::string &text, } Particle* -Particle::addTextRiseFadeOutEffect(const std::string &text, gcn::Font *font, +Particle::addTextRiseFadeOutEffect(const std::string &text, + int colorR, int colorG, int colorB, + gcn::Font *font, int x, int y) { - Particle *newParticle = new TextParticle(mMap, text, 255, 255, 255, font); + Particle *newParticle = new TextParticle(mMap, text, colorR, colorG, colorB, font); newParticle->setPosition(x, y, 0); newParticle->setVelocity(0.0f, 0.0f, 0.5f); newParticle->setGravity(0.0015f); diff --git a/src/particle.h b/src/particle.h index 045ab9b9..0dd34065 100644 --- a/src/particle.h +++ b/src/particle.h @@ -123,7 +123,9 @@ class Particle : public Sprite * Creates a standalone text particle. */ Particle* - addTextRiseFadeOutEffect(const std::string &text, gcn::Font *font, + addTextRiseFadeOutEffect(const std::string &text, + int colorR, int colorG, int colorB, + gcn::Font *font, int x, int y); /** diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index c03e42a2..5f6846ba 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -79,16 +79,14 @@ WeaponType weaponTypeFromString (std::string name, int id = 0) if (name=="knife") return WPNTYPE_KNIFE; else if (name=="sword") return WPNTYPE_SWORD; else if (name=="polearm") return WPNTYPE_POLEARM; - else if (name=="javelin") return WPNTYPE_JAVELIN; else if (name=="staff") return WPNTYPE_STAFF; else if (name=="whip") return WPNTYPE_WHIP; - else if (name=="boomerang") return WPNTYPE_BOOMERANG; else if (name=="bow") return WPNTYPE_BOW; - else if (name=="sickle") return WPNTYPE_SICKLE; - else if (name=="crossbow") return WPNTYPE_CROSSBOW; + else if (name=="shooting") return WPNTYPE_SHOOTING; else if (name=="mace") return WPNTYPE_MACE; else if (name=="axe") return WPNTYPE_AXE; else if (name=="thrown") return WPNTYPE_THROWN; + else return WPNTYPE_NONE; } diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp index ade7f685..ad4c9797 100644 --- a/src/resources/iteminfo.cpp +++ b/src/resources/iteminfo.cpp @@ -60,7 +60,7 @@ void ItemInfo::setWeaponType(int type) case WPNTYPE_BOW: mAttackType = ACTION_ATTACK_BOW; break; - case WPNTYPE_SICKLE: + case WPNTYPE_POLEARM: mAttackType = ACTION_ATTACK_SWING; break; default: diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index c637b010..90675a17 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -62,19 +62,16 @@ enum ItemType enum WeaponType { WPNTYPE_NONE = 0, - WPNTYPE_KNIFE,// 1 - WPNTYPE_SWORD,// 2 - WPNTYPE_POLEARM,// 3 - WPNTYPE_JAVELIN,// 4 - WPNTYPE_STAFF,// 5 - WPNTYPE_WHIP,// 6 - WPNTYPE_BOOMERANG,// 7 - WPNTYPE_BOW,// 8 - WPNTYPE_SICKLE,// 9 - WPNTYPE_CROSSBOW,// 10 - WPNTYPE_MACE,// 11 - WPNTYPE_AXE,// 12 - WPNTYPE_THROWN// 13 + WPNTYPE_KNIFE, + WPNTYPE_SWORD, + WPNTYPE_POLEARM, + WPNTYPE_STAFF, + WPNTYPE_WHIP, + WPNTYPE_BOW, + WPNTYPE_SHOOTING, + WPNTYPE_MACE, + WPNTYPE_AXE, + WPNTYPE_THROWN }; /** -- cgit v1.2.3-70-g09d2