diff options
Diffstat (limited to 'engines/xeen/party.cpp')
-rw-r--r-- | engines/xeen/party.cpp | 190 |
1 files changed, 108 insertions, 82 deletions
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp index d92a4952cc..83763a863e 100644 --- a/engines/xeen/party.cpp +++ b/engines/xeen/party.cpp @@ -87,6 +87,12 @@ void Treasure::clear() { } } +void Treasure::reset() { + clear(); + _hasItems = false; + _gold = _gems = 0; +} + /*------------------------------------------------------------------------*/ const int BLACKSMITH_DATA1[4][4] = { @@ -212,9 +218,9 @@ Party::Party(XeenEngine *vm) { _holyBonus = 0; _heroism = 0; _difficulty = ADVENTURER; - _cloudsEnd = false; - _darkSideEnd = false; - _worldEnd = false; + _cloudsCompleted = false; + _darkSideCompleted = false; + _worldCompleted = false; _ctr24 = 0; _day = 0; _year = 0; @@ -299,9 +305,9 @@ void Party::synchronize(Common::Serializer &s) { _blacksmithWares.synchronize(s, 0); - s.syncAsUint16LE(_cloudsEnd); - s.syncAsUint16LE(_darkSideEnd); - s.syncAsUint16LE(_worldEnd); + s.syncAsUint16LE(_cloudsCompleted); + s.syncAsUint16LE(_darkSideCompleted); + s.syncAsUint16LE(_worldCompleted); s.syncAsUint16LE(_ctr24); s.syncAsUint16LE(_day); s.syncAsUint16LE(_year); @@ -518,7 +524,7 @@ void Party::addTime(int numMinutes) { _newDay = true; if (_newDay && _minutes >= 300) { - if (_vm->_mode != MODE_RECORD_EVENTS && _vm->_mode != MODE_17) { + if (_vm->_mode != MODE_SCRIPT_IN_PROGRESS && _vm->_mode != MODE_INTERACTIVE7) { resetTemps(); if (_rested || _vm->_mode == MODE_SLEEPING) { _rested = false; @@ -689,11 +695,8 @@ void Party::giveTreasure() { if (!_treasure._hasItems && !_treasure._gold && !_treasure._gems) return; - bool monstersPresent = false; - for (int idx = 0; idx < 26 && !monstersPresent; ++idx) - monstersPresent = combat._attackMonsters[idx] != -1; - - if (_vm->_mode != MODE_RECORD_EVENTS && monstersPresent) + bool monstersPresent = combat.areMonstersPresent(); + if (_vm->_mode != MODE_SCRIPT_IN_PROGRESS && monstersPresent) return; combat.clearShooting(); @@ -778,7 +781,7 @@ void Party::giveTreasure() { events.clearEvents(); if (_vm->_mode != MODE_COMBAT) - _vm->_mode = MODE_1; + _vm->_mode = MODE_INTERACTIVE; w.close(); _gold += _treasure._gold; @@ -821,9 +824,17 @@ void Party::giveTreasureToCharacter(Character &c, ItemCategory category, int ite w.update(); events.ipause(5); - const char *itemName = XeenItem::getItemName(category, (category == CATEGORY_MISC) ? - treasureItem._material : treasureItem._id); - w.writeString(Common::String::format(Res.X_FOUND_Y, c._name.c_str(), itemName)); + int index = (category == CATEGORY_MISC) ? treasureItem._material : treasureItem._id; + const char *itemName = XeenItem::getItemName(category, index); + + if (index >= (_vm->getGameID() == GType_Swords ? 88 : 82)) { + // Quest item, give an extra '*' prefix + Common::String format = Common::String::format("\f04 * \fd%s", itemName); + w.writeString(Common::String::format(Res.X_FOUND_Y, c._name.c_str(), format.c_str())); + } else { + w.writeString(Common::String::format(Res.X_FOUND_Y, c._name.c_str(), itemName)); + } + w.update(); c._items[category].sort(); events.ipause(8); @@ -886,7 +897,7 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int ps._tempAge -= takeVal; break; case 13: - ps._skills[THIEVERY] = 0; + ps._skills[takeVal] = 0; break; case 15: ps.setAward(takeVal, false); @@ -915,45 +926,46 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int case 20: _gameFlags[files._ccNum][takeVal] = false; break; - case 21: { - bool found = false; - for (int idx = 0; idx < 9; ++idx) { - if (takeVal < 35) { - if (ps._weapons[idx]._id == takeVal) { - ps._weapons[idx].clear(); - ps._weapons.sort(); - found = true; - break; - } - } else if (takeVal < 49) { - if (ps._armor[idx]._id == (takeVal - 35)) { - ps._armor[idx].clear(); - ps._armor.sort(); - found = true; - break; - } - } else if (takeVal < 60) { - if (ps._accessories[idx]._id == (takeVal - 49)) { - ps._accessories[idx].clear(); - ps._accessories.sort(); - found = true; - break; - } - } else if (takeVal < 82) { - if (ps._misc[idx]._material == ((int)takeVal - 60)) { - ps._misc[idx].clear(); - ps._misc.sort(); - found = true; - break; + case 21: + if (takeVal >= 82) { + _questItems[takeVal - 82]--; + } else { + bool found = false; + for (int idx = 0; idx < 9; ++idx) { + if (takeVal < 35) { + if (ps._weapons[idx]._id == takeVal) { + ps._weapons[idx].clear(); + ps._weapons.sort(); + found = true; + break; + } + } else if (takeVal < 49) { + if (ps._armor[idx]._id == (takeVal - 35)) { + ps._armor[idx].clear(); + ps._armor.sort(); + found = true; + break; + } + } else if (takeVal < 60) { + if (ps._accessories[idx]._id == (takeVal - 49)) { + ps._accessories[idx].clear(); + ps._accessories.sort(); + found = true; + break; + } + } else { + if (ps._misc[idx]._material == ((int)takeVal - 60)) { + ps._misc[idx].clear(); + ps._misc.sort(); + found = true; + break; + } } - } else { - _questItems[takeVal - 82]--; } + if (!found) + return true; } - if (!found) - return true; break; - } case 25: changeTime(takeVal); break; @@ -1156,14 +1168,16 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int ps._currentHp = 0; break; case 19: { + // Give spell to character SpellsCategory category = ps.getSpellsCategory(); - assert(category != SPELLCAT_INVALID); - for (int idx = 0; idx < SPELLS_PER_CLASS; ++idx) { - if (Res.SPELLS_ALLOWED[category][idx] == (int)giveVal) { - ps._spells[idx] = true; - intf.spellFX(&ps); - break; + if (category != SPELLCAT_INVALID) { + for (int idx = 0; idx < SPELLS_PER_CLASS; ++idx) { + if (Res.SPELLS_ALLOWED[category][idx] == (int)giveVal) { + ps._spells[idx] = true; + intf.spellFX(&ps); + break; + } } } break; @@ -1172,35 +1186,40 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int _gameFlags[files._ccNum][giveVal] = true; break; case 21: { + const uint WEAPONS_END = _vm->getGameID() != GType_Swords ? 35 : 41; + const uint ARMOR_END = _vm->getGameID() != GType_Swords ? 49 : 55; + const uint ACCESSORIES_END = _vm->getGameID() != GType_Swords ? 60 : 66; + const uint MISC_END = _vm->getGameID() != GType_Swords ? 82 : 88; + int idx; - if (giveVal >= 82) { - _questItems[giveVal - 82]++; + if (giveVal >= MISC_END) { + _questItems[giveVal - MISC_END]++; } - if (giveVal < 35 || giveVal >= 82) { - for (idx = 0; idx < 10 && _treasure._weapons[idx]._id; ++idx); - if (idx < 10) { + if (giveVal < WEAPONS_END || giveVal >= MISC_END) { + for (idx = 0; idx < MAX_TREASURE_ITEMS && !_treasure._weapons[idx].empty(); ++idx); + if (idx < MAX_TREASURE_ITEMS) { _treasure._weapons[idx]._id = giveVal; _treasure._hasItems = true; return false; } - } else if (giveVal < 49) { - for (idx = 0; idx < 10 && _treasure._armor[idx]._id; ++idx); - if (idx < 10) { - _treasure._armor[idx]._id = giveVal - 35; + } else if (giveVal < ARMOR_END) { + for (idx = 0; idx < MAX_TREASURE_ITEMS && !_treasure._armor[idx].empty(); ++idx); + if (idx < MAX_TREASURE_ITEMS) { + _treasure._armor[idx]._id = giveVal - WEAPONS_END; _treasure._hasItems = true; return false; } - } else if (giveVal < 60) { - for (idx = 0; idx < 10 && _treasure._accessories[idx]._id; ++idx); - if (idx < 10) { - _treasure._accessories[idx]._id = giveVal - 49; + } else if (giveVal < ACCESSORIES_END) { + for (idx = 0; idx < MAX_TREASURE_ITEMS && !_treasure._accessories[idx].empty(); ++idx); + if (idx < MAX_TREASURE_ITEMS) { + _treasure._accessories[idx]._id = giveVal - ARMOR_END; _treasure._hasItems = true; return false; } } else { - for (idx = 0; idx < 10 && _treasure._misc[idx]._material; ++idx); - if (idx < 10) { - _treasure._accessories[idx]._material = giveVal - 60; + for (idx = 0; idx < MAX_TREASURE_ITEMS && _treasure._misc[idx]._material; ++idx); + if (idx < MAX_TREASURE_ITEMS) { + _treasure._accessories[idx]._material = giveVal - ACCESSORIES_END; _treasure._hasItems = true; return false; } @@ -1412,16 +1431,16 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int _gold += _vm->getRandomNumber(1, giveVal); break; case 103: - assert(takeVal < 128); - _worldFlags[takeVal] = true; + assert(giveVal < 128); + _worldFlags[giveVal] = true; break; case 104: assert(giveVal < 30); _questFlags[files._ccNum][giveVal] = true; break; case 107: - assert(takeVal < 24); - _characterFlags[ps._rosterId][takeVal] = true; + assert(giveVal < 24); + _characterFlags[ps._rosterId][giveVal] = true; break; default: break; @@ -1437,9 +1456,10 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint Map &map = *g_vm->_map; Scripts &scripts = *g_vm->_scripts; Sound &sound = *g_vm->_sound; - Character &c = _itemsCharacter; - if (intf._objNumber != -1 && !scripts._animCounter) { + // WORKAROUND: Ali Baba's chest in Dark Side requires the character in the first slot to have Lockpicking. + // This is obviously a mistake, since the chest is meant to be opened via a password + if (intf._objNumber != -1 && !scripts._animCounter && !(files._ccNum && _mazeId == 63 && intf._objNumber == 15)) { MazeObject &obj = map._mobData._objects[intf._objNumber]; switch (obj._spriteId) { case 15: @@ -1449,7 +1469,8 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint case 16: case 58: - case 73: + case 73: { + Character &c = _activeParty[charId]; obj._frame = 1; if (obj._position.x != 20) { @@ -1480,6 +1501,11 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint return true; } } + break; + } + + default: + break; } } @@ -1497,7 +1523,7 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint break; case 66: - c.clear(); + _itemsCharacter.clear(); if (giveTake(0, 0, mode, val, charId)) return true; |