mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Initial commit: wowee native WoW 3.3.5a client
This commit is contained in:
commit
ce6cb8f38e
147 changed files with 32347 additions and 0 deletions
274
src/game/inventory.cpp
Normal file
274
src/game/inventory.cpp
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
#include "game/inventory.hpp"
|
||||
#include "core/logger.hpp"
|
||||
|
||||
namespace wowee {
|
||||
namespace game {
|
||||
|
||||
static const ItemSlot EMPTY_SLOT{};
|
||||
|
||||
Inventory::Inventory() = default;
|
||||
|
||||
const ItemSlot& Inventory::getBackpackSlot(int index) const {
|
||||
if (index < 0 || index >= BACKPACK_SLOTS) return EMPTY_SLOT;
|
||||
return backpack[index];
|
||||
}
|
||||
|
||||
bool Inventory::setBackpackSlot(int index, const ItemDef& item) {
|
||||
if (index < 0 || index >= BACKPACK_SLOTS) return false;
|
||||
backpack[index].item = item;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Inventory::clearBackpackSlot(int index) {
|
||||
if (index < 0 || index >= BACKPACK_SLOTS) return false;
|
||||
backpack[index].item = ItemDef{};
|
||||
return true;
|
||||
}
|
||||
|
||||
const ItemSlot& Inventory::getEquipSlot(EquipSlot slot) const {
|
||||
int idx = static_cast<int>(slot);
|
||||
if (idx < 0 || idx >= NUM_EQUIP_SLOTS) return EMPTY_SLOT;
|
||||
return equipment[idx];
|
||||
}
|
||||
|
||||
bool Inventory::setEquipSlot(EquipSlot slot, const ItemDef& item) {
|
||||
int idx = static_cast<int>(slot);
|
||||
if (idx < 0 || idx >= NUM_EQUIP_SLOTS) return false;
|
||||
equipment[idx].item = item;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Inventory::clearEquipSlot(EquipSlot slot) {
|
||||
int idx = static_cast<int>(slot);
|
||||
if (idx < 0 || idx >= NUM_EQUIP_SLOTS) return false;
|
||||
equipment[idx].item = ItemDef{};
|
||||
return true;
|
||||
}
|
||||
|
||||
int Inventory::getBagSize(int bagIndex) const {
|
||||
if (bagIndex < 0 || bagIndex >= NUM_BAG_SLOTS) return 0;
|
||||
return bags[bagIndex].size;
|
||||
}
|
||||
|
||||
const ItemSlot& Inventory::getBagSlot(int bagIndex, int slotIndex) const {
|
||||
if (bagIndex < 0 || bagIndex >= NUM_BAG_SLOTS) return EMPTY_SLOT;
|
||||
if (slotIndex < 0 || slotIndex >= bags[bagIndex].size) return EMPTY_SLOT;
|
||||
return bags[bagIndex].slots[slotIndex];
|
||||
}
|
||||
|
||||
bool Inventory::setBagSlot(int bagIndex, int slotIndex, const ItemDef& item) {
|
||||
if (bagIndex < 0 || bagIndex >= NUM_BAG_SLOTS) return false;
|
||||
if (slotIndex < 0 || slotIndex >= bags[bagIndex].size) return false;
|
||||
bags[bagIndex].slots[slotIndex].item = item;
|
||||
return true;
|
||||
}
|
||||
|
||||
int Inventory::findFreeBackpackSlot() const {
|
||||
for (int i = 0; i < BACKPACK_SLOTS; i++) {
|
||||
if (backpack[i].empty()) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Inventory::addItem(const ItemDef& item) {
|
||||
// Try stacking first
|
||||
if (item.maxStack > 1) {
|
||||
for (int i = 0; i < BACKPACK_SLOTS; i++) {
|
||||
if (!backpack[i].empty() &&
|
||||
backpack[i].item.itemId == item.itemId &&
|
||||
backpack[i].item.stackCount < backpack[i].item.maxStack) {
|
||||
uint32_t space = backpack[i].item.maxStack - backpack[i].item.stackCount;
|
||||
uint32_t toAdd = std::min(space, item.stackCount);
|
||||
backpack[i].item.stackCount += toAdd;
|
||||
if (toAdd >= item.stackCount) return true;
|
||||
// Remaining needs a new slot — fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int slot = findFreeBackpackSlot();
|
||||
if (slot < 0) return false;
|
||||
backpack[slot].item = item;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Inventory::populateTestItems() {
|
||||
// Equipment
|
||||
{
|
||||
ItemDef sword;
|
||||
sword.itemId = 25;
|
||||
sword.name = "Worn Shortsword";
|
||||
sword.quality = ItemQuality::COMMON;
|
||||
sword.inventoryType = 21; // Main Hand
|
||||
sword.strength = 1;
|
||||
sword.displayInfoId = 1542; // Sword_1H_Short_A_02.m2
|
||||
sword.subclassName = "Sword";
|
||||
setEquipSlot(EquipSlot::MAIN_HAND, sword);
|
||||
}
|
||||
{
|
||||
ItemDef shield;
|
||||
shield.itemId = 2129;
|
||||
shield.name = "Large Round Shield";
|
||||
shield.quality = ItemQuality::COMMON;
|
||||
shield.inventoryType = 14; // Off Hand (Shield)
|
||||
shield.armor = 18;
|
||||
shield.stamina = 1;
|
||||
shield.displayInfoId = 18662; // Shield_Round_A_01.m2
|
||||
shield.subclassName = "Shield";
|
||||
setEquipSlot(EquipSlot::OFF_HAND, shield);
|
||||
}
|
||||
// Shirt/pants/boots in backpack (character model renders bare geosets)
|
||||
{
|
||||
ItemDef shirt;
|
||||
shirt.itemId = 38;
|
||||
shirt.name = "Recruit's Shirt";
|
||||
shirt.quality = ItemQuality::COMMON;
|
||||
shirt.inventoryType = 4; // Shirt
|
||||
shirt.displayInfoId = 2163;
|
||||
addItem(shirt);
|
||||
}
|
||||
{
|
||||
ItemDef pants;
|
||||
pants.itemId = 39;
|
||||
pants.name = "Recruit's Pants";
|
||||
pants.quality = ItemQuality::COMMON;
|
||||
pants.inventoryType = 7; // Legs
|
||||
pants.armor = 4;
|
||||
pants.displayInfoId = 1883;
|
||||
addItem(pants);
|
||||
}
|
||||
{
|
||||
ItemDef boots;
|
||||
boots.itemId = 40;
|
||||
boots.name = "Recruit's Boots";
|
||||
boots.quality = ItemQuality::COMMON;
|
||||
boots.inventoryType = 8; // Feet
|
||||
boots.armor = 3;
|
||||
boots.displayInfoId = 2166;
|
||||
addItem(boots);
|
||||
}
|
||||
|
||||
// Backpack items
|
||||
{
|
||||
ItemDef potion;
|
||||
potion.itemId = 118;
|
||||
potion.name = "Minor Healing Potion";
|
||||
potion.quality = ItemQuality::COMMON;
|
||||
potion.stackCount = 3;
|
||||
potion.maxStack = 5;
|
||||
addItem(potion);
|
||||
}
|
||||
{
|
||||
ItemDef hearthstone;
|
||||
hearthstone.itemId = 6948;
|
||||
hearthstone.name = "Hearthstone";
|
||||
hearthstone.quality = ItemQuality::COMMON;
|
||||
addItem(hearthstone);
|
||||
}
|
||||
{
|
||||
ItemDef leather;
|
||||
leather.itemId = 2318;
|
||||
leather.name = "Light Leather";
|
||||
leather.quality = ItemQuality::COMMON;
|
||||
leather.stackCount = 5;
|
||||
leather.maxStack = 20;
|
||||
addItem(leather);
|
||||
}
|
||||
{
|
||||
ItemDef cloth;
|
||||
cloth.itemId = 2589;
|
||||
cloth.name = "Linen Cloth";
|
||||
cloth.quality = ItemQuality::COMMON;
|
||||
cloth.stackCount = 8;
|
||||
cloth.maxStack = 20;
|
||||
addItem(cloth);
|
||||
}
|
||||
{
|
||||
ItemDef quest;
|
||||
quest.itemId = 50000;
|
||||
quest.name = "Kobold Candle";
|
||||
quest.quality = ItemQuality::COMMON;
|
||||
quest.stackCount = 4;
|
||||
quest.maxStack = 10;
|
||||
addItem(quest);
|
||||
}
|
||||
{
|
||||
ItemDef ring;
|
||||
ring.itemId = 11287;
|
||||
ring.name = "Verdant Ring";
|
||||
ring.quality = ItemQuality::UNCOMMON;
|
||||
ring.inventoryType = 11; // Ring
|
||||
ring.stamina = 3;
|
||||
ring.spirit = 2;
|
||||
addItem(ring);
|
||||
}
|
||||
{
|
||||
ItemDef cloak;
|
||||
cloak.itemId = 2570;
|
||||
cloak.name = "Linen Cloak";
|
||||
cloak.quality = ItemQuality::UNCOMMON;
|
||||
cloak.inventoryType = 16; // Back
|
||||
cloak.armor = 10;
|
||||
cloak.agility = 1;
|
||||
cloak.displayInfoId = 15055;
|
||||
addItem(cloak);
|
||||
}
|
||||
{
|
||||
ItemDef rareAxe;
|
||||
rareAxe.itemId = 15268;
|
||||
rareAxe.name = "Stoneslayer";
|
||||
rareAxe.quality = ItemQuality::RARE;
|
||||
rareAxe.inventoryType = 17; // Two-Hand
|
||||
rareAxe.strength = 8;
|
||||
rareAxe.stamina = 7;
|
||||
rareAxe.subclassName = "Axe";
|
||||
rareAxe.displayInfoId = 782; // Axe_2H_Battle_B_01.m2
|
||||
addItem(rareAxe);
|
||||
}
|
||||
|
||||
LOG_INFO("Inventory: populated test items (2 equipped, 11 backpack)");
|
||||
}
|
||||
|
||||
const char* getQualityName(ItemQuality quality) {
|
||||
switch (quality) {
|
||||
case ItemQuality::POOR: return "Poor";
|
||||
case ItemQuality::COMMON: return "Common";
|
||||
case ItemQuality::UNCOMMON: return "Uncommon";
|
||||
case ItemQuality::RARE: return "Rare";
|
||||
case ItemQuality::EPIC: return "Epic";
|
||||
case ItemQuality::LEGENDARY: return "Legendary";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char* getEquipSlotName(EquipSlot slot) {
|
||||
switch (slot) {
|
||||
case EquipSlot::HEAD: return "Head";
|
||||
case EquipSlot::NECK: return "Neck";
|
||||
case EquipSlot::SHOULDERS: return "Shoulders";
|
||||
case EquipSlot::SHIRT: return "Shirt";
|
||||
case EquipSlot::CHEST: return "Chest";
|
||||
case EquipSlot::WAIST: return "Waist";
|
||||
case EquipSlot::LEGS: return "Legs";
|
||||
case EquipSlot::FEET: return "Feet";
|
||||
case EquipSlot::WRISTS: return "Wrists";
|
||||
case EquipSlot::HANDS: return "Hands";
|
||||
case EquipSlot::RING1: return "Ring 1";
|
||||
case EquipSlot::RING2: return "Ring 2";
|
||||
case EquipSlot::TRINKET1: return "Trinket 1";
|
||||
case EquipSlot::TRINKET2: return "Trinket 2";
|
||||
case EquipSlot::BACK: return "Back";
|
||||
case EquipSlot::MAIN_HAND: return "Main Hand";
|
||||
case EquipSlot::OFF_HAND: return "Off Hand";
|
||||
case EquipSlot::RANGED: return "Ranged";
|
||||
case EquipSlot::TABARD: return "Tabard";
|
||||
case EquipSlot::BAG1: return "Bag 1";
|
||||
case EquipSlot::BAG2: return "Bag 2";
|
||||
case EquipSlot::BAG3: return "Bag 3";
|
||||
case EquipSlot::BAG4: return "Bag 4";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue