diff options
author | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-07-29 17:15:40 +0000 |
---|---|---|
committer | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-07-29 17:15:40 +0000 |
commit | 18c0302e49c761b2a3b531a0ac2683e5f1135c5e (patch) | |
tree | 5ed10d14ce764e8252d3e23f95aa62b6aad76ac4 /src/game-server/inventory.cpp | |
parent | fd2cecb5c45cd6f69b193c97b7c78121f6b5b30f (diff) | |
download | manaserv-18c0302e49c761b2a3b531a0ac2683e5f1135c5e.tar.gz manaserv-18c0302e49c761b2a3b531a0ac2683e5f1135c5e.tar.bz2 manaserv-18c0302e49c761b2a3b531a0ac2683e5f1135c5e.tar.xz manaserv-18c0302e49c761b2a3b531a0ac2683e5f1135c5e.zip |
Added support for trading.
Diffstat (limited to 'src/game-server/inventory.cpp')
-rw-r--r-- | src/game-server/inventory.cpp | 142 |
1 files changed, 98 insertions, 44 deletions
diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index 7cefd72b..2d3a66c6 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -31,15 +31,62 @@ #include "game-server/itemmanager.hpp" #include "net/messageout.hpp" -Inventory::Inventory(Character *p) - : poss(p->getPossessions()), msg(GPMSG_INVENTORY), client(p) -{} +Inventory::Inventory(Character *p, bool d): + mPoss(&p->getPossessions()), msg(GPMSG_INVENTORY), mClient(p), mDelayed(d) +{ +} Inventory::~Inventory() { if (msg.getLength() > 2) { - gameHandler->sendTo(client, msg); + if (mDelayed) + { + Possessions &poss = mClient->getPossessions(); + if (mPoss != &poss) + { + poss = *mPoss; + delete mPoss; + } + } + gameHandler->sendTo(mClient, msg); + } +} + +void Inventory::cancel() +{ + msg.clear(); + msg.writeShort(GPMSG_INVENTORY); + mPoss = &mClient->getPossessions(); +} + +void Inventory::commit() +{ + if (msg.getLength() > 2) + { + if (mDelayed) + { + Possessions &poss = mClient->getPossessions(); + if (mPoss != &poss) + { + poss = *mPoss; + delete mPoss; + mPoss = &poss; + } + } + gameHandler->sendTo(mClient, msg); + msg.clear(); + msg.writeShort(GPMSG_INVENTORY); + } +} + +void Inventory::prepare() +{ + if (!mDelayed) return; + Possessions &poss = mClient->getPossessions(); + if (mPoss == &poss) + { + mPoss = new Possessions(poss); } } @@ -49,7 +96,7 @@ void Inventory::sendFull() const for (int i = 0; i < EQUIPMENT_SLOTS; ++i) { - if (int id = poss.equipment[i]) + if (int id = mPoss->equipment[i]) { m.writeByte(i); m.writeShort(id); @@ -57,8 +104,8 @@ void Inventory::sendFull() const } int slot = EQUIP_CLIENT_INVENTORY; - for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), - i_end = poss.inventory.end(); i != i_end; ++i) + for (std::vector< InventoryItem >::const_iterator i = mPoss->inventory.begin(), + i_end = mPoss->inventory.end(); i != i_end; ++i) { if (i->itemId) { @@ -73,13 +120,13 @@ void Inventory::sendFull() const } } - gameHandler->sendTo(client, m); + gameHandler->sendTo(mClient, m); } int Inventory::getItem(int slot) const { - for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), - i_end = poss.inventory.end(); i != i_end; ++i) + for (std::vector< InventoryItem >::const_iterator i = mPoss->inventory.begin(), + i_end = mPoss->inventory.end(); i != i_end; ++i) { if (slot == 0) { @@ -99,8 +146,8 @@ int Inventory::getItem(int slot) const int Inventory::getIndex(int slot) const { int index = 0; - for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), - i_end = poss.inventory.end(); i != i_end; ++i, ++index) + for (std::vector< InventoryItem >::const_iterator i = mPoss->inventory.begin(), + i_end = mPoss->inventory.end(); i != i_end; ++i, ++index) { if (slot == 0) { @@ -120,8 +167,8 @@ int Inventory::getIndex(int slot) const int Inventory::getSlot(int index) const { int slot = 0; - for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), - i_end = poss.inventory.begin() + index; i != i_end; ++i) + for (std::vector< InventoryItem >::const_iterator i = mPoss->inventory.begin(), + i_end = mPoss->inventory.begin() + index; i != i_end; ++i) { slot += i->itemId ? 1 : i->amount; } @@ -131,9 +178,9 @@ int Inventory::getSlot(int index) const int Inventory::fillFreeSlot(int itemId, int amount, int maxPerSlot) { int slot = 0; - for (int i = 0, i_end = poss.inventory.size(); i < i_end; ++i) + for (int i = 0, i_end = mPoss->inventory.size(); i < i_end; ++i) { - InventoryItem &it = poss.inventory[i]; + InventoryItem &it = mPoss->inventory[i]; if (it.itemId == 0) { int nb = std::min(amount, maxPerSlot); @@ -146,7 +193,7 @@ int Inventory::fillFreeSlot(int itemId, int amount, int maxPerSlot) { --it.amount; InventoryItem iu = { itemId, nb }; - poss.inventory.insert(poss.inventory.begin() + i, iu); + mPoss->inventory.insert(mPoss->inventory.begin() + i, iu); ++i_end; } @@ -168,7 +215,7 @@ int Inventory::fillFreeSlot(int itemId, int amount, int maxPerSlot) int nb = std::min(amount, maxPerSlot); amount -= nb; InventoryItem it = { itemId, nb }; - poss.inventory.push_back(it); + mPoss->inventory.push_back(it); msg.writeByte(slot + EQUIP_CLIENT_INVENTORY); msg.writeShort(itemId); @@ -181,11 +228,13 @@ int Inventory::fillFreeSlot(int itemId, int amount, int maxPerSlot) int Inventory::insert(int itemId, int amount) { + prepare(); + int slot = 0; int maxPerSlot = ItemManager::getItem(itemId)->getMaxPerSlot(); - for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), - i_end = poss.inventory.end(); i != i_end; ++i) + for (std::vector< InventoryItem >::iterator i = mPoss->inventory.begin(), + i_end = mPoss->inventory.end(); i != i_end; ++i) { if (i->itemId == itemId) { @@ -216,8 +265,8 @@ int Inventory::count(int itemId) const { int nb = 0; - for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), - i_end = poss.inventory.end(); i != i_end; ++i) + for (std::vector< InventoryItem >::const_iterator i = mPoss->inventory.begin(), + i_end = mPoss->inventory.end(); i != i_end; ++i) { if (i->itemId == itemId) { @@ -230,17 +279,17 @@ int Inventory::count(int itemId) const void Inventory::freeIndex(int i) { - InventoryItem &it = poss.inventory[i]; + InventoryItem &it = mPoss->inventory[i]; - if (i == (int)poss.inventory.size() - 1) + if (i == (int)mPoss->inventory.size() - 1) { - poss.inventory.pop_back(); + mPoss->inventory.pop_back(); } - else if (poss.inventory[i + 1].itemId == 0) + else if (mPoss->inventory[i + 1].itemId == 0) { it.itemId = 0; - it.amount = poss.inventory[i + 1].amount + 1; - poss.inventory.erase(poss.inventory.begin() + i + 1); + it.amount = mPoss->inventory[i + 1].amount + 1; + mPoss->inventory.erase(mPoss->inventory.begin() + i + 1); } else { @@ -248,19 +297,21 @@ void Inventory::freeIndex(int i) it.amount = 1; } - if (i > 0 && poss.inventory[i - 1].itemId == 0) + if (i > 0 && mPoss->inventory[i - 1].itemId == 0) { // Note: "it" is no longer a valid iterator. - poss.inventory[i - 1].amount += poss.inventory[i].amount; - poss.inventory.erase(poss.inventory.begin() + i); + mPoss->inventory[i - 1].amount += mPoss->inventory[i].amount; + mPoss->inventory.erase(mPoss->inventory.begin() + i); } } int Inventory::remove(int itemId, int amount) { - for (int i = poss.inventory.size() - 1; i >= 0; --i) + prepare(); + + for (int i = mPoss->inventory.size() - 1; i >= 0; --i) { - InventoryItem &it = poss.inventory[i]; + InventoryItem &it = mPoss->inventory[i]; if (it.itemId == itemId) { int nb = std::min((int)it.amount, amount); @@ -290,13 +341,14 @@ int Inventory::remove(int itemId, int amount) int Inventory::removeFromSlot(int slot, int amount) { int i = getIndex(slot); - if (i < 0) { return amount; } - InventoryItem &it = poss.inventory[i]; + prepare(); + + InventoryItem &it = mPoss->inventory[i]; int nb = std::min((int)it.amount, amount); it.amount -= nb; amount -= nb; @@ -322,6 +374,8 @@ bool Inventory::equip(int slot) return false; } + prepare(); + int availableSlots = 0, firstSlot = 0, secondSlot = 0; switch (ItemManager::getItem(itemId)->getType()) @@ -330,13 +384,13 @@ bool Inventory::equip(int slot) { // Special case 1, the two one-handed weapons are to be placed back // in the inventory, if there are any. - int id = poss.equipment[EQUIP_FIGHT1_SLOT]; + int id = mPoss->equipment[EQUIP_FIGHT1_SLOT]; if (id && !insert(id, 1)) { return false; } - id = poss.equipment[EQUIP_FIGHT2_SLOT]; + id = mPoss->equipment[EQUIP_FIGHT2_SLOT]; if (id && !insert(id, 1)) { return false; @@ -346,8 +400,8 @@ bool Inventory::equip(int slot) msg.writeShort(itemId); msg.writeByte(EQUIP_FIGHT2_SLOT); msg.writeShort(0); - poss.equipment[EQUIP_FIGHT1_SLOT] = itemId; - poss.equipment[EQUIP_FIGHT2_SLOT] = 0; + mPoss->equipment[EQUIP_FIGHT1_SLOT] = itemId; + mPoss->equipment[EQUIP_FIGHT2_SLOT] = 0; removeFromSlot(slot, 1); return true; } @@ -355,7 +409,7 @@ bool Inventory::equip(int slot) case ITEM_EQUIPMENT_PROJECTILE: msg.writeByte(EQUIP_PROJECTILE_SLOT); msg.writeShort(itemId); - poss.equipment[EQUIP_PROJECTILE_SLOT] = itemId; + mPoss->equipment[EQUIP_PROJECTILE_SLOT] = itemId; return true; case ITEM_EQUIPMENT_ONE_HAND_WEAPON: @@ -400,19 +454,19 @@ bool Inventory::equip(int slot) return false; } - int id = poss.equipment[firstSlot]; + int id = mPoss->equipment[firstSlot]; switch (availableSlots) { case 2: - if (id && !poss.equipment[secondSlot] && + if (id && !mPoss->equipment[secondSlot] && ItemManager::getItem(id)->getType() != ITEM_EQUIPMENT_TWO_HANDS_WEAPON) { // The first slot is full and the second slot is empty. msg.writeByte(secondSlot); msg.writeShort(itemId); - poss.equipment[secondSlot] = itemId; + mPoss->equipment[secondSlot] = itemId; removeFromSlot(slot, 1); return true; } @@ -425,7 +479,7 @@ bool Inventory::equip(int slot) } msg.writeByte(firstSlot); msg.writeShort(itemId); - poss.equipment[firstSlot] = itemId; + mPoss->equipment[firstSlot] = itemId; removeFromSlot(slot, 1); return true; |