summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYohann Ferreira <bertram@cegetel.net>2006-11-14 23:53:45 +0000
committerYohann Ferreira <bertram@cegetel.net>2006-11-14 23:53:45 +0000
commit896901986a1d6ad0e93f494fba0b39b066c2aabf (patch)
tree3f8684f10c6416beab986cc3217f5e977aefa72c /src
parent89683f9b2e2f788bbbb23d6874c495e54cf60a28 (diff)
downloadmanaserv-896901986a1d6ad0e93f494fba0b39b066c2aabf.tar.gz
manaserv-896901986a1d6ad0e93f494fba0b39b066c2aabf.tar.bz2
manaserv-896901986a1d6ad0e93f494fba0b39b066c2aabf.tar.xz
manaserv-896901986a1d6ad0e93f494fba0b39b066c2aabf.zip
Adding inventory basics part 2.
Diffstat (limited to 'src')
-rw-r--r--src/inventory.cpp302
-rw-r--r--src/inventory.h68
-rw-r--r--src/item.h3
-rw-r--r--src/player.cpp4
4 files changed, 330 insertions, 47 deletions
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 442b5952..4fbda228 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -26,9 +26,12 @@
Inventory::Inventory()
{
itemList.reserve(MAX_ITEMS_IN_INVENTORY);
- itemList.reserve(TOTAL_EQUIPMENT_SLOTS);
+ equippedItemList.reserve(TOTAL_EQUIPMENT_SLOTS);
}
+// ---------
+// Items
+// ---------
unsigned char
Inventory::getInventoryFreeSlot()
{
@@ -52,14 +55,36 @@ Inventory::getSlotFromId(const unsigned int itemId)
}
bool
-Inventory::hasItem(unsigned int itemId)
+Inventory::hasItem(unsigned int itemId,
+ bool searchInInventory,
+ bool searchInEquipment)
{
- for (int a = 0; a < MAX_ITEMS_IN_INVENTORY; a++)
+ bool hasItem = false;
+ // Search in inventory
+ if (searchInInventory)
{
- if (itemList.at(a).itemId == itemId)
- return true;
+ std::vector<StoredItem>::iterator iter = itemList.begin();
+ for (iter = itemList.begin(); iter != itemList.end(); ++iter)
+ {
+ if (iter->itemId == itemId)
+ hasItem = true;
+ }
}
- return false;
+ // Search in equipment
+ if (searchInEquipment)
+ {
+ std::vector<EquippedItem>::iterator equipIter = equippedItemList.begin();
+ for (equipIter = equippedItemList.begin();
+ equipIter != equippedItemList.end();
+ ++equipIter)
+ {
+ if (equipIter->itemId == itemId)
+ hasItem = true;
+ }
+ if (equippedProjectiles.itemId == itemId)
+ hasItem = true;
+ }
+ return hasItem;
}
short
@@ -76,50 +101,80 @@ Inventory::addItem(unsigned int itemId, unsigned char amount)
// Parsing inventory
unsigned char currentAmountInSlot = 0;
- for (int a = 0; a < MAX_ITEMS_IN_INVENTORY; a++)
+ std::vector<StoredItem>::iterator iter = itemList.begin();
+ for (iter = itemList.begin(); iter != itemList.end(); ++iter)
{
- currentAmountInSlot = itemList.at(a).amount;
- // If a slot a got place for some more of such an item.
- if (itemList.at(a).itemId == itemId && currentAmountInSlot < maxPerSlot)
+ currentAmountInSlot = iter->amount;
+ // If a slot has got place for some more of such an item.
+ if (iter->itemId == itemId && currentAmountInSlot < maxPerSlot)
{
// If there isn't enough space to put every item in the slot.
// We add the difference.
if ((maxPerSlot - currentAmountInSlot) < amountToAdd)
{
- itemList.at(a).amount += (maxPerSlot - currentAmountInSlot);
+ iter->amount += (maxPerSlot - currentAmountInSlot);
amountToAdd -= (maxPerSlot - currentAmountInSlot);
}
else // there is enough to add everything.
{
- itemList.at(a).amount += amountToAdd;
+ iter->amount += amountToAdd;
amountToAdd = 0; // Ok!
}
}
// Or if there is an empty slot.
- else if (itemList.at(a).amount == 0)
+ else if (iter->amount == 0)
{
// We add the item in the new slot (setting also the Id.)
if (maxPerSlot < amountToAdd)
{
- itemList.at(a).amount = maxPerSlot;
+ iter->amount = maxPerSlot;
amountToAdd -= maxPerSlot;
}
else
{
- itemList.at(a).amount += amountToAdd;
+ iter->amount += amountToAdd;
amountToAdd = 0; // Ok!
}
- itemList.at(a).itemId = itemId;
+ iter->itemId = itemId;
}
}
- return (short)amount - amountToAdd;
+ return (short)(amount - amountToAdd);
}
short
Inventory::removeItem(unsigned int itemId, unsigned char amount)
{
- return false; // TODO
+ // We'll remove items in slots with the item type
+ // until it's all done or until the inventory will be all parsed.
+ // Searching for items with the same Id in the inventory
+ unsigned char amountToRemove = amount;
+
+ // Parsing inventory
+ unsigned char currentAmountInSlot = 0;
+ std::vector<StoredItem>::iterator iter = itemList.begin();
+ for (iter = itemList.begin(); iter != itemList.end(); ++iter)
+ {
+ currentAmountInSlot = iter->amount;
+ // If a slot has got such an item, remove it
+ if (iter->itemId == itemId && currentAmountInSlot > 0)
+ {
+ // If there isn't enough to finish, we remove the difference
+ // Emptying the slot, so we clean also the itemId.
+ if (currentAmountInSlot <= amountToRemove)
+ {
+ amountToRemove -= currentAmountInSlot;
+ iter->amount = 0;
+ iter->itemId = 0;
+ }
+ else // there is enough to remove everything.
+ {
+ iter->amount -= amountToRemove;
+ amountToRemove = 0; // Ok!
+ }
+ }
+ }
+ return (short)(amount - amountToRemove);
}
short
@@ -139,38 +194,231 @@ Inventory::removeItem(unsigned char slot, unsigned char amount)
}
bool
-Inventory::equipItem(unsigned int itemId)
+Inventory::use(unsigned char slot, BeingPtr itemUser)
{
return false; // TODO
}
bool
-Inventory::unequipItem(unsigned int itemId)
+Inventory::use(unsigned int itemId, BeingPtr itemUser)
{
return false; // TODO
}
-bool
-Inventory::equipItem(unsigned char slot)
+// ---------
+// Equipment
+// ---------
+unsigned char
+Inventory::equipItem(unsigned int itemId)
{
- return false; // TODO
+ // First, we look for the item in the player's inventory.
+ if (!hasItem(itemId, true, false))
+ return false;
+
+ unsigned char availableSlots = 0, firstSlot = 0, secondSlot = 0;
+
+ unsigned short itemType = itemManager->getItemType(itemId);
+ switch (itemType)
+ {
+ case ITEM_EQUIPMENT_TWO_HANDS_WEAPON:
+ // Special case 1, the two one-handed weapons are to be placed back
+ // in the inventory, if there are any.
+ if (equippedItemList.at(EQUIP_FIGHT1_SLOT).itemId > 0)
+ { // Slot 1 full
+ // old two-handed weapon case:
+ if (equippedItemList.at(EQUIP_FIGHT1_SLOT).itemType
+ == ITEM_EQUIPMENT_TWO_HANDS_WEAPON)
+ {
+ equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId = 0;
+ equippedItemList.at(EQUIP_FIGHT2_SLOT).itemType = 0;
+ }
+
+ if (unequipItem_(equippedItemList.at(EQUIP_FIGHT1_SLOT).itemId,
+ EQUIP_FIGHT1_SLOT) == INVENTORY_FULL)
+ return INVENTORY_FULL;
+ }
+ if (equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId > 0)
+ { // Slot 2 full
+ if (unequipItem_(equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId,
+ EQUIP_FIGHT2_SLOT) == INVENTORY_FULL)
+ return INVENTORY_FULL;
+ }
+ // Only the slot 1 needs to be updated.
+ return equipItem_(itemId, itemType, EQUIP_FIGHT1_SLOT);
+ break;
+
+ case ITEM_EQUIPMENT_PROJECTILE:
+ // Special case 2: the projectile is a Stored Item structure,
+ // but is still considered as part of the equipment.
+ // Case 1: Reloading
+ if (equippedProjectiles.itemId == itemId)
+ {
+ equippedProjectiles.amount += removeItem(itemId,
+ (255 - equippedProjectiles.amount));
+ return EQUIP_PROJECTILES_SLOT;
+ }
+ else // Case 2: Changing projectiles.
+ {
+ short added;
+ added = addItem(equippedProjectiles.itemId,
+ equippedProjectiles.amount);
+ if (added == equippedProjectiles.amount)
+ { // Ok, we can equip
+ equippedProjectiles.itemId = itemId;
+ equippedProjectiles.amount = removeItem(itemId, 255);
+ return EQUIP_PROJECTILES_SLOT;
+ }
+ else // Some were unequipped.
+ {
+ equippedProjectiles.amount -= added;
+ return INVENTORY_FULL;
+ }
+ }
+ break;
+
+ case ITEM_EQUIPMENT_ONE_HAND_WEAPON:
+ case ITEM_EQUIPMENT_SHIELD:
+ availableSlots = 2;
+ firstSlot = EQUIP_FIGHT1_SLOT;
+ secondSlot = EQUIP_FIGHT2_SLOT;
+ break;
+ case ITEM_EQUIPMENT_RING:
+ availableSlots = 2;
+ firstSlot = EQUIP_RING1_SLOT;
+ secondSlot = EQUIP_RING2_SLOT;
+ break;
+ case ITEM_EQUIPMENT_BREST:
+ availableSlots = 1;
+ firstSlot = EQUIP_BREST_SLOT;
+ break;
+ case ITEM_EQUIPMENT_ARMS:
+ availableSlots = 1;
+ firstSlot = EQUIP_ARMS_SLOT;
+ break;
+ case ITEM_EQUIPMENT_HEAD:
+ availableSlots = 1;
+ firstSlot = EQUIP_HEAD_SLOT;
+ break;
+ case ITEM_EQUIPMENT_LEGS:
+ availableSlots = 1;
+ firstSlot = EQUIP_LEGS_SLOT;
+ break;
+ case ITEM_EQUIPMENT_NECKLACE:
+ availableSlots = 1;
+ firstSlot = EQUIP_NECKLACE_SLOT;
+ break;
+ case ITEM_EQUIPMENT_FEET:
+ availableSlots = 1;
+ firstSlot = EQUIP_FEET_SLOT;
+ break;
+
+ case ITEM_UNUSABLE:
+ case ITEM_USABLE:
+ default:
+ return NOT_EQUIPPABLE;
+ }
+
+ switch (availableSlots)
+ {
+ case 1:
+ if (equippedItemList.at(firstSlot).itemId > 0)
+ {
+ if (unequipItem_(equippedItemList.at(firstSlot).itemId,
+ firstSlot) != INVENTORY_FULL)
+ return equipItem_(itemId, itemType, firstSlot);
+ else
+ return INVENTORY_FULL;
+ }
+ else // slot empty, we can equip.
+ {
+ return equipItem_(itemId, itemType, firstSlot);
+ }
+ break;
+
+ case 2:
+ if (equippedItemList.at(firstSlot).itemId > 0)
+ {
+ // If old weapon is two-handed one, we can unequip
+ // the first slot only, and clean the second.
+ if (equippedItemList.at(firstSlot).itemId ==
+ ITEM_EQUIPMENT_TWO_HANDS_WEAPON)
+ {
+ if (unequipItem_(equippedItemList.at(firstSlot).itemId,
+ firstSlot) != INVENTORY_FULL)
+ return equipItem_(itemId, itemType, firstSlot);
+ else
+ return INVENTORY_FULL;
+ }
+
+ if (equippedItemList.at(secondSlot).itemId > 0)
+ { // Both slots are full,
+ // we remove the first one to equip
+ if (unequipItem_(equippedItemList.at(firstSlot).itemId,
+ firstSlot) != INVENTORY_FULL)
+ return equipItem_(itemId, itemType, firstSlot);
+ else
+ return INVENTORY_FULL;
+ }
+ else // Second slot empty, we can equip.
+ {
+ return equipItem_(itemId, itemType, secondSlot);
+ }
+ }
+ else // first slot empty, we can equip.
+ {
+ return equipItem_(itemId, itemType, firstSlot);
+ }
+ break;
+
+ default:
+ return NOT_EQUIPPABLE;
+ }
}
bool
-Inventory::unequipItem(unsigned char slot)
+Inventory::equipItem(unsigned char inventorySlot, unsigned char equipmentSlot)
{
return false; // TODO
}
-
bool
-Inventory::use(unsigned char slot, BeingPtr itemUser)
+Inventory::unequipItem(unsigned int itemId)
{
return false; // TODO
}
bool
-Inventory::use(unsigned int itemId, BeingPtr itemUser)
+Inventory::unequipItem(unsigned char inventorySlot,
+ unsigned char equipmentSlot)
{
return false; // TODO
}
+
+unsigned char
+Inventory::equipItem_(unsigned int itemId,
+ unsigned int itemType,
+ unsigned char equipmentSlot)
+{
+ if (removeItem(itemId, 1) == 1)
+ {
+ equippedItemList.at(equipmentSlot).itemId = itemId;
+ equippedItemList.at(equipmentSlot).itemType = itemType;
+ return equipmentSlot;
+ }
+ else
+ return NO_ITEM_TO_EQUIP;
+}
+
+unsigned char
+Inventory::unequipItem_(unsigned int itemId,
+ unsigned char equipmentSlot)
+{
+ if (addItem(itemId, 1) == 1)
+ {
+ equippedItemList.at(equipmentSlot).itemId = 0;
+ equippedItemList.at(equipmentSlot).itemType = 0;
+ return equipmentSlot;
+ }
+ else
+ return INVENTORY_FULL;
+}
diff --git a/src/inventory.h b/src/inventory.h
index 198c181b..ab9a256e 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -27,21 +27,36 @@
#include "itemmanager.h"
// items in inventory :
-const unsigned char MAX_ITEMS_IN_INVENTORY = 50, // Max 254.
+const unsigned char MAX_ITEMS_IN_INVENTORY = 50, // Max 252.
// Equipment rules:
// 1 Brest equipment
+ EQUIP_BREST_SLOT = 0,
// 1 arms equipment
+ EQUIP_ARMS_SLOT = 1,
// 1 head equipment
+ EQUIP_HEAD_SLOT = 2,
// 1 legs equipment
+ EQUIP_LEGS_SLOT = 3,
// 1 feet equipment
+ EQUIP_FEET_SLOT = 4,
// 2 rings
+ EQUIP_RING1_SLOT = 5,
+ EQUIP_RING2_SLOT = 6,
// 1 necklace
+ EQUIP_NECKLACE_SLOT = 7,
// Fight:
// 2 one-handed weapons
+ EQUIP_FIGHT1_SLOT = 8,
+ EQUIP_FIGHT2_SLOT = 9,
// or 1 two-handed weapon
// or 1 one-handed weapon + 1 shield.
+// Projectiles
+ EQUIP_PROJECTILES_SLOT = 10,
// = 10 total slots for equipment.
- TOTAL_EQUIPMENT_SLOTS = 10,
+ TOTAL_EQUIPMENT_SLOTS = 11,
+// Error codes
+ NOT_EQUIPPABLE = 253,
+ NO_ITEM_TO_EQUIP = 254,
INVENTORY_FULL = 255;
/**
@@ -92,17 +107,12 @@ class Inventory
getStoredItemAt(unsigned char slot) const { return itemList.at(slot); };
/**
- * Return Item reference from ItemReference
- */
- //ItemPtr getItem(unsigned short index) const
- //{ return itemReference.getItem(itemList.at(index).itemId); };
-
- /**
- * Search in inventory only if an item is present.
- * Don't tell if an item is equipped.
+ * Search in inventory and equipment if an item is present.
*/
bool
- hasItem(unsigned int itemId);
+ hasItem(unsigned int itemId,
+ bool searchInInventory = true,
+ bool searchInEquipment = true);
/**
* Tells an item's amount
@@ -145,12 +155,16 @@ class Inventory
/**
* Equip an item searched by its id.
+ * Can equip more than one item at a time.
+ * @return unsigned char value: Returns the slot if successful
+ * or the error code if not.
*/
- bool
+ unsigned char
equipItem(unsigned int itemId);
/**
* Unequip an item searched by its id.
+ * Can unequip more than one item at a time.
*/
bool
unequipItem(unsigned int itemId);
@@ -159,24 +173,24 @@ class Inventory
* Equip an item searched by its slot index.
*/
bool
- equipItem(unsigned char slot);
+ equipItem(unsigned char inventorySlot, unsigned char equipmentSlot);
/**
- * Unequip an item searched by its slot index.
+ * Unequip an equipped item searched by its slot index.
*/
bool
- unequipItem(unsigned char slot);
+ unequipItem(unsigned char inventorySlot, unsigned char equipmentSlot);
/**
* The function called to use an item applying
- * only the modifiers (for simple items...)
+ * only the modifiers
*/
bool
use(unsigned char slot, BeingPtr itemUser);
/**
* The function called to use an item applying
- * only the modifiers (for simple items...)
+ * only the modifiers
*/
bool
use(unsigned int itemId, BeingPtr itemUser);
@@ -188,6 +202,26 @@ class Inventory
*/
unsigned char getInventoryFreeSlot();
+ /**
+ * Quick equip an equipment with a given equipSlot,
+ * an itemId and an itemType.
+ * @return the equipment slot if successful,
+ * the error code, if not.
+ */
+ unsigned char equipItem_(unsigned int itemId,
+ unsigned int itemType,
+ unsigned char equipmentSlot);
+
+ /**
+ * Quick unequip an equipment with a given equipSlot,
+ * and an itemId.
+ * @return the Equipment slot if successful,
+ * the error code, if not.
+ */
+ unsigned char unequipItem_(unsigned int itemId,
+ unsigned char equipmentSlot);
+
+
// Stored items in inventory and equipment
std::vector<StoredItem> itemList; /**< Items in inventory */
std::vector<EquippedItem> equippedItemList; /**< Equipped Items */
diff --git a/src/item.h b/src/item.h
index 492e97c8..f57ac863 100644
--- a/src/item.h
+++ b/src/item.h
@@ -41,7 +41,8 @@ typedef enum ItemType {
ITEM_EQUIPMENT_SHIELD, // 8
ITEM_EQUIPMENT_RING, // 9
ITEM_EQUIPMENT_NECKLACE, // 10
- ITEM_EQUIPMENT_FEET // 11
+ ITEM_EQUIPMENT_FEET, // 11
+ ITEM_EQUIPMENT_PROJECTILE // 12
};
/**
diff --git a/src/player.cpp b/src/player.cpp
index e4c49b12..40650157 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -66,10 +66,10 @@ bool Player::hasItem(unsigned int itemId)
bool Player::equip(unsigned char slot)
{
- return true; // TODO
+ return false; // TODO
}
bool Player::unequip(unsigned char slot)
{
- return true; // TODO
+ return false; // TODO
}