[Scummvm-git-logs] scummvm master -> 44ea691154db466fe9a07addea302e7fa5b24cab

dreammaster dreammaster at scummvm.org
Sat Mar 10 13:08:11 CET 2018


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
aaf954e5d4 XEEN: Move item classes into their own file
44ea691154 XEEN: Cleanup and comments for Combat class


Commit: aaf954e5d46e9f9664aec00d4bc6df94a582d1c2
    https://github.com/scummvm/scummvm/commit/aaf954e5d46e9f9664aec00d4bc6df94a582d1c2
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-03-10T06:44:07-05:00

Commit Message:
XEEN: Move item classes into their own file

Changed paths:
  A engines/xeen/item.cpp
  A engines/xeen/item.h
    engines/xeen/character.cpp
    engines/xeen/character.h
    engines/xeen/module.mk


diff --git a/engines/xeen/character.cpp b/engines/xeen/character.cpp
index c6ebde8..248d432 100644
--- a/engines/xeen/character.cpp
+++ b/engines/xeen/character.cpp
@@ -21,656 +21,15 @@
  */
 
 #include "xeen/character.h"
-#include "xeen/dialogs/dialogs_query.h"
-#include "xeen/dialogs/dialogs_message.h"
 #include "xeen/resources.h"
 #include "xeen/xeen.h"
 
 namespace Xeen {
 
-XeenItem::XeenItem() {
-	clear();
-}
-
-void XeenItem::clear() {
-	_material = _id = _bonusFlags = 0;
-	_frame = 0;
-}
-
-void XeenItem::synchronize(Common::Serializer &s) {
-	s.syncAsByte(_material);
-	s.syncAsByte(_id);
-	s.syncAsByte(_bonusFlags);
-	s.syncAsByte(_frame);
-}
-
-ElementalCategory XeenItem::getElementalCategory() const {
-	int idx;
-	for (idx = 0; Res.ELEMENTAL_CATEGORIES[idx] < _material; ++idx)
-		;
-
-	return (ElementalCategory)idx;
-}
-
-AttributeCategory XeenItem::getAttributeCategory() const {
-	int m = _material - 59;
-	int idx;
-	for (idx = 0; Res.ATTRIBUTE_CATEGORIES[idx] < m; ++idx)
-		;
-
-	return (AttributeCategory)idx;
-}
-
-const char *XeenItem::getItemName(ItemCategory category, uint id) {
-	if (id < 82)
-		return Res.ITEM_NAMES[category][id];
-
-	switch (category) {
-	case CATEGORY_WEAPON:
-		return Res.QUEST_ITEM_NAMES[id - 82];
-
-	case CATEGORY_ARMOR:
-		return Res.QUEST_ITEM_NAMES[id - 82 + 35];
-
-	case CATEGORY_ACCESSORY:
-		return Res.QUEST_ITEM_NAMES[id - 82 + 35 + 14];
-
-	default:
-		return Res.QUEST_ITEM_NAMES[id - 82 + 35 + 14 + 11];
-	}
-}
-
-/*------------------------------------------------------------------------*/
-
-InventoryItems::InventoryItems(Character *character, ItemCategory category):
-		_character(character), _category(category) {
-	resize(INV_ITEMS_TOTAL);
-
-	_names = Res.ITEM_NAMES[category];
-}
-
-void InventoryItems::clear() {
-	for (uint idx = 0; idx < size(); ++idx)
-		operator[](idx).clear();
-}
-
-bool InventoryItems::passRestrictions(int itemId, bool showError) const {
-	CharacterClass charClass = _character->_class;
-
-	switch (charClass) {
-	case CLASS_KNIGHT:
-	case CLASS_PALADIN:
-		return true;
-
-	case CLASS_ARCHER:
-	case CLASS_CLERIC:
-	case CLASS_SORCERER:
-	case CLASS_ROBBER:
-	case CLASS_NINJA:
-	case CLASS_BARBARIAN:
-	case CLASS_DRUID:
-	case CLASS_RANGER: {
-		if (!(Res.ITEM_RESTRICTIONS[itemId + Res.RESTRICTION_OFFSETS[_category]] &
-			(1 << (charClass - CLASS_ARCHER))))
-			return true;
-		break;
-	}
-
-	default:
-		break;
-	}
-
-	Common::String name = _names[itemId];
-	if (showError) {
-		Common::String msg = Common::String::format(Res.NOT_PROFICIENT,
-			Res.CLASS_NAMES[charClass], name.c_str());
-		ErrorScroll::show(Party::_vm, msg, WT_FREEZE_WAIT);
-	}
-
-	return false;
-}
-
-Common::String InventoryItems::getName(int itemIndex) {
-	int id = operator[](itemIndex)._id;
-	return _names[id];
-}
-
-Common::String InventoryItems::getIdentifiedDetails(int itemIndex) {
-	XeenItem &item = operator[](itemIndex);
-
-	Common::String classes;
-	for (int charClass = CLASS_KNIGHT; charClass <= CLASS_RANGER; ++charClass) {
-		if (passRestrictions(charClass, true)) {
-			const char *const name = Res.CLASS_NAMES[charClass];
-			classes += name[0];
-			classes += name[1];
-			classes += " ";
-		}
-	}
-	if (classes.size() == 30)
-		classes = Res.ALL;
-
-	return getAttributes(item, classes);
-}
-
-bool InventoryItems::discardItem(int itemIndex) {
-	XeenItem &item = operator[](itemIndex);
-	XeenEngine *vm = Party::_vm;
-
-	if (item._bonusFlags & ITEMFLAG_CURSED) {
-		ErrorScroll::show(vm, Res.CANNOT_DISCARD_CURSED_ITEM);
-	} else {
-		Common::String itemDesc = getFullDescription(itemIndex, 4);
-		Common::String msg = Common::String::format(Res.PERMANENTLY_DISCARD, itemDesc.c_str());
-
-		if (Confirm::show(vm, msg)) {
-			operator[](itemIndex).clear();
-			sort();
-
-			return true;
-		}
-	}
-
-	return true;
-}
-
-void InventoryItems::sort() {
-	for (uint idx = 0; idx < size(); ++idx) {
-		if (operator[](idx)._id == 0) {
-			// Found empty slot
-			operator[](idx).clear();
-
-			// Scan through the rest of the list to find any item
-			for (uint idx2 = idx + 1; idx2 < size(); ++idx2) {
-				if (operator[](idx2)._id) {
-					// Found an item, so move it into the blank slot
-					operator[](idx) = operator[](idx2);
-					operator[](idx2).clear();
-					break;
-				}
-			}
-		}
-	}
-}
-
-void InventoryItems::removeItem(int itemIndex) {
-	XeenItem &item = operator[](itemIndex);
-	XeenEngine *vm = Party::_vm;
-
-	if (item._bonusFlags & ITEMFLAG_CURSED)
-		ErrorScroll::show(vm, Res.CANNOT_REMOVE_CURSED_ITEM);
-	else
-		item._frame = 0;
-}
-
-XeenEngine *InventoryItems::getVm() {
-	return Party::_vm;
-}
-
-void InventoryItems::equipError(int itemIndex1, ItemCategory category1, int itemIndex2,
-		ItemCategory category2) {
-	XeenEngine *vm = Party::_vm;
-
-	if (itemIndex1 >= 0) {
-		Common::String itemName1 = _character->_items[category1].getName(itemIndex1);
-		Common::String itemName2 = _character->_items[category2].getName(itemIndex2);
-
-		MessageDialog::show(vm, Common::String::format(Res.REMOVE_X_TO_EQUIP_Y,
-			itemName1.c_str(), itemName2.c_str()));
-	} else {
-		MessageDialog::show(vm, Common::String::format(Res.EQUIPPED_ALL_YOU_CAN,
-			(itemIndex1 == -1) ? Res.RING : Res.MEDAL));
-	}
-}
-
-void InventoryItems::enchantItem(int itemIndex, int amount) {
-	XeenEngine *vm = Party::_vm;
-	vm->_sound->playFX(21);
-	ErrorScroll::show(vm, Common::String::format(Res.NOT_ENCHANTABLE, Res.SPELL_FAILED));
-}
-
-bool InventoryItems::isFull() const {
-	return operator[](size() - 1)._id != 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-void WeaponItems::equipItem(int itemIndex) {
-	XeenItem &item = operator[](itemIndex);
-
-	if (item._id <= 17) {
-		if (passRestrictions(item._id, false)) {
-			for (uint idx = 0; idx < size(); ++idx) {
-				XeenItem &i = operator[](idx);
-				if (i._frame == 13 || i._frame == 1) {
-					equipError(itemIndex, CATEGORY_WEAPON, idx, CATEGORY_WEAPON);
-					return;
-				}
-			}
-
-			item._frame = 1;
-		}
-	} else if (item._id >= 30 && item._id <= 33) {
-		if (passRestrictions(item._id, false)) {
-			for (uint idx = 0; idx < size(); ++idx) {
-				XeenItem &i = operator[](idx);
-				if (i._frame == 4) {
-					equipError(itemIndex, CATEGORY_WEAPON, idx, CATEGORY_WEAPON);
-					return;
-				}
-			}
-
-			item._frame = 4;
-		}
-	} else {
-		if (passRestrictions(item._id, false)) {
-			for (uint idx = 0; idx < size(); ++idx) {
-				XeenItem &i = operator[](idx);
-				if (i._frame == 13 || i._frame == 1) {
-					equipError(itemIndex, CATEGORY_WEAPON, idx, CATEGORY_WEAPON);
-					return;
-				}
-			}
-
-			for (uint idx = 0; idx < _character->_armor.size(); ++idx) {
-				XeenItem &i = _character->_armor[idx];
-				if (i._frame == 2) {
-					equipError(itemIndex, CATEGORY_WEAPON, idx, CATEGORY_ARMOR);
-					return;
-				}
-			}
-
-			item._frame = 13;
-		}
-	}
-}
-
-Common::String WeaponItems::getFullDescription(int itemIndex, int displayNum) {
-	XeenItem &i = operator[](itemIndex);
-	Resources &res = *getVm()->_resources;
-
-	return Common::String::format("\f%02u%s%s%s\f%02u%s%s%s", displayNum,
-		!i._bonusFlags ? res._maeNames[i._material].c_str() : "",
-		(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
-		(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
-		displayNum,
-		Res.WEAPON_NAMES[i._id],
-		!i._bonusFlags ? "" : Res.BONUS_NAMES[i._bonusFlags & ITEMFLAG_BONUS_MASK],
-		(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
-			!i._bonusFlags ? "\b " : ""
-	);
-}
-
-void WeaponItems::enchantItem(int itemIndex, int amount) {
-	Sound &sound = *getVm()->_sound;
-	XeenItem &item = operator[](itemIndex);
-	Character tempCharacter;
-
-	if (item._material == 0 && item._bonusFlags == 0 && item._id != 34) {
-		tempCharacter.makeItem(amount, 0, 1);
-		XeenItem &tempItem = tempCharacter._weapons[0];
-
-		item._material = tempItem._material;
-		item._bonusFlags = tempItem._bonusFlags;
-		sound.playFX(19);
-	} else {
-		InventoryItems::enchantItem(itemIndex, amount);
-	}
-}
-
-/*
- * Returns a text string listing all the stats/attributes of a given item
- */
-Common::String WeaponItems::getAttributes(XeenItem &item, const Common::String &classes) {
-	Common::String attrBonus, elemDamage, physDamage, toHit, specialPower;
-	attrBonus = elemDamage = physDamage = toHit = specialPower = Res.FIELD_NONE;
-
-	// First calculate physical damage
-	int minVal = Res.WEAPON_DAMAGE_BASE[item._id];
-	int maxVal = minVal * Res.WEAPON_DAMAGE_MULTIPLIER[item._id];
-
-	if (item._material >= 37 && item._material <= 58) {
-		minVal += Res.METAL_DAMAGE[item._material - 37];
-		maxVal += Res.METAL_DAMAGE[item._material - 37];
-		toHit = Common::String::format("%+d", Res.METAL_DAMAGE_PERCENT[item._material - 37]);
-	}
-
-	physDamage = Common::String::format(Res.DAMAGE_X_TO_Y, minVal, maxVal);
-
-	// Next handle elemental/attribute damage
-	if (item._material < 37) {
-		int damage = Res.ELEMENTAL_DAMAGE[item._material];
-		if (damage > 0) {
-			ElementalCategory elemCategory = item.getElementalCategory();
-			elemDamage = Common::String::format(Res.ELEMENTAL_XY_DAMAGE,
-				damage, Res.ELEMENTAL_NAMES[elemCategory]);
-		}
-	} else if (item._material >= 59) {
-		int bonus = Res.ATTRIBUTE_BONUSES[item._material - 59];
-		AttributeCategory attrCategory = item.getAttributeCategory();
-		attrBonus = Common::String::format(Res.ATTR_XY_BONUS, bonus,
-			Res.ATTRIBUTE_NAMES[attrCategory]);
-	}
-
-	// Handle weapon effective against
-	int effective = item._bonusFlags & ITEMFLAG_BONUS_MASK;
-	if (effective) {
-		specialPower = Common::String::format(Res.EFFECTIVE_AGAINST,
-			Res.EFFECTIVENESS_NAMES[effective]);
-	}
-
-	return Common::String::format(Res.ITEM_DETAILS, classes.c_str(),
-		toHit.c_str(), physDamage.c_str(), elemDamage.c_str(),
-		Res.FIELD_NONE, Res.FIELD_NONE, attrBonus.c_str(), specialPower.c_str()
-	);
-}
-
-/*------------------------------------------------------------------------*/
-
-void ArmorItems::equipItem(int itemIndex) {
-	XeenItem &item = operator[](itemIndex);
-
-	if (item._id <= 7) {
-		if (passRestrictions(item._id, false)) {
-			for (uint idx = 0; idx < size(); ++idx) {
-				XeenItem &i = operator[](idx);
-				if (i._frame == 9) {
-					equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
-					return;
-				}
-			}
-
-			item._frame = 3;
-		}
-	} else if (item._id == 8) {
-		if (passRestrictions(item._id, false)) {
-			for (uint idx = 0; idx < size(); ++idx) {
-				XeenItem &i = operator[](idx);
-				if (i._frame == 2) {
-					equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
-					return;
-				}
-			}
-
-			for (uint idx = 0; idx < _character->_weapons.size(); ++idx) {
-				XeenItem &i = _character->_weapons[idx];
-				if (i._frame == 13) {
-					equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_WEAPON);
-					return;
-				}
-			}
-
-			item._frame = 2;
-		}
-	} else if (item._id == 9) {
-		for (uint idx = 0; idx < size(); ++idx) {
-			XeenItem &i = operator[](idx);
-			if (i._frame == 5) {
-				equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
-				return;
-			}
-		}
-
-		item._frame = 5;
-	} else if (item._id == 10) {
-		for (uint idx = 0; idx < size(); ++idx) {
-			XeenItem &i = operator[](idx);
-			if (i._frame == 9) {
-				equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
-				return;
-			}
-		}
-
-		item._frame = 9;
-	} else if (item._id <= 12) {
-		for (uint idx = 0; idx < size(); ++idx) {
-			XeenItem &i = operator[](idx);
-			if (i._frame == 10) {
-				equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
-				return;
-			}
-		}
-
-		item._frame = 10;
-	} else {
-		for (uint idx = 0; idx < size(); ++idx) {
-			XeenItem &i = operator[](idx);
-			if (i._frame == 6) {
-				equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
-				return;
-			}
-		}
-
-		item._frame = 6;
-	}
-}
-
-Common::String ArmorItems::getFullDescription(int itemIndex, int displayNum) {
-	XeenItem &i = operator[](itemIndex);
-	Resources &res = *getVm()->_resources;
-
-	return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
-		!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
-		(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
-		(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
-		displayNum,
-		Res.ARMOR_NAMES[i._id],
-		(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
-			!i._bonusFlags ? "\b " : ""
-	);
-}
-
-void ArmorItems::enchantItem(int itemIndex, int amount) {
-	Sound &sound = *getVm()->_sound;
-	XeenItem &item = operator[](itemIndex);
-	Character tempCharacter;
-
-	if (item._material == 0 && item._bonusFlags == 0) {
-		tempCharacter.makeItem(amount, 0, 2);
-		XeenItem &tempItem = tempCharacter._armor[0];
-
-		item._material = tempItem._material;
-		item._bonusFlags = tempItem._bonusFlags;
-		sound.playFX(19);
-	} else {
-		InventoryItems::enchantItem(itemIndex, amount);
-	}
-}
-
-/*
-* Returns a text string listing all the stats/attributes of a given item
-*/
-Common::String ArmorItems::getAttributes(XeenItem &item, const Common::String &classes) {
-	Common::String elemResist, attrBonus, acBonus;
-	elemResist = attrBonus = acBonus = Res.FIELD_NONE;
-
-	if (item._material < 36) {
-		int resistence = Res.ELEMENTAL_RESISTENCES[item._material];
-		if (resistence > 0) {
-			int eCategory = ELEM_FIRE;
-			while (eCategory < ELEM_MAGIC && Res.ELEMENTAL_CATEGORIES[eCategory] < item._material)
-				++eCategory;
-
-			elemResist = Common::String::format(Res.ATTR_XY_BONUS, resistence,
-				Res.ELEMENTAL_NAMES[eCategory]);
-		}
-	} else if (item._material >= 59) {
-		int bonus = Res.ATTRIBUTE_BONUSES[item._material - 59];
-		AttributeCategory aCategory = item.getAttributeCategory();
-		attrBonus = Common::String::format(Res.ATTR_XY_BONUS, bonus,
-			Res.ATTRIBUTE_NAMES[aCategory]);
-	}
-
-	int strength = Res.ARMOR_STRENGTHS[item._id];
-	if (item._material >= 37 && item._material <= 58) {
-		strength += Res.METAL_LAC[item._material - 37];
-	}
-	acBonus = Common::String::format("%+d", strength);
-
-	return Common::String::format(Res.ITEM_DETAILS, classes.c_str(),
-		Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE,
-		elemResist.c_str(), acBonus.c_str(), attrBonus.c_str(), Res.FIELD_NONE);
-}
-
-/*------------------------------------------------------------------------*/
-
-void AccessoryItems::equipItem(int itemIndex) {
-	XeenItem &item = operator[](itemIndex);
-
-	if (item._id == 1) {
-		int count = 0;
-		for (uint idx = 0; idx < size(); ++idx) {
-			XeenItem &i = operator[](idx);
-			if (i._frame == 8)
-				++count;
-		}
-
-		if (count <= 1)
-			item._frame = 8;
-		else
-			equipError(-1, CATEGORY_ACCESSORY, itemIndex, CATEGORY_ACCESSORY);
-	} else if (item._id == 2) {
-		for (uint idx = 0; idx < size(); ++idx) {
-			XeenItem &i = operator[](idx);
-			if (i._frame == 12) {
-				equipError(itemIndex, CATEGORY_ACCESSORY, idx, CATEGORY_ACCESSORY);
-				return;
-			}
-		}
-	} else if (item._id <= 7) {
-		int count = 0;
-		for (uint idx = 0; idx < size(); ++idx) {
-			XeenItem &i = operator[](idx);
-			if (i._frame == 7)
-				++count;
-		}
-
-		if (count <= 1)
-			item._frame = 7;
-		else
-			equipError(-2, CATEGORY_ACCESSORY, itemIndex, CATEGORY_ACCESSORY);
-	} else {
-		for (uint idx = 0; idx < size(); ++idx) {
-			XeenItem &i = operator[](idx);
-			if (i._frame == 11) {
-				equipError(itemIndex, CATEGORY_ACCESSORY, idx, CATEGORY_ACCESSORY);
-				return;
-			}
-		}
-
-		item._frame = 11;
-	}
-}
-
-Common::String AccessoryItems::getFullDescription(int itemIndex, int displayNum) {
-	XeenItem &i = operator[](itemIndex);
-	Resources &res = *getVm()->_resources;
-
-	return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
-		!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
-		(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
-		(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
-		displayNum,
-		Res.ARMOR_NAMES[i._id],
-		(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
-			!i._bonusFlags ? "\b " : ""
-	);
-}
-
-/*
-* Returns a text string listing all the stats/attributes of a given item
-*/
-Common::String AccessoryItems::getAttributes(XeenItem &item, const Common::String &classes) {
-	Common::String elemResist, attrBonus;
-	elemResist = attrBonus = Res.FIELD_NONE;
-
-	if (item._material < 36) {
-		int resistence = Res.ELEMENTAL_RESISTENCES[item._material];
-		if (resistence > 0) {
-			int eCategory = ELEM_FIRE;
-			while (eCategory < ELEM_MAGIC && Res.ELEMENTAL_CATEGORIES[eCategory] < item._material)
-				++eCategory;
-
-			elemResist = Common::String::format(Res.ATTR_XY_BONUS, resistence,
-				Res.ELEMENTAL_NAMES[eCategory]);
-		}
-	} else if (item._material >= 59) {
-		int bonus = Res.ATTRIBUTE_BONUSES[item._material - 59];
-		AttributeCategory aCategory = item.getAttributeCategory();
-		attrBonus = Common::String::format(Res.ATTR_XY_BONUS, bonus,
-			Res.ATTRIBUTE_NAMES[aCategory]);
-	}
-
-	return Common::String::format(Res.ITEM_DETAILS, classes.c_str(),
-		Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE,
-		elemResist.c_str(), Res.FIELD_NONE, attrBonus.c_str(), Res.FIELD_NONE);
-}
-
-/*------------------------------------------------------------------------*/
-
-Common::String MiscItems::getFullDescription(int itemIndex, int displayNum) {
-	XeenItem &i = operator[](itemIndex);
-	Resources &res = *getVm()->_resources;
-
-	return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
-		!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
-		(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
-		(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
-		displayNum,
-		Res.ARMOR_NAMES[i._id],
-		(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
-			!i._id ? "\b " : ""
-	);
-}
-
-
-/*
-* Returns a text string listing all the stats/attributes of a given item
-*/
-Common::String MiscItems::getAttributes(XeenItem &item, const Common::String &classes) {
-	Common::String specialPower = Res.FIELD_NONE;
-	Spells &spells = *getVm()->_spells;
-
-	if (item._id) {
-		specialPower = spells._spellNames[Res.MISC_SPELL_INDEX[item._id]];
-	}
-
-	return Common::String::format(Res.ITEM_DETAILS, classes.c_str(),
-		Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE,
-		Res.FIELD_NONE, specialPower.c_str());
-}
-/*------------------------------------------------------------------------*/
-
-InventoryItemsGroup::InventoryItemsGroup(InventoryItems &weapons, InventoryItems &armor,
-		InventoryItems &accessories, InventoryItems &misc) {
-	_itemSets[0] = &weapons;
-	_itemSets[1] = &armor;
-	_itemSets[2] = &accessories;
-	_itemSets[3] = &misc;
-}
-
-InventoryItems &InventoryItemsGroup::operator[](ItemCategory category) {
-	return *_itemSets[category];
-}
-
-void InventoryItemsGroup::breakAllItems() {
-	for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) {
-		if ((*_itemSets[0])[idx]._id != 34) {
-			(*_itemSets[0])[idx]._bonusFlags |= ITEMFLAG_BROKEN;
-			(*_itemSets[0])[idx]._frame = 0;
-		}
-
-		(*_itemSets[1])[idx]._bonusFlags |= ITEMFLAG_BROKEN;
-		(*_itemSets[2])[idx]._bonusFlags |= ITEMFLAG_BROKEN;
-		(*_itemSets[3])[idx]._bonusFlags |= ITEMFLAG_BROKEN;
-		(*_itemSets[1])[idx]._frame = 0;
-		(*_itemSets[2])[idx]._frame = 0;
-	}
+AttributePair::AttributePair() {
+	_temporary = _permanent = 0;
 }
 
-/*------------------------------------------------------------------------*/
-
-
 void AttributePair::synchronize(Common::Serializer &s) {
 	s.syncAsByte(_permanent);
 	s.syncAsByte(_temporary);
@@ -678,12 +37,6 @@ void AttributePair::synchronize(Common::Serializer &s) {
 
 /*------------------------------------------------------------------------*/
 
-AttributePair::AttributePair() {
-	_temporary = _permanent = 0;
-}
-
-/*------------------------------------------------------------------------*/
-
 Character::Character():
 		_weapons(this), _armor(this), _accessories(this), _misc(this),
 		_items(_weapons, _armor, _accessories, _misc) {
diff --git a/engines/xeen/character.h b/engines/xeen/character.h
index 649da7e..05a61c3 100644
--- a/engines/xeen/character.h
+++ b/engines/xeen/character.h
@@ -28,6 +28,7 @@
 #include "common/rect.h"
 #include "common/serializer.h"
 #include "xeen/combat.h"
+#include "xeen/item.h"
 #include "xeen/sprites.h"
 
 namespace Xeen {
@@ -47,11 +48,6 @@ enum BonusFlags {
 	ITEMFLAG_BONUS_MASK = 0xBF, ITEMFLAG_CURSED = 0x40, ITEMFLAG_BROKEN = 0x80
 };
 
-enum ItemCategory {
-	CATEGORY_WEAPON = 0, CATEGORY_ARMOR = 1, CATEGORY_ACCESSORY = 2, CATEGORY_MISC = 3,
-	NUM_ITEM_CATEGORIES = 4
-};
-
 enum Sex { MALE = 0, FEMALE = 1, YES_PLEASE = 2 };
 
 enum Race { HUMAN = 0, ELF = 1, DWARF = 2, GNOME = 3, HALF_ORC = 4 };
@@ -83,222 +79,11 @@ enum Condition {
 	NO_CONDITION = 16
 };
 
-enum AttributeCategory {
-	ATTR_MIGHT = 0, ATTR_INTELLECT = 1, ATTR_PERSONALITY = 2, ATTR_SPEED = 3,
-	ATTR_ACCURACY = 4, ATTR_LUCK = 5, ATTR_HIT_POINTS = 6, ATTR_SPELL_POINTS = 7,
-	ATTR_ARMOR_CLASS = 8, ATTR_THIEVERY  = 9
-};
-
 enum QuickAction {
 	QUICK_ATTACK = 0, QUICK_SPELL = 1, QUICK_BLOCK = 2, QUICK_RUN = 3
 };
 
 class XeenEngine;
-class Character;
-
-class XeenItem {
-public:
-	int _material;
-	uint _id;
-	int _bonusFlags;
-	int _frame;
-public:
-	/**
-	 * Return the name of the item
-	 */
-	static const char *getItemName(ItemCategory category, uint id);
-public:
-	XeenItem();
-
-	/**
-	 * Clear the data for the item
-	 */
-	void clear();
-
-	/**
-	 * Returns true if no item is set
-	 */
-	bool empty() const { return _id != 0; }
-
-	/**
-	 * Synchronizes the data for the item
-	 */
-	void synchronize(Common::Serializer &s);
-
-	/**
-	 * Gets the elemental category for the item
-	 */
-	ElementalCategory getElementalCategory() const;
-
-	/**
-	 * Gets the attribute category for the item
-	 */
-	AttributeCategory getAttributeCategory() const;
-};
-
-class InventoryItems : public Common::Array<XeenItem> {
-protected:
-	Character *_character;
-	ItemCategory _category;
-	const char **_names;
-
-	XeenEngine *getVm();
-	void equipError(int itemIndex1, ItemCategory category1, int itemIndex2,
-		ItemCategory category2);
-
-	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes) = 0;
-public:
-	InventoryItems(Character *character, ItemCategory category);
-	virtual ~InventoryItems() {}
-
-	/**
-	 * Clears the set of items
-	 */
-	void clear();
-
-	/**
-	 * Return whether a given item passes class-based usage restrictions
-	 */
-	bool passRestrictions(int itemId, bool showError) const;
-
-	/**
-	 * Return the bare name of a given inventory item
-	 */
-	Common::String getName(int itemIndex);
-
-	virtual Common::String getFullDescription(int itemIndex, int displayNum = 15) = 0;
-
-	/**
-	 * Returns the identified details for an item
-	 */
-	Common::String getIdentifiedDetails(int itemIndex);
-
-	/**
-	 * Discard an item from the inventory
-	 */
-	bool discardItem(int itemIndex);
-
-	/**
-	 * Equips an item
-	 */
-	virtual void equipItem(int itemIndex) {}
-
-	/**
-	 * Un-equips the given item
-	 */
-	void removeItem(int itemIndex);
-
-	/**
-	 * Sorts the items list, removing any empty item slots to the end of the array
-	 */
-	void sort();
-
-	/**
-	 * Enchants an item
-	 */
-	virtual void enchantItem(int itemIndex, int amount);
-
-	/**
-	 * Return if the given inventory items list is full
-	 */
-	bool isFull() const;
-};
-
-class WeaponItems: public InventoryItems {
-protected:
-	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
-public:
-	WeaponItems(Character *character) : InventoryItems(character, CATEGORY_WEAPON) {}
-	virtual ~WeaponItems() {}
-
-	/**
-	 * Equip a given weapon
-	 */
-	virtual void equipItem(int itemIndex);
-
-	/**
-	 * Assembles a full lines description for a specified item for use in
-	 * the Items dialog
-	 */
-	virtual Common::String getFullDescription(int itemIndex, int displayNum);
-
-	/**
-	 * Enchants a weapon
-	 */
-	virtual void enchantItem(int itemIndex, int amount);
-};
-
-class ArmorItems : public InventoryItems {
-protected:
-	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
-public:
-	ArmorItems(Character *character) : InventoryItems(character, CATEGORY_ARMOR) {}
-	virtual ~ArmorItems() {}
-
-	/**
-	 * Equip a given piece of armor
-	 */
-	virtual void equipItem(int itemIndex);
-
-	/**
-	 * Assembles a full lines description for a specified item for use in
-	 * the Items dialog
-	 */
-	virtual Common::String getFullDescription(int itemIndex, int displayNum);
-
-	/**
-	 * Enchants an armor
-	 */
-	virtual void enchantItem(int itemIndex, int amount);
-};
-
-class AccessoryItems : public InventoryItems {
-protected:
-	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
-public:
-	AccessoryItems(Character *character) : InventoryItems(character, CATEGORY_ACCESSORY) {}
-
-	/**
-	 * Equip a given accessory
-	 */
-	virtual void equipItem(int itemIndex);
-
-	/**
-	 * Assembles a full lines description for a specified item for use in
-	 * the Items dialog
-	 */
-	virtual Common::String getFullDescription(int itemIndex, int displayNum);
-};
-
-class MiscItems : public InventoryItems {
-protected:
-	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
-public:
-	MiscItems(Character *character) : InventoryItems(character, CATEGORY_MISC) {}
-	virtual ~MiscItems() {}
-
-	/**
-	 * Assembles a full lines description for a specified item for use in
-	 * the Items dialog
-	 */
-	virtual Common::String getFullDescription(int itemIndex, int displayNum);
-};
-
-class InventoryItemsGroup {
-private:
-	InventoryItems *_itemSets[4];
-public:
-	InventoryItemsGroup(InventoryItems &weapons, InventoryItems &armor,
-		InventoryItems &accessories, InventoryItems &misc);
-
-	InventoryItems &operator[](ItemCategory category);
-
-	/**
-	 * Breaks all the items in a given character's inventory
-	 */
-	void breakAllItems();
-};
-
 
 class AttributePair {
 public:
diff --git a/engines/xeen/item.cpp b/engines/xeen/item.cpp
new file mode 100644
index 0000000..722c249
--- /dev/null
+++ b/engines/xeen/item.cpp
@@ -0,0 +1,658 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "xeen/item.h"
+#include "xeen/resources.h"
+#include "xeen/xeen.h"
+#include "xeen/dialogs/dialogs_query.h"
+
+namespace Xeen {
+
+XeenItem::XeenItem() {
+	clear();
+}
+
+void XeenItem::clear() {
+	_material = _id = _bonusFlags = 0;
+	_frame = 0;
+}
+
+void XeenItem::synchronize(Common::Serializer &s) {
+	s.syncAsByte(_material);
+	s.syncAsByte(_id);
+	s.syncAsByte(_bonusFlags);
+	s.syncAsByte(_frame);
+}
+
+ElementalCategory XeenItem::getElementalCategory() const {
+	int idx;
+	for (idx = 0; Res.ELEMENTAL_CATEGORIES[idx] < _material; ++idx)
+		;
+
+	return (ElementalCategory)idx;
+}
+
+AttributeCategory XeenItem::getAttributeCategory() const {
+	int m = _material - 59;
+	int idx;
+	for (idx = 0; Res.ATTRIBUTE_CATEGORIES[idx] < m; ++idx)
+		;
+
+	return (AttributeCategory)idx;
+}
+
+const char *XeenItem::getItemName(ItemCategory category, uint id) {
+	if (id < 82)
+		return Res.ITEM_NAMES[category][id];
+
+	switch (category) {
+	case CATEGORY_WEAPON:
+		return Res.QUEST_ITEM_NAMES[id - 82];
+
+	case CATEGORY_ARMOR:
+		return Res.QUEST_ITEM_NAMES[id - 82 + 35];
+
+	case CATEGORY_ACCESSORY:
+		return Res.QUEST_ITEM_NAMES[id - 82 + 35 + 14];
+
+	default:
+		return Res.QUEST_ITEM_NAMES[id - 82 + 35 + 14 + 11];
+	}
+}
+
+/*------------------------------------------------------------------------*/
+
+InventoryItems::InventoryItems(Character *character, ItemCategory category):
+		_character(character), _category(category) {
+	resize(INV_ITEMS_TOTAL);
+
+	_names = Res.ITEM_NAMES[category];
+}
+
+void InventoryItems::clear() {
+	for (uint idx = 0; idx < size(); ++idx)
+		operator[](idx).clear();
+}
+
+bool InventoryItems::passRestrictions(int itemId, bool showError) const {
+	CharacterClass charClass = _character->_class;
+
+	switch (charClass) {
+	case CLASS_KNIGHT:
+	case CLASS_PALADIN:
+		return true;
+
+	case CLASS_ARCHER:
+	case CLASS_CLERIC:
+	case CLASS_SORCERER:
+	case CLASS_ROBBER:
+	case CLASS_NINJA:
+	case CLASS_BARBARIAN:
+	case CLASS_DRUID:
+	case CLASS_RANGER: {
+		if (!(Res.ITEM_RESTRICTIONS[itemId + Res.RESTRICTION_OFFSETS[_category]] &
+			(1 << (charClass - CLASS_ARCHER))))
+			return true;
+		break;
+	}
+
+	default:
+		break;
+	}
+
+	Common::String name = _names[itemId];
+	if (showError) {
+		Common::String msg = Common::String::format(Res.NOT_PROFICIENT,
+			Res.CLASS_NAMES[charClass], name.c_str());
+		ErrorScroll::show(Party::_vm, msg, WT_FREEZE_WAIT);
+	}
+
+	return false;
+}
+
+Common::String InventoryItems::getName(int itemIndex) {
+	int id = operator[](itemIndex)._id;
+	return _names[id];
+}
+
+Common::String InventoryItems::getIdentifiedDetails(int itemIndex) {
+	XeenItem &item = operator[](itemIndex);
+
+	Common::String classes;
+	for (int charClass = CLASS_KNIGHT; charClass <= CLASS_RANGER; ++charClass) {
+		if (passRestrictions(charClass, true)) {
+			const char *const name = Res.CLASS_NAMES[charClass];
+			classes += name[0];
+			classes += name[1];
+			classes += " ";
+		}
+	}
+	if (classes.size() == 30)
+		classes = Res.ALL;
+
+	return getAttributes(item, classes);
+}
+
+bool InventoryItems::discardItem(int itemIndex) {
+	XeenItem &item = operator[](itemIndex);
+	XeenEngine *vm = Party::_vm;
+
+	if (item._bonusFlags & ITEMFLAG_CURSED) {
+		ErrorScroll::show(vm, Res.CANNOT_DISCARD_CURSED_ITEM);
+	} else {
+		Common::String itemDesc = getFullDescription(itemIndex, 4);
+		Common::String msg = Common::String::format(Res.PERMANENTLY_DISCARD, itemDesc.c_str());
+
+		if (Confirm::show(vm, msg)) {
+			operator[](itemIndex).clear();
+			sort();
+
+			return true;
+		}
+	}
+
+	return true;
+}
+
+void InventoryItems::sort() {
+	for (uint idx = 0; idx < size(); ++idx) {
+		if (operator[](idx)._id == 0) {
+			// Found empty slot
+			operator[](idx).clear();
+
+			// Scan through the rest of the list to find any item
+			for (uint idx2 = idx + 1; idx2 < size(); ++idx2) {
+				if (operator[](idx2)._id) {
+					// Found an item, so move it into the blank slot
+					operator[](idx) = operator[](idx2);
+					operator[](idx2).clear();
+					break;
+				}
+			}
+		}
+	}
+}
+
+void InventoryItems::removeItem(int itemIndex) {
+	XeenItem &item = operator[](itemIndex);
+	XeenEngine *vm = Party::_vm;
+
+	if (item._bonusFlags & ITEMFLAG_CURSED)
+		ErrorScroll::show(vm, Res.CANNOT_REMOVE_CURSED_ITEM);
+	else
+		item._frame = 0;
+}
+
+XeenEngine *InventoryItems::getVm() {
+	return Party::_vm;
+}
+
+void InventoryItems::equipError(int itemIndex1, ItemCategory category1, int itemIndex2,
+		ItemCategory category2) {
+	XeenEngine *vm = Party::_vm;
+
+	if (itemIndex1 >= 0) {
+		Common::String itemName1 = _character->_items[category1].getName(itemIndex1);
+		Common::String itemName2 = _character->_items[category2].getName(itemIndex2);
+
+		MessageDialog::show(vm, Common::String::format(Res.REMOVE_X_TO_EQUIP_Y,
+			itemName1.c_str(), itemName2.c_str()));
+	} else {
+		MessageDialog::show(vm, Common::String::format(Res.EQUIPPED_ALL_YOU_CAN,
+			(itemIndex1 == -1) ? Res.RING : Res.MEDAL));
+	}
+}
+
+void InventoryItems::enchantItem(int itemIndex, int amount) {
+	XeenEngine *vm = Party::_vm;
+	vm->_sound->playFX(21);
+	ErrorScroll::show(vm, Common::String::format(Res.NOT_ENCHANTABLE, Res.SPELL_FAILED));
+}
+
+bool InventoryItems::isFull() const {
+	return operator[](size() - 1)._id != 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+void WeaponItems::equipItem(int itemIndex) {
+	XeenItem &item = operator[](itemIndex);
+
+	if (item._id <= 17) {
+		if (passRestrictions(item._id, false)) {
+			for (uint idx = 0; idx < size(); ++idx) {
+				XeenItem &i = operator[](idx);
+				if (i._frame == 13 || i._frame == 1) {
+					equipError(itemIndex, CATEGORY_WEAPON, idx, CATEGORY_WEAPON);
+					return;
+				}
+			}
+
+			item._frame = 1;
+		}
+	} else if (item._id >= 30 && item._id <= 33) {
+		if (passRestrictions(item._id, false)) {
+			for (uint idx = 0; idx < size(); ++idx) {
+				XeenItem &i = operator[](idx);
+				if (i._frame == 4) {
+					equipError(itemIndex, CATEGORY_WEAPON, idx, CATEGORY_WEAPON);
+					return;
+				}
+			}
+
+			item._frame = 4;
+		}
+	} else {
+		if (passRestrictions(item._id, false)) {
+			for (uint idx = 0; idx < size(); ++idx) {
+				XeenItem &i = operator[](idx);
+				if (i._frame == 13 || i._frame == 1) {
+					equipError(itemIndex, CATEGORY_WEAPON, idx, CATEGORY_WEAPON);
+					return;
+				}
+			}
+
+			for (uint idx = 0; idx < _character->_armor.size(); ++idx) {
+				XeenItem &i = _character->_armor[idx];
+				if (i._frame == 2) {
+					equipError(itemIndex, CATEGORY_WEAPON, idx, CATEGORY_ARMOR);
+					return;
+				}
+			}
+
+			item._frame = 13;
+		}
+	}
+}
+
+Common::String WeaponItems::getFullDescription(int itemIndex, int displayNum) {
+	XeenItem &i = operator[](itemIndex);
+	Resources &res = *getVm()->_resources;
+
+	return Common::String::format("\f%02u%s%s%s\f%02u%s%s%s", displayNum,
+		!i._bonusFlags ? res._maeNames[i._material].c_str() : "",
+		(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
+		(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
+		displayNum,
+		Res.WEAPON_NAMES[i._id],
+		!i._bonusFlags ? "" : Res.BONUS_NAMES[i._bonusFlags & ITEMFLAG_BONUS_MASK],
+		(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
+			!i._bonusFlags ? "\b " : ""
+	);
+}
+
+void WeaponItems::enchantItem(int itemIndex, int amount) {
+	Sound &sound = *getVm()->_sound;
+	XeenItem &item = operator[](itemIndex);
+	Character tempCharacter;
+
+	if (item._material == 0 && item._bonusFlags == 0 && item._id != 34) {
+		tempCharacter.makeItem(amount, 0, 1);
+		XeenItem &tempItem = tempCharacter._weapons[0];
+
+		item._material = tempItem._material;
+		item._bonusFlags = tempItem._bonusFlags;
+		sound.playFX(19);
+	} else {
+		InventoryItems::enchantItem(itemIndex, amount);
+	}
+}
+
+Common::String WeaponItems::getAttributes(XeenItem &item, const Common::String &classes) {
+	Common::String attrBonus, elemDamage, physDamage, toHit, specialPower;
+	attrBonus = elemDamage = physDamage = toHit = specialPower = Res.FIELD_NONE;
+
+	// First calculate physical damage
+	int minVal = Res.WEAPON_DAMAGE_BASE[item._id];
+	int maxVal = minVal * Res.WEAPON_DAMAGE_MULTIPLIER[item._id];
+
+	if (item._material >= 37 && item._material <= 58) {
+		minVal += Res.METAL_DAMAGE[item._material - 37];
+		maxVal += Res.METAL_DAMAGE[item._material - 37];
+		toHit = Common::String::format("%+d", Res.METAL_DAMAGE_PERCENT[item._material - 37]);
+	}
+
+	physDamage = Common::String::format(Res.DAMAGE_X_TO_Y, minVal, maxVal);
+
+	// Next handle elemental/attribute damage
+	if (item._material < 37) {
+		int damage = Res.ELEMENTAL_DAMAGE[item._material];
+		if (damage > 0) {
+			ElementalCategory elemCategory = item.getElementalCategory();
+			elemDamage = Common::String::format(Res.ELEMENTAL_XY_DAMAGE,
+				damage, Res.ELEMENTAL_NAMES[elemCategory]);
+		}
+	} else if (item._material >= 59) {
+		int bonus = Res.ATTRIBUTE_BONUSES[item._material - 59];
+		AttributeCategory attrCategory = item.getAttributeCategory();
+		attrBonus = Common::String::format(Res.ATTR_XY_BONUS, bonus,
+			Res.ATTRIBUTE_NAMES[attrCategory]);
+	}
+
+	// Handle weapon effective against
+	int effective = item._bonusFlags & ITEMFLAG_BONUS_MASK;
+	if (effective) {
+		specialPower = Common::String::format(Res.EFFECTIVE_AGAINST,
+			Res.EFFECTIVENESS_NAMES[effective]);
+	}
+
+	return Common::String::format(Res.ITEM_DETAILS, classes.c_str(),
+		toHit.c_str(), physDamage.c_str(), elemDamage.c_str(),
+		Res.FIELD_NONE, Res.FIELD_NONE, attrBonus.c_str(), specialPower.c_str()
+	);
+}
+
+/*------------------------------------------------------------------------*/
+
+void ArmorItems::equipItem(int itemIndex) {
+	XeenItem &item = operator[](itemIndex);
+
+	if (item._id <= 7) {
+		if (passRestrictions(item._id, false)) {
+			for (uint idx = 0; idx < size(); ++idx) {
+				XeenItem &i = operator[](idx);
+				if (i._frame == 9) {
+					equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
+					return;
+				}
+			}
+
+			item._frame = 3;
+		}
+	} else if (item._id == 8) {
+		if (passRestrictions(item._id, false)) {
+			for (uint idx = 0; idx < size(); ++idx) {
+				XeenItem &i = operator[](idx);
+				if (i._frame == 2) {
+					equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
+					return;
+				}
+			}
+
+			for (uint idx = 0; idx < _character->_weapons.size(); ++idx) {
+				XeenItem &i = _character->_weapons[idx];
+				if (i._frame == 13) {
+					equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_WEAPON);
+					return;
+				}
+			}
+
+			item._frame = 2;
+		}
+	} else if (item._id == 9) {
+		for (uint idx = 0; idx < size(); ++idx) {
+			XeenItem &i = operator[](idx);
+			if (i._frame == 5) {
+				equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
+				return;
+			}
+		}
+
+		item._frame = 5;
+	} else if (item._id == 10) {
+		for (uint idx = 0; idx < size(); ++idx) {
+			XeenItem &i = operator[](idx);
+			if (i._frame == 9) {
+				equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
+				return;
+			}
+		}
+
+		item._frame = 9;
+	} else if (item._id <= 12) {
+		for (uint idx = 0; idx < size(); ++idx) {
+			XeenItem &i = operator[](idx);
+			if (i._frame == 10) {
+				equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
+				return;
+			}
+		}
+
+		item._frame = 10;
+	} else {
+		for (uint idx = 0; idx < size(); ++idx) {
+			XeenItem &i = operator[](idx);
+			if (i._frame == 6) {
+				equipError(itemIndex, CATEGORY_ARMOR, idx, CATEGORY_ARMOR);
+				return;
+			}
+		}
+
+		item._frame = 6;
+	}
+}
+
+Common::String ArmorItems::getFullDescription(int itemIndex, int displayNum) {
+	XeenItem &i = operator[](itemIndex);
+	Resources &res = *getVm()->_resources;
+
+	return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
+		!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
+		(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
+		(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
+		displayNum,
+		Res.ARMOR_NAMES[i._id],
+		(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
+			!i._bonusFlags ? "\b " : ""
+	);
+}
+
+void ArmorItems::enchantItem(int itemIndex, int amount) {
+	Sound &sound = *getVm()->_sound;
+	XeenItem &item = operator[](itemIndex);
+	Character tempCharacter;
+
+	if (item._material == 0 && item._bonusFlags == 0) {
+		tempCharacter.makeItem(amount, 0, 2);
+		XeenItem &tempItem = tempCharacter._armor[0];
+
+		item._material = tempItem._material;
+		item._bonusFlags = tempItem._bonusFlags;
+		sound.playFX(19);
+	} else {
+		InventoryItems::enchantItem(itemIndex, amount);
+	}
+}
+
+Common::String ArmorItems::getAttributes(XeenItem &item, const Common::String &classes) {
+	Common::String elemResist, attrBonus, acBonus;
+	elemResist = attrBonus = acBonus = Res.FIELD_NONE;
+
+	if (item._material < 36) {
+		int resistence = Res.ELEMENTAL_RESISTENCES[item._material];
+		if (resistence > 0) {
+			int eCategory = ELEM_FIRE;
+			while (eCategory < ELEM_MAGIC && Res.ELEMENTAL_CATEGORIES[eCategory] < item._material)
+				++eCategory;
+
+			elemResist = Common::String::format(Res.ATTR_XY_BONUS, resistence,
+				Res.ELEMENTAL_NAMES[eCategory]);
+		}
+	} else if (item._material >= 59) {
+		int bonus = Res.ATTRIBUTE_BONUSES[item._material - 59];
+		AttributeCategory aCategory = item.getAttributeCategory();
+		attrBonus = Common::String::format(Res.ATTR_XY_BONUS, bonus,
+			Res.ATTRIBUTE_NAMES[aCategory]);
+	}
+
+	int strength = Res.ARMOR_STRENGTHS[item._id];
+	if (item._material >= 37 && item._material <= 58) {
+		strength += Res.METAL_LAC[item._material - 37];
+	}
+	acBonus = Common::String::format("%+d", strength);
+
+	return Common::String::format(Res.ITEM_DETAILS, classes.c_str(),
+		Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE,
+		elemResist.c_str(), acBonus.c_str(), attrBonus.c_str(), Res.FIELD_NONE);
+}
+
+void AccessoryItems::equipItem(int itemIndex) {
+	XeenItem &item = operator[](itemIndex);
+
+	if (item._id == 1) {
+		int count = 0;
+		for (uint idx = 0; idx < size(); ++idx) {
+			XeenItem &i = operator[](idx);
+			if (i._frame == 8)
+				++count;
+		}
+
+		if (count <= 1)
+			item._frame = 8;
+		else
+			equipError(-1, CATEGORY_ACCESSORY, itemIndex, CATEGORY_ACCESSORY);
+	} else if (item._id == 2) {
+		for (uint idx = 0; idx < size(); ++idx) {
+			XeenItem &i = operator[](idx);
+			if (i._frame == 12) {
+				equipError(itemIndex, CATEGORY_ACCESSORY, idx, CATEGORY_ACCESSORY);
+				return;
+			}
+		}
+	} else if (item._id <= 7) {
+		int count = 0;
+		for (uint idx = 0; idx < size(); ++idx) {
+			XeenItem &i = operator[](idx);
+			if (i._frame == 7)
+				++count;
+		}
+
+		if (count <= 1)
+			item._frame = 7;
+		else
+			equipError(-2, CATEGORY_ACCESSORY, itemIndex, CATEGORY_ACCESSORY);
+	} else {
+		for (uint idx = 0; idx < size(); ++idx) {
+			XeenItem &i = operator[](idx);
+			if (i._frame == 11) {
+				equipError(itemIndex, CATEGORY_ACCESSORY, idx, CATEGORY_ACCESSORY);
+				return;
+			}
+		}
+
+		item._frame = 11;
+	}
+}
+
+Common::String AccessoryItems::getFullDescription(int itemIndex, int displayNum) {
+	XeenItem &i = operator[](itemIndex);
+	Resources &res = *getVm()->_resources;
+
+	return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
+		!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
+		(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
+		(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
+		displayNum,
+		Res.ARMOR_NAMES[i._id],
+		(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
+			!i._bonusFlags ? "\b " : ""
+	);
+}
+
+/*
+* Returns a text string listing all the stats/attributes of a given item
+*/
+Common::String AccessoryItems::getAttributes(XeenItem &item, const Common::String &classes) {
+	Common::String elemResist, attrBonus;
+	elemResist = attrBonus = Res.FIELD_NONE;
+
+	if (item._material < 36) {
+		int resistence = Res.ELEMENTAL_RESISTENCES[item._material];
+		if (resistence > 0) {
+			int eCategory = ELEM_FIRE;
+			while (eCategory < ELEM_MAGIC && Res.ELEMENTAL_CATEGORIES[eCategory] < item._material)
+				++eCategory;
+
+			elemResist = Common::String::format(Res.ATTR_XY_BONUS, resistence,
+				Res.ELEMENTAL_NAMES[eCategory]);
+		}
+	} else if (item._material >= 59) {
+		int bonus = Res.ATTRIBUTE_BONUSES[item._material - 59];
+		AttributeCategory aCategory = item.getAttributeCategory();
+		attrBonus = Common::String::format(Res.ATTR_XY_BONUS, bonus,
+			Res.ATTRIBUTE_NAMES[aCategory]);
+	}
+
+	return Common::String::format(Res.ITEM_DETAILS, classes.c_str(),
+		Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE,
+		elemResist.c_str(), Res.FIELD_NONE, attrBonus.c_str(), Res.FIELD_NONE);
+}
+
+/*------------------------------------------------------------------------*/
+
+Common::String MiscItems::getFullDescription(int itemIndex, int displayNum) {
+	XeenItem &i = operator[](itemIndex);
+	Resources &res = *getVm()->_resources;
+
+	return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
+		!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
+		(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
+		(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
+		displayNum,
+		Res.ARMOR_NAMES[i._id],
+		(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
+			!i._id ? "\b " : ""
+	);
+}
+
+Common::String MiscItems::getAttributes(XeenItem &item, const Common::String &classes) {
+	Common::String specialPower = Res.FIELD_NONE;
+	Spells &spells = *getVm()->_spells;
+
+	if (item._id) {
+		specialPower = spells._spellNames[Res.MISC_SPELL_INDEX[item._id]];
+	}
+
+	return Common::String::format(Res.ITEM_DETAILS, classes.c_str(),
+		Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE, Res.FIELD_NONE,
+		Res.FIELD_NONE, specialPower.c_str());
+}
+/*------------------------------------------------------------------------*/
+
+InventoryItemsGroup::InventoryItemsGroup(InventoryItems &weapons, InventoryItems &armor,
+		InventoryItems &accessories, InventoryItems &misc) {
+	_itemSets[0] = &weapons;
+	_itemSets[1] = &armor;
+	_itemSets[2] = &accessories;
+	_itemSets[3] = &misc;
+}
+
+InventoryItems &InventoryItemsGroup::operator[](ItemCategory category) {
+	return *_itemSets[category];
+}
+
+void InventoryItemsGroup::breakAllItems() {
+	for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) {
+		if ((*_itemSets[0])[idx]._id != 34) {
+			(*_itemSets[0])[idx]._bonusFlags |= ITEMFLAG_BROKEN;
+			(*_itemSets[0])[idx]._frame = 0;
+		}
+
+		(*_itemSets[1])[idx]._bonusFlags |= ITEMFLAG_BROKEN;
+		(*_itemSets[2])[idx]._bonusFlags |= ITEMFLAG_BROKEN;
+		(*_itemSets[3])[idx]._bonusFlags |= ITEMFLAG_BROKEN;
+		(*_itemSets[1])[idx]._frame = 0;
+		(*_itemSets[2])[idx]._frame = 0;
+	}
+}
+
+} // End of namespace Xeen
diff --git a/engines/xeen/item.h b/engines/xeen/item.h
new file mode 100644
index 0000000..2b6058c
--- /dev/null
+++ b/engines/xeen/item.h
@@ -0,0 +1,270 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef XEEN_ITEM_H
+#define XEEN_ITEM_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "xeen/combat.h"
+#include "xeen/sprites.h"
+
+namespace Xeen {
+
+#define INV_ITEMS_TOTAL 9
+
+class XeenEngine;
+
+enum ItemCategory {
+	CATEGORY_WEAPON = 0, CATEGORY_ARMOR = 1, CATEGORY_ACCESSORY = 2, CATEGORY_MISC = 3,
+	NUM_ITEM_CATEGORIES = 4
+};
+
+enum AttributeCategory {
+	ATTR_MIGHT = 0, ATTR_INTELLECT = 1, ATTR_PERSONALITY = 2, ATTR_SPEED = 3,
+	ATTR_ACCURACY = 4, ATTR_LUCK = 5, ATTR_HIT_POINTS = 6, ATTR_SPELL_POINTS = 7,
+	ATTR_ARMOR_CLASS = 8, ATTR_THIEVERY = 9
+};
+
+class XeenItem {
+public:
+	int _material;
+	uint _id;
+	int _bonusFlags;
+	int _frame;
+public:
+	/**
+	 * Return the name of the item
+	 */
+	static const char *getItemName(ItemCategory category, uint id);
+public:
+	XeenItem();
+
+	/**
+	 * Clear the data for the item
+	 */
+	void clear();
+
+	/**
+	 * Returns true if no item is set
+	 */
+	bool empty() const { return _id != 0; }
+
+	/**
+	 * Synchronizes the data for the item
+	 */
+	void synchronize(Common::Serializer &s);
+
+	/**
+	 * Gets the elemental category for the item
+	 */
+	ElementalCategory getElementalCategory() const;
+
+	/**
+	 * Gets the attribute category for the item
+	 */
+	AttributeCategory getAttributeCategory() const;
+};
+
+class InventoryItems : public Common::Array<XeenItem> {
+protected:
+	Character *_character;
+	ItemCategory _category;
+	const char **_names;
+
+	XeenEngine *getVm();
+	void equipError(int itemIndex1, ItemCategory category1, int itemIndex2,
+		ItemCategory category2);
+
+	/**
+	 ** Returns a text string listing all the stats/attributes of a given item
+	 */
+	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes) = 0;
+public:
+	InventoryItems(Character *character, ItemCategory category);
+	virtual ~InventoryItems() {}
+
+	/**
+	 * Clears the set of items
+	 */
+	void clear();
+
+	/**
+	 * Return whether a given item passes class-based usage restrictions
+	 */
+	bool passRestrictions(int itemId, bool showError) const;
+
+	/**
+	 * Return the bare name of a given inventory item
+	 */
+	Common::String getName(int itemIndex);
+
+	virtual Common::String getFullDescription(int itemIndex, int displayNum = 15) = 0;
+
+	/**
+	 * Returns the identified details for an item
+	 */
+	Common::String getIdentifiedDetails(int itemIndex);
+
+	/**
+	 * Discard an item from the inventory
+	 */
+	bool discardItem(int itemIndex);
+
+	/**
+	 * Equips an item
+	 */
+	virtual void equipItem(int itemIndex) {}
+
+	/**
+	 * Un-equips the given item
+	 */
+	void removeItem(int itemIndex);
+
+	/**
+	 * Sorts the items list, removing any empty item slots to the end of the array
+	 */
+	void sort();
+
+	/**
+	 * Enchants an item
+	 */
+	virtual void enchantItem(int itemIndex, int amount);
+
+	/**
+	 * Return if the given inventory items list is full
+	 */
+	bool isFull() const;
+};
+
+class WeaponItems: public InventoryItems {
+protected:
+	/**
+	 ** Returns a text string listing all the stats/attributes of a given item
+	 */
+	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
+public:
+	WeaponItems(Character *character) : InventoryItems(character, CATEGORY_WEAPON) {}
+	virtual ~WeaponItems() {}
+
+	/**
+	 * Equip a given weapon
+	 */
+	virtual void equipItem(int itemIndex);
+
+	/**
+	 * Assembles a full lines description for a specified item for use in
+	 * the Items dialog
+	 */
+	virtual Common::String getFullDescription(int itemIndex, int displayNum);
+
+	/**
+	 * Enchants a weapon
+	 */
+	virtual void enchantItem(int itemIndex, int amount);
+};
+
+class ArmorItems : public InventoryItems {
+protected:
+	/**
+	 ** Returns a text string listing all the stats/attributes of a given item
+	 */
+	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
+public:
+	ArmorItems(Character *character) : InventoryItems(character, CATEGORY_ARMOR) {}
+	virtual ~ArmorItems() {}
+
+	/**
+	 * Equip a given piece of armor
+	 */
+	virtual void equipItem(int itemIndex);
+
+	/**
+	 * Assembles a full lines description for a specified item for use in
+	 * the Items dialog
+	 */
+	virtual Common::String getFullDescription(int itemIndex, int displayNum);
+
+	/**
+	 * Enchants an armor
+	 */
+	virtual void enchantItem(int itemIndex, int amount);
+};
+
+class AccessoryItems : public InventoryItems {
+protected:
+	/**
+	 ** Returns a text string listing all the stats/attributes of a given item
+	 */
+	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
+public:
+	AccessoryItems(Character *character) : InventoryItems(character, CATEGORY_ACCESSORY) {}
+
+	/**
+	 * Equip a given accessory
+	 */
+	virtual void equipItem(int itemIndex);
+
+	/**
+	 * Assembles a full lines description for a specified item for use in
+	 * the Items dialog
+	 */
+	virtual Common::String getFullDescription(int itemIndex, int displayNum);
+};
+
+class MiscItems : public InventoryItems {
+protected:
+	/**
+	 ** Returns a text string listing all the stats/attributes of a given item
+	 */
+	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
+public:
+	MiscItems(Character *character) : InventoryItems(character, CATEGORY_MISC) {}
+	virtual ~MiscItems() {}
+
+	/**
+	 * Assembles a full lines description for a specified item for use in
+	 * the Items dialog
+	 */
+	virtual Common::String getFullDescription(int itemIndex, int displayNum);
+};
+
+class InventoryItemsGroup {
+private:
+	InventoryItems *_itemSets[4];
+public:
+	InventoryItemsGroup(InventoryItems &weapons, InventoryItems &armor,
+		InventoryItems &accessories, InventoryItems &misc);
+
+	InventoryItems &operator[](ItemCategory category);
+
+	/**
+	 * Breaks all the items in a given character's inventory
+	 */
+	void breakAllItems();
+};
+
+} // End of namespace Xeen
+
+#endif /* XEEN_CHARACTER_H */
diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk
index b3e0d9a..a988137 100644
--- a/engines/xeen/module.mk
+++ b/engines/xeen/module.mk
@@ -42,6 +42,7 @@ MODULE_OBJS := \
 	interface.o \
 	interface_minimap.o \
 	interface_scene.o \
+	item.o \
 	locations.o \
 	map.o \
 	party.o \


Commit: 44ea691154db466fe9a07addea302e7fa5b24cab
    https://github.com/scummvm/scummvm/commit/44ea691154db466fe9a07addea302e7fa5b24cab
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-03-10T07:08:05-05:00

Commit Message:
XEEN: Cleanup and comments for Combat class

Changed paths:
    engines/xeen/combat.cpp
    engines/xeen/combat.h
    engines/xeen/item.h


diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp
index 94d31bd..35283f2 100644
--- a/engines/xeen/combat.cpp
+++ b/engines/xeen/combat.cpp
@@ -1678,25 +1678,26 @@ void Combat::getWeaponDamage(Character &c, RangeType rangeType) {
 	_hitChanceBonus = 0;
 
 	for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) {
+		XeenItem &weapon = c._weapons[idx];
 		bool flag;
 		if (rangeType) {
-			flag = c._weapons[idx]._frame == 4;
+			flag = weapon._frame == 4;
 		} else {
-			flag = c._weapons[idx]._frame == 1 || c._weapons[idx]._frame == 13;
+			flag = weapon._frame == 1 || weapon._frame == 13;
 		}
 
 		if (flag) {
-			if (!(c._weapons[idx]._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED))) {
-				_attackWeapon = &c._weapons[idx];
+			if (!(weapon._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED))) {
+				_attackWeapon = &weapon;
 
-				if (c._weapons[idx]._material >= 37 && c._weapons[idx]._material < 59) {
-					_hitChanceBonus = Res.METAL_DAMAGE_PERCENT[c._weapons[idx]._material - 37];
-					_weaponDamage = Res.METAL_DAMAGE[c._weapons[idx]._material - 37];
+				if (weapon._material >= 37 && weapon._material < 59) {
+					_hitChanceBonus = Res.METAL_DAMAGE_PERCENT[weapon._material - 37];
+					_weaponDamage = Res.METAL_DAMAGE[weapon._material - 37];
 				}
 			}
 
 			_hitChanceBonus += party._heroism;
-			_attackWeaponId = c._weapons[idx]._id;
+			_attackWeaponId = weapon._id;
 			_weaponDice = Res.WEAPON_DAMAGE_BASE[_attackWeaponId];
 			_weaponDie = Res.WEAPON_DAMAGE_MULTIPLIER[_attackWeaponId];
 
diff --git a/engines/xeen/combat.h b/engines/xeen/combat.h
index efff2d5..e01d4df 100644
--- a/engines/xeen/combat.h
+++ b/engines/xeen/combat.h
@@ -26,6 +26,7 @@
 #include "common/scummsys.h"
 #include "common/rect.h"
 #include "xeen/files.h"
+#include "xeen/item.h"
 #include "xeen/sprites.h"
 
 namespace Xeen {
@@ -53,15 +54,6 @@ enum SpecialAttack {
 	SA_ERADICATE = 19, SA_AGING = 20, SA_DEATH = 21, SA_STONE = 22
 };
 
-enum ElementalCategory {
-	ELEM_FIRE = 0, ELEM_ELECTRICITY = 1, ELEM_COLD = 2,
-	ELEM_ACID_POISON = 3, ELEM_ENERGY = 4, ELEM_MAGIC = 5
-};
-
-enum RangeType {
-	RT_SINGLE = 0, RT_GROUP = 1, RT_ALL = 2, RT_HIT = 3
-};
-
 enum ShootType {
 	ST_0 = 0, ST_1 = 1
 };
@@ -119,16 +111,34 @@ class Combat {
 private:
 	XeenEngine *_vm;
 
+	/**
+	 * Handles the logic for attacking with a given amount of damage
+	 */
 	void attack2(int damage, RangeType rangeType);
 
+	/**
+	 * Returns true if the character successfully hits the monster
+	 */
 	bool hitMonster(Character &c, RangeType rangeType);
 
+	/**
+	 * Gets the damage a given character's equipped weapon will do
+	 */
 	void getWeaponDamage(Character &c, RangeType rangeType);
 
+	/**
+	 * Returns how much damage will be done to a monster
+	 */
 	int getMonsterDamage(Character &c);
 
+	/**
+	 * Gets the scale of damage, used for sprite display in the scene
+	 */
 	int getDamageScale(int v);
 
+	/**
+	 * Gets the current monster's damage resistance to the currently set damage type
+	 */
 	int getMonsterResistence(RangeType rangeType);
 
 	/**
@@ -190,6 +200,9 @@ public:
 	 */
 	void clearShooting();
 
+	/**
+	 * Gives damage to character or characters in the party
+	 */
 	void giveCharDamage(int damage, DamageType attackType, int charIndex);
 
 	/**
@@ -197,6 +210,9 @@ public:
 	 */
 	void doCharDamage(Character &c, int charNum, int monsterDataIndex);
 
+	/**
+	 * Handles moving monsters by a space between game turns
+	 */
 	void moveMonsters();
 
 	/**
@@ -204,6 +220,9 @@ public:
 	 */
 	void setupCombatParty();
 
+	/**
+	 * Sets up a table of speeds to determine the order in which characters and monsters fight
+	 */
 	void setSpeedTable();
 
 	/**
@@ -221,6 +240,9 @@ public:
 	 */
 	Common::String getMonsterDescriptions();
 
+	/**
+	 * Main method for characters to attack
+	 */
 	void attack(Character &c, RangeType rangeType);
 
 	/**
@@ -258,10 +280,16 @@ public:
 
 	void doMonsterTurn(int monsterId);
 
+	/**
+	 * Called when combat has ended
+	 */
 	void endAttack();
 
 	void monsterOvercome();
 
+	/**
+	 * Checks whether a given position on the map will stop a ranged attack
+	 */
 	int stopAttack(const Common::Point &diffPt);
 
 	/**
diff --git a/engines/xeen/item.h b/engines/xeen/item.h
index 2b6058c..6e81004 100644
--- a/engines/xeen/item.h
+++ b/engines/xeen/item.h
@@ -27,7 +27,6 @@
 #include "common/array.h"
 #include "common/rect.h"
 #include "common/serializer.h"
-#include "xeen/combat.h"
 #include "xeen/sprites.h"
 
 namespace Xeen {
@@ -35,6 +34,7 @@ namespace Xeen {
 #define INV_ITEMS_TOTAL 9
 
 class XeenEngine;
+class Character;
 
 enum ItemCategory {
 	CATEGORY_WEAPON = 0, CATEGORY_ARMOR = 1, CATEGORY_ACCESSORY = 2, CATEGORY_MISC = 3,
@@ -47,6 +47,15 @@ enum AttributeCategory {
 	ATTR_ARMOR_CLASS = 8, ATTR_THIEVERY = 9
 };
 
+enum RangeType {
+	RT_SINGLE = 0, RT_GROUP = 1, RT_ALL = 2, RT_HIT = 3
+};
+
+enum ElementalCategory {
+	ELEM_FIRE = 0, ELEM_ELECTRICITY = 1, ELEM_COLD = 2, ELEM_ACID_POISON = 3,
+	ELEM_ENERGY = 4, ELEM_MAGIC = 5
+};
+
 class XeenItem {
 public:
 	int _material;
@@ -85,6 +94,8 @@ public:
 	 * Gets the attribute category for the item
 	 */
 	AttributeCategory getAttributeCategory() const;
+
+	void getWeaponDamage(Character &c, RangeType rangeType);
 };
 
 class InventoryItems : public Common::Array<XeenItem> {
@@ -98,7 +109,7 @@ protected:
 		ItemCategory category2);
 
 	/**
-	 ** Returns a text string listing all the stats/attributes of a given item
+	 * Returns a text string listing all the stats/attributes of a given item
 	 */
 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes) = 0;
 public:
@@ -161,7 +172,7 @@ public:
 class WeaponItems: public InventoryItems {
 protected:
 	/**
-	 ** Returns a text string listing all the stats/attributes of a given item
+	 * Returns a text string listing all the stats/attributes of a given item
 	 */
 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
 public:
@@ -188,7 +199,7 @@ public:
 class ArmorItems : public InventoryItems {
 protected:
 	/**
-	 ** Returns a text string listing all the stats/attributes of a given item
+	 * Returns a text string listing all the stats/attributes of a given item
 	 */
 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
 public:
@@ -215,7 +226,7 @@ public:
 class AccessoryItems : public InventoryItems {
 protected:
 	/**
-	 ** Returns a text string listing all the stats/attributes of a given item
+	 * Returns a text string listing all the stats/attributes of a given item
 	 */
 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
 public:
@@ -236,7 +247,7 @@ public:
 class MiscItems : public InventoryItems {
 protected:
 	/**
-	 ** Returns a text string listing all the stats/attributes of a given item
+	 * Returns a text string listing all the stats/attributes of a given item
 	 */
 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
 public:
@@ -257,6 +268,9 @@ public:
 	InventoryItemsGroup(InventoryItems &weapons, InventoryItems &armor,
 		InventoryItems &accessories, InventoryItems &misc);
 
+	/**
+	 * Returns the inventory items for a given category
+	 */
 	InventoryItems &operator[](ItemCategory category);
 
 	/**





More information about the Scummvm-git-logs mailing list