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 /src | |
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.
Diffstat (limited to 'src')
-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 |
7 files changed, 170 insertions, 16 deletions
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. |