diff options
author | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-08-08 14:44:50 +0000 |
---|---|---|
committer | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-08-08 14:44:50 +0000 |
commit | 96ed6284affefcba1b0ded75e4ef88e52b430c4d (patch) | |
tree | 6495166390f2279d8fb68b900191795ead09fda4 | |
parent | e481ad5466eb2b87036515a2a15166e41828c31f (diff) | |
download | manaserv-96ed6284affefcba1b0ded75e4ef88e52b430c4d.tar.gz manaserv-96ed6284affefcba1b0ded75e4ef88e52b430c4d.tar.bz2 manaserv-96ed6284affefcba1b0ded75e4ef88e52b430c4d.tar.xz manaserv-96ed6284affefcba1b0ded75e4ef88e52b430c4d.zip |
Changed some argument types. Added untested protocol for moving objects between slots of inventory. Fixed position of the cleaning bit for looks, so that it actually fits into network data.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | src/defines.h | 1 | ||||
-rw-r--r-- | src/game-server/gamehandler.cpp | 8 | ||||
-rw-r--r-- | src/game-server/inventory.cpp | 147 | ||||
-rw-r--r-- | src/game-server/inventory.hpp | 6 | ||||
-rw-r--r-- | src/game-server/state.cpp | 2 | ||||
-rw-r--r-- | src/net/messageout.cpp | 11 | ||||
-rw-r--r-- | src/net/messageout.hpp | 11 |
8 files changed, 180 insertions, 16 deletions
@@ -1,3 +1,13 @@ +2007-08-08 Guillaume Melquiond <guillaume.melquiond@gmail.com> + + * src/net/messageout.hpp, src/net/messageout.cpp: Changed argument + types to generic int. + * src/game-server/inventory.cpp, src/game-server/inventory.hpp, + src/defines.h, src/game-server/gamehandler.cpp: Added protocol for + moving objects between slots of inventory. + * src/game-server/state.cpp: Fixed position of the cleaning bit for + looks, so that it actually fits into network data. + 2007-08-01 Guillaume Melquiond <guillaume.melquiond@gmail.com> * src/game-server/itemmanager.cpp: Ensured equipment items cannot diff --git a/src/defines.h b/src/defines.h index 2fe6efba..3e172489 100644 --- a/src/defines.h +++ b/src/defines.h @@ -146,6 +146,7 @@ enum { PGMSG_DROP = 0x0111, // B slot, B amount PGMSG_EQUIP = 0x0112, // B slot PGMSG_UNEQUIP = 0x0113, // B slot + PGMSG_MOVE_ITEM = 0x0114, // B slot1, B slot2, B amount 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/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index e01c4a9d..17ce6dee 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -259,6 +259,14 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) } } break; + case PGMSG_MOVE_ITEM: + { + int slot1 = message.readByte(); + int slot2 = message.readByte(); + int amount = message.readByte(); + Inventory(computer.character).move(slot1, slot2, amount); + } break; + case PGMSG_ATTACK: { LOG_DEBUG("Character " << computer.character->getPublicID() diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index 50e229cc..49442a5c 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -162,12 +162,13 @@ int Inventory::getItem(int slot) const int Inventory::getIndex(int slot) const { int index = 0; + for (std::vector< InventoryItem >::const_iterator i = mPoss->inventory.begin(), i_end = mPoss->inventory.end(); i != i_end; ++i, ++index) { if (slot == 0) { - return index; + return i->itemId ? index : -1; } slot -= i->itemId ? 1 : i->amount; @@ -379,6 +380,150 @@ int Inventory::remove(int itemId, int amount) return amount; } +int Inventory::move(int slot1, int slot2, int amount) +{ + if (amount == 0 || slot2 >= INVENTORY_SLOTS) + { + return amount; + } + + int i1 = getIndex(slot1); + if (i1 < 0) + { + return amount; + } + + prepare(); + + InventoryItem &it1 = mPoss->inventory[i1]; + int i2 = getIndex(slot2); + + if (i2 >= 0) + { + InventoryItem &it2 = mPoss->inventory[i2]; + if (it1.itemId == it2.itemId) + { + // Move between two stacks of the same kind. + int nb = std::min(std::min(amount, (int)it1.amount), 255 - it2.amount); + if (nb == 0) + { + return amount; + } + + it1.amount -= nb; + it2.amount += nb; + amount -= nb; + + msg.writeByte(slot1 + EQUIP_CLIENT_INVENTORY); + if (it1.amount == 0) + { + msg.writeShort(0); + freeIndex(i1); + } + else + { + msg.writeShort(it1.itemId); + msg.writeByte(it1.amount); + } + + msg.writeByte(slot2 + EQUIP_CLIENT_INVENTORY); + msg.writeShort(it2.itemId); + msg.writeByte(it2.amount); + return amount; + } + + // Swap between two different stacks. + + if (it1.amount != amount) + { + return amount; + } + + std::swap(it1, it2); + + msg.writeByte(slot1 + EQUIP_CLIENT_INVENTORY); + msg.writeShort(it1.itemId); + msg.writeByte(it1.amount); + msg.writeByte(slot2 + EQUIP_CLIENT_INVENTORY); + msg.writeShort(it2.itemId); + msg.writeByte(it2.amount); + return 0; + } + + // Move some items to an empty slot. + int id = it1.itemId; + int nb = std::min((int)it1.amount, amount); + it1.amount -= nb; + amount -= nb; + + msg.writeByte(slot1 + EQUIP_CLIENT_INVENTORY); + if (it1.amount == 0) + { + msg.writeShort(0); + freeIndex(i1); + } + else + { + msg.writeShort(id); + msg.writeByte(it1.amount); + } + + // Fill second slot. + for (std::vector< InventoryItem >::iterator i = mPoss->inventory.begin(), + i_end = mPoss->inventory.end(); i != i_end; ++i) + { + if (i->itemId) + { + --slot2; + continue; + } + + if (slot2 >= i->amount) + { + slot2 -= i->amount; + continue; + } + + assert(slot2 >= 0 && i + 1 != i_end); + + if (i->amount == 1) + { + // One single empty slot in the range. + i->itemId = id; + i->amount = nb; + break; + } + + InventoryItem it = { id, nb }; + --i->amount; + + if (slot2 == 0) + { + // First slot in an empty range. + mPoss->inventory.insert(i + 1, it); + break; + } + + if (slot2 == i->amount) + { + // Last slot in an empty range. + mPoss->inventory.insert(i, it); + break; + } + + InventoryItem it3 = { 0, slot2 }; + i->amount -= slot2; + i = mPoss->inventory.insert(i, it); + mPoss->inventory.insert(i, it3); + break; + } + + msg.writeByte(slot2 + EQUIP_CLIENT_INVENTORY); + msg.writeShort(id); + msg.writeByte(nb); + return amount; +} + int Inventory::removeFromSlot(int slot, int amount) { if (amount == 0) diff --git a/src/game-server/inventory.hpp b/src/game-server/inventory.hpp index c9a2643d..1f2611eb 100644 --- a/src/game-server/inventory.hpp +++ b/src/game-server/inventory.hpp @@ -123,6 +123,12 @@ class Inventory int remove(int itemId, int amount); /** + * Moves some items from the first slot to the second one. + * @returns number of items not moved. + */ + int move(int slot1, int slot2, int amount); + + /** * Removes some items from inventory. * @return number of items not removed. */ diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 19c3ea60..513f7e6e 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -138,7 +138,7 @@ static void serializeLooks(Character *ch, MessageOut &msg, bool full) /* Bitmask enumerating the sent slots. Setting the upper bit tells the client to clear the slots beforehand. */ - int mask = full ? mask_full | (1 << 8) : mask_diff; + int mask = full ? mask_full | (1 << 7) : mask_diff; msg.writeByte(mask); for (int i = 0; i < nb_slots; ++i) diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp index 57b2db78..7753d9d3 100644 --- a/src/net/messageout.cpp +++ b/src/net/messageout.cpp @@ -43,7 +43,7 @@ MessageOut::MessageOut(): mDataSize = INITIAL_DATA_CAPACITY; } -MessageOut::MessageOut(short id): +MessageOut::MessageOut(int id): mPos(0) { mData = (char*) malloc(INITIAL_DATA_CAPACITY); @@ -79,16 +79,14 @@ MessageOut::expand(size_t bytes) } } -void -MessageOut::writeByte(char value) +void MessageOut::writeByte(int value) { expand(mPos + 1); mData[mPos] = value; mPos += 1; } -void -MessageOut::writeShort(short value) +void MessageOut::writeShort(int value) { expand(mPos + 2); uint16_t t = ENET_HOST_TO_NET_16(value); @@ -96,8 +94,7 @@ MessageOut::writeShort(short value) mPos += 2; } -void -MessageOut::writeLong(long value) +void MessageOut::writeLong(int value) { expand(mPos + 4); uint32_t t = ENET_HOST_TO_NET_32(value); diff --git a/src/net/messageout.hpp b/src/net/messageout.hpp index 3515476f..2d0490f6 100644 --- a/src/net/messageout.hpp +++ b/src/net/messageout.hpp @@ -40,7 +40,7 @@ class MessageOut /** * Constructor that takes a message ID. */ - MessageOut(short id); + MessageOut(int id); /** * Destructor. @@ -52,14 +52,11 @@ class MessageOut */ void clear(); - void - writeByte(char value); /**< Writes a byte. */ + void writeByte(int value); /**< Writes an integer on one byte. */ - void - writeShort(short value); /**< Writes a short. */ + void writeShort(int value); /**< Writes an integer on two bytes. */ - void - writeLong(long value); /**< Writes a long. */ + void writeLong(int value); /**< Writes an integer on four bytes. */ /** * Writes a 3-byte block containing tile-based coordinates. |