summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-08 14:44:50 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-08 14:44:50 +0000
commit96ed6284affefcba1b0ded75e4ef88e52b430c4d (patch)
tree6495166390f2279d8fb68b900191795ead09fda4
parente481ad5466eb2b87036515a2a15166e41828c31f (diff)
downloadmanaserv-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--ChangeLog10
-rw-r--r--src/defines.h1
-rw-r--r--src/game-server/gamehandler.cpp8
-rw-r--r--src/game-server/inventory.cpp147
-rw-r--r--src/game-server/inventory.hpp6
-rw-r--r--src/game-server/state.cpp2
-rw-r--r--src/net/messageout.cpp11
-rw-r--r--src/net/messageout.hpp11
8 files changed, 180 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 6150b991..b8559f00 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.