diff options
author | Yohann Ferreira <bertram@cegetel.net> | 2006-11-14 23:53:45 +0000 |
---|---|---|
committer | Yohann Ferreira <bertram@cegetel.net> | 2006-11-14 23:53:45 +0000 |
commit | 896901986a1d6ad0e93f494fba0b39b066c2aabf (patch) | |
tree | 3f8684f10c6416beab986cc3217f5e977aefa72c /src | |
parent | 89683f9b2e2f788bbbb23d6874c495e54cf60a28 (diff) | |
download | manaserv-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.cpp | 302 | ||||
-rw-r--r-- | src/inventory.h | 68 | ||||
-rw-r--r-- | src/item.h | 3 | ||||
-rw-r--r-- | src/player.cpp | 4 |
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 */ @@ -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 } |