aboutsummaryrefslogtreecommitdiff
path: root/engines/xeen/party.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/xeen/party.cpp')
-rw-r--r--engines/xeen/party.cpp190
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;