aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2015-02-21 14:34:49 -0500
committerPaul Gilbert2015-02-21 14:34:49 -0500
commitf49b1f9b4377af9693c5b1c1fdea162425c0c2b6 (patch)
treeabb62cebac94c2cd8091b8135b0e0381221c09b5 /engines
parentc5a98b0093330589dc269fe337a60cf0e1508785 (diff)
downloadscummvm-rg350-f49b1f9b4377af9693c5b1c1fdea162425c0c2b6.tar.gz
scummvm-rg350-f49b1f9b4377af9693c5b1c1fdea162425c0c2b6.tar.bz2
scummvm-rg350-f49b1f9b4377af9693c5b1c1fdea162425c0c2b6.zip
XEEN: Implemented giveTreasure
Diffstat (limited to 'engines')
-rw-r--r--engines/xeen/character.cpp8
-rw-r--r--engines/xeen/character.h5
-rw-r--r--engines/xeen/party.cpp150
-rw-r--r--engines/xeen/party.h5
-rw-r--r--engines/xeen/resources.cpp27
-rw-r--r--engines/xeen/resources.h12
6 files changed, 205 insertions, 2 deletions
diff --git a/engines/xeen/character.cpp b/engines/xeen/character.cpp
index 737c36ab30..e005a35f13 100644
--- a/engines/xeen/character.cpp
+++ b/engines/xeen/character.cpp
@@ -228,6 +228,14 @@ void InventoryItems::enchantItem(int itemIndex, int amount) {
ErrorScroll::show(vm, Common::String::format(NOT_ENCHANTABLE, SPELL_FAILED));
}
+/**
+ * Return if the given inventory items list is full
+ */
+bool InventoryItems::isFull() const {
+ return operator[](size() - 1)._id != 0;
+}
+
+
/*------------------------------------------------------------------------*/
/**
diff --git a/engines/xeen/character.h b/engines/xeen/character.h
index 372014f7fc..9e858da7fa 100644
--- a/engines/xeen/character.h
+++ b/engines/xeen/character.h
@@ -39,7 +39,8 @@ enum BonusFlags {
};
enum ItemCategory {
- CATEGORY_WEAPON = 0, CATEGORY_ARMOR = 1, CATEGORY_ACCESSORY = 2, CATEGORY_MISC = 3
+ 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 };
@@ -140,6 +141,8 @@ public:
void sort();
virtual void enchantItem(int itemIndex, int amount);
+
+ bool isFull() const;
};
class WeaponItems: public InventoryItems {
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index aede42464b..268dfcce15 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -60,6 +60,11 @@ void Roster::synchronize(Common::Serializer &s) {
Treasure::Treasure() {
_hasItems = false;
_gold = _gems = 0;
+
+ _categories[0] = &_weapons[0];
+ _categories[1] = &_armor[0];
+ _categories[2] = &_accessories[0];
+ _categories[3] = &_misc[0];
}
/*------------------------------------------------------------------------*/
@@ -564,8 +569,12 @@ void Party::moveToRunLocation() {
*/
void Party::giveTreasure() {
Combat &combat = *_vm->_combat;
+ EventsManager &events = *_vm->_events;
Interface &intf = *_vm->_interface;
+ Screen &screen = *_vm->_screen;
+ Scripts &scripts = *_vm->_scripts;
SoundManager &sound = *_vm->_sound;
+ Window &w = screen._windows[10];
if (!_treasure._gold && !_treasure._gems)
return;
@@ -584,7 +593,146 @@ void Party::giveTreasure() {
if (_treasure._gold || _treasure._gems)
sound.playFX(54);
- error("TODO");
+ events.clearEvents();
+ w.close();
+ w.open();
+ w.writeString(Common::String::format(PARTY_FOUND, _treasure._gold, _treasure._gems));
+ w.update();
+
+ if (_vm->_mode != MODE_COMBAT)
+ _vm->_mode = MODE_7;
+
+ if (arePacksFull())
+ ErrorScroll::show(_vm, BACKPACKS_FULL_PRESS_KEY, WT_NONFREEZED_WAIT);
+
+ for (int categoryNum = 0; categoryNum < NUM_ITEM_CATEGORIES; ++categoryNum) {
+ for (int itemNum = 0; itemNum < MAX_TREASURE_ITEMS; ++itemNum) {
+ if (arePacksFull()) {
+ if (_treasure._weapons[itemNum]._id == 34) {
+ // Important item, so clear a slot for it
+ _activeParty[0]._weapons[INV_ITEMS_TOTAL - 1].clear();
+ } else {
+ // Otherwise, clear all the remaining treasure items,
+ // since all the party's packs are full
+ for (int idx = 0; idx < MAX_TREASURE_ITEMS; ++idx) {
+ _treasure._weapons[idx].clear();
+ _treasure._armor[idx].clear();
+ _treasure._accessories[idx].clear();
+ _treasure._armor[idx].clear();
+ }
+ }
+ }
+
+ // If there's no treasure item to be distributed, skip to next slot
+ if (!_treasure._categories[categoryNum][itemNum]._id)
+ continue;
+
+ int charIndex = scripts._whoWill - 1;
+ if (charIndex >= 0 && charIndex < (int)_activeParty.size()) {
+ // Check the designated character first
+ Character &c = _activeParty[charIndex];
+ if (!c._items[(ItemCategory)categoryNum].isFull() && !c.isDisabledOrDead()) {
+ giveTreasureToCharacter(c, (ItemCategory)categoryNum, itemNum);
+ continue;
+ }
+
+ // Fall back on checking the entire conscious party
+ for (charIndex = 0; charIndex < (int)_activeParty.size(); ++charIndex) {
+ Character &c = _activeParty[charIndex];
+ if (!c._items[(ItemCategory)categoryNum].isFull() && !c.isDisabledOrDead()) {
+ giveTreasureToCharacter(c, (ItemCategory)categoryNum, itemNum);
+ break;
+ }
+ }
+ if (charIndex != (int)_activeParty.size())
+ continue;
+ }
+
+ // At this point, find an empty pack for any character, irrespective
+ // of whether the character is conscious or not
+ for (charIndex = 0; charIndex < (int)_activeParty.size(); ++charIndex) {
+ Character &c = _activeParty[charIndex];
+ if (!c._items[(ItemCategory)categoryNum].isFull() && !c.isDisabledOrDead()) {
+ giveTreasureToCharacter(c, (ItemCategory)categoryNum, itemNum);
+ continue;
+ }
+ }
+ }
+ }
+
+ w.writeString(HIT_A_KEY);
+ w.update();
+
+ do {
+ events.updateGameCounter();
+ intf.draw3d(true);
+
+ while (!events.isKeyMousePressed() && events.timeElapsed() < 1)
+ events.pollEventsAndWait();
+ } while (!_vm->shouldQuit() && events.timeElapsed() == 1);
+
+ if (_vm->_mode != MODE_COMBAT)
+ _vm->_mode = MODE_1;
+
+ w.close();
+ _gold += _treasure._gold;
+ _gems += _treasure._gems;
+ _treasure._gold = 0;
+ _treasure._gems = 0;
+
+ _treasure._hasItems = false;
+ for (int idx = 0; idx < MAX_TREASURE_ITEMS; ++idx) {
+ _treasure._weapons[idx].clear();
+ _treasure._armor[idx].clear();
+ _treasure._accessories[idx].clear();
+ _treasure._armor[idx].clear();
+ }
+
+ scripts._v2 = 1;
+}
+
+/**
+ * Returns true if all the packs for all the characters are full
+ */
+bool Party::arePacksFull() const {
+ uint total = 0;
+ for (uint idx = 0; idx < _activeParty.size(); ++idx) {
+ const Character &c = _activeParty[idx];
+ total += (c._weapons[INV_ITEMS_TOTAL - 1]._id != 0 ? 1 : 0)
+ + (c._armor[INV_ITEMS_TOTAL - 1]._id != 0 ? 1 : 0)
+ + (c._accessories[INV_ITEMS_TOTAL - 1]._id != 0 ? 1 : 0)
+ + (c._misc[INV_ITEMS_TOTAL - 1]._id != 0 ? 1 : 0);
+ }
+
+ return total == (_activeParty.size() * NUM_ITEM_CATEGORIES);
+}
+
+/**
+ * Give a treasure item to the given character's inventory
+ */
+void Party::giveTreasureToCharacter(Character &c, ItemCategory category, int itemIndex) {
+ EventsManager &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ SoundManager &sound = *_vm->_sound;
+ Window &w = screen._windows[10];
+ XeenItem &treasureItem = _treasure._categories[category][itemIndex];
+ sound.playFX(20);
+
+ if (treasureItem._id < 82) {
+ // Copy item into the character's inventory
+ c._items[category][INV_ITEMS_TOTAL - 1] = treasureItem;
+ c._items[category].sort();
+ }
+
+ w.writeString(GIVE_TREASURE_FORMATTING);
+ w.update();
+ events.ipause(5);
+
+ w.writeString(Common::String::format(X_FOUND_Y, c._name.c_str(),
+ ITEM_NAMES[category][treasureItem._id]));
+ w.update();
+
+ events.ipause(5);
}
} // End of namespace Xeen
diff --git a/engines/xeen/party.h b/engines/xeen/party.h
index 483476cb9c..b5e31f9405 100644
--- a/engines/xeen/party.h
+++ b/engines/xeen/party.h
@@ -65,6 +65,7 @@ public:
XeenItem _accessories[MAX_TREASURE_ITEMS];
XeenItem _armor[MAX_TREASURE_ITEMS];
XeenItem _weapons[MAX_TREASURE_ITEMS];
+ XeenItem *_categories[4];
bool _hasItems;
int _gems, _gold;
public:
@@ -76,6 +77,8 @@ class Party {
friend class InventoryItems;
private:
static XeenEngine *_vm;
+
+ void giveTreasureToCharacter(Character &c, ItemCategory category, int itemIndex);
public:
// Dynamic data that's saved
Direction _mazeDirection;
@@ -168,6 +171,8 @@ public:
void moveToRunLocation();
void giveTreasure();
+
+ bool arePacksFull() const;
};
} // End of namespace Xeen
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index da57a8085b..bcf408d893 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -1097,6 +1097,7 @@ const char *const BONUS_NAMES[7] = {
"", "Dragon Slayer", "Undead Eater", "Golem Smasher",
"Bug Zapper", "Monster Masher", "Beast Bopper"
};
+
const char *const WEAPON_NAMES[35] = {
nullptr, "long sword ", "short sword ", "broad sword ", "scimitar ",
"cutlass ", "sabre ", "club ", "hand axe ", "katana ", "nunchakas ",
@@ -1124,6 +1125,10 @@ const char *const MISC_NAMES[22] = {
"bogus", "bogus", "bogus", "bogus"
};
+const char *const *ITEM_NAMES[4] = {
+ &WEAPON_NAMES[0], &ARMOR_NAMES[0], &ACCESSORY_NAMES[0], &MISC_NAMES[0]
+};
+
const char *const ELEMENTAL_NAMES[6] = {
"Fire", "Elec", "Cold", "Acid/Poison", "Energy", "Magic"
};
@@ -1501,4 +1506,26 @@ const char *const CAST_SPELL_DETAILS =
"\v082Cost\x3r\t000%u/%u\x3l\n"
"Cur SP\x3r\t000%u\x1";
+const char *const PARTY_FOUND =
+ "\x3""cThe Party Found:\n"
+ "\n"
+ "\x3r\t000%lu Gold\n"
+ "%lu Gems";
+
+const char *const BACKPACKS_FULL_PRESS_KEY =
+ "\v007\f12Warning! BackPacks Full!\fd\n"
+ "Press a Key";
+
+const char *const HIT_A_KEY = "\x3l\v120\t000\x4""077\x3""c\f37Hit a key\f'd";
+
+const char *const GIVE_TREASURE_FORMATTING =
+ "\x3l\v060\t000\x4""077\n"
+ "\x4""077\n"
+ "\x4""077\n"
+ "\x4""077\n"
+ "\x4""077\n"
+ "\x4""077";
+
+const char *const X_FOUND_Y = "\v060\t000\x03c%s found: %s";
+
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index c61784475c..c98db7f0f9 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -384,6 +384,8 @@ extern const char *const WEAPON_NAMES[35];
extern const char *const ARMOR_NAMES[14];
extern const char *const ACCESSORY_NAMES[11];
extern const char *const MISC_NAMES[22];
+extern const char *const *ITEM_NAMES[4];
+
extern const char *const ELEMENTAL_NAMES[6];
extern const char *const ATTRIBUTE_NAMES[10];
extern const char *const EFFECTIVENESS_NAMES[7];
@@ -527,6 +529,16 @@ extern const char *SPELL_CAST_COMPONENTS[2];
extern const char *const CAST_SPELL_DETAILS;
+extern const char *const PARTY_FOUND;
+
+extern const char *const BACKPACKS_FULL_PRESS_KEY;
+
+extern const char *const HIT_A_KEY;
+
+extern const char *const GIVE_TREASURE_FORMATTING;
+
+extern const char *const X_FOUND_Y;
+
} // End of namespace Xeen
#endif /* XEEN_RESOURCES_H */