diff options
-rw-r--r-- | engines/xeen/character.h | 2 | ||||
-rw-r--r-- | engines/xeen/dialogs_char_info.cpp | 12 | ||||
-rw-r--r-- | engines/xeen/dialogs_error.cpp | 2 | ||||
-rw-r--r-- | engines/xeen/dialogs_items.cpp | 6 | ||||
-rw-r--r-- | engines/xeen/dialogs_spells.cpp | 2 | ||||
-rw-r--r-- | engines/xeen/interface.cpp | 139 | ||||
-rw-r--r-- | engines/xeen/interface.h | 2 | ||||
-rw-r--r-- | engines/xeen/interface_map.cpp | 2 | ||||
-rw-r--r-- | engines/xeen/map.cpp | 2 | ||||
-rw-r--r-- | engines/xeen/map.h | 9 | ||||
-rw-r--r-- | engines/xeen/party.cpp | 18 | ||||
-rw-r--r-- | engines/xeen/party.h | 3 | ||||
-rw-r--r-- | engines/xeen/resources.cpp | 9 | ||||
-rw-r--r-- | engines/xeen/resources.h | 6 | ||||
-rw-r--r-- | engines/xeen/spells.cpp | 2 | ||||
-rw-r--r-- | engines/xeen/xeen.h | 5 |
16 files changed, 200 insertions, 21 deletions
diff --git a/engines/xeen/character.h b/engines/xeen/character.h index af9e331fb5..c9a787cbc5 100644 --- a/engines/xeen/character.h +++ b/engines/xeen/character.h @@ -67,7 +67,7 @@ enum Skill { enum Condition { CURSED = 0, HEART_BROKEN = 1, WEAK = 2, POISONED = 3, - DISEASED = 4, INSANE = 5, IN_LOVE = 6, DRUNK = 7, SLEEP = 8, + DISEASED = 4, INSANE = 5, IN_LOVE = 6, DRUNK = 7, ASLEEP = 8, DEPRESSED = 9, CONFUSED = 10, PARALYZED = 11, UNCONSCIOUS = 12, DEAD = 13, STONED = 14, ERADICATED = 15, NO_CONDITION = 16 diff --git a/engines/xeen/dialogs_char_info.cpp b/engines/xeen/dialogs_char_info.cpp index 0c71bfb0be..36ca5bdd4c 100644 --- a/engines/xeen/dialogs_char_info.cpp +++ b/engines/xeen/dialogs_char_info.cpp @@ -47,7 +47,7 @@ void CharacterInfo::execute(int charIndex) { loadDrawStructs(); addButtons(); - Character *c = (oldMode != MODE_InCombat) ? &party._activeParty[charIndex] : party._combatParty[charIndex]; + Character *c = (oldMode != MODE_COMBAT) ? &party._activeParty[charIndex] : party._combatParty[charIndex]; intf.highlightChar(charIndex); Window &w = screen._windows[24]; w.open(); @@ -86,9 +86,9 @@ void CharacterInfo::execute(int charIndex) { case Common::KEYCODE_F5: case Common::KEYCODE_F6: _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)(oldMode == MODE_InCombat ? party._combatParty.size() : party._activeParty.size())) { + if (_buttonValue < (int)(oldMode == MODE_COMBAT ? party._combatParty.size() : party._activeParty.size())) { charIndex = _buttonValue; - c = (oldMode != MODE_InCombat) ? &party._activeParty[charIndex] : party._combatParty[charIndex]; + c = (oldMode != MODE_COMBAT) ? &party._activeParty[charIndex] : party._combatParty[charIndex]; } else { _vm->_mode = MODE_CHARACTER_INFO; } @@ -166,14 +166,14 @@ void CharacterInfo::execute(int charIndex) { w.update(); bool result = expandStat(_cursorCell, *c); - _vm->_mode = MODE_InCombat; + _vm->_mode = MODE_COMBAT; if (result) redrawFlag = true; break; } case Common::KEYCODE_e: - if (oldMode == MODE_InCombat) { + if (oldMode == MODE_COMBAT) { ErrorScroll::show(_vm, EXCHANGING_IN_COMBAT, WT_FREEZE_WAIT); } else { _vm->_mode = oldMode; @@ -185,7 +185,7 @@ void CharacterInfo::execute(int charIndex) { case Common::KEYCODE_i: _vm->_mode = oldMode; - _vm->_combat->_itemFlag = _vm->_mode == MODE_InCombat; + _vm->_combat->_itemFlag = _vm->_mode == MODE_COMBAT; c = ItemsDialog::show(_vm, c, ITEMMODE_CHAR_INFO); if (!c) { diff --git a/engines/xeen/dialogs_error.cpp b/engines/xeen/dialogs_error.cpp index 598af1ede7..4fe39db3b3 100644 --- a/engines/xeen/dialogs_error.cpp +++ b/engines/xeen/dialogs_error.cpp @@ -76,7 +76,7 @@ void ErrorDialog::execute(const Common::String &msg, ErrorWaitType waitType) { /*------------------------------------------------------------------------*/ void ErrorScroll::show(XeenEngine *vm, const Common::String &msg, ErrorWaitType waitType) { - Common::String s = Common::String::format("\x03c\v010\t000%s", msg.c_str()); + Common::String s = Common::String::format("\x3""c\v010\t000%s", msg.c_str()); ErrorDialog::show(vm, s, waitType); } diff --git a/engines/xeen/dialogs_items.cpp b/engines/xeen/dialogs_items.cpp index 83e0dd23a0..002a8fb946 100644 --- a/engines/xeen/dialogs_items.cpp +++ b/engines/xeen/dialogs_items.cpp @@ -336,11 +336,11 @@ Character *ItemsDialog::execute(Character *c, ItemsMode mode) { && party._mazeId != 0) { _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)(_vm->_mode == MODE_InCombat ? + if (_buttonValue < (int)(_vm->_mode == MODE_COMBAT ? party._combatParty.size() : party._activeParty.size())) { // Character number is valid redrawFlag = REDRAW_TEXT; - Character *newChar = _vm->_mode == MODE_InCombat ? + Character *newChar = _vm->_mode == MODE_COMBAT ? party._combatParty[_buttonValue] : &party._activeParty[_buttonValue]; if (mode == ITEMMODE_BLACKSMITH) { @@ -867,7 +867,7 @@ int ItemsDialog::doItemOptions(Character &c, int actionIndex, int itemIndex, Ite Condition condition = c.worstCondition(); switch (condition) { - case SLEEP: + case ASLEEP: case PARALYZED: case UNCONSCIOUS: case DEAD: diff --git a/engines/xeen/dialogs_spells.cpp b/engines/xeen/dialogs_spells.cpp index 4f86707554..dc05be611d 100644 --- a/engines/xeen/dialogs_spells.cpp +++ b/engines/xeen/dialogs_spells.cpp @@ -109,7 +109,7 @@ Character *SpellsScroll::execute(Character *c, int v2) { switch (_buttonValue) { case Common::KEYCODE_F1: case Common::KEYCODE_F6: - if (_vm->_mode != MODE_InCombat) { + if (_vm->_mode != MODE_COMBAT) { _buttonValue -= Common::KEYCODE_F1; if (_buttonValue < party._partyCount) { c = &party._activeParty[_buttonValue]; diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp index 34c7b548ff..c31ff844d9 100644 --- a/engines/xeen/interface.cpp +++ b/engines/xeen/interface.cpp @@ -25,6 +25,7 @@ #include "xeen/dialogs_error.h" #include "xeen/dialogs_automap.h" #include "xeen/dialogs_info.h" +#include "xeen/dialogs_query.h" #include "xeen/dialogs_quests.h" #include "xeen/dialogs_quick_ref.h" #include "xeen/resources.h" @@ -334,7 +335,7 @@ void Interface::setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool void Interface::charIconsPrint(bool updateFlag) { Screen &screen = *_vm->_screen; - bool stateFlag = _vm->_mode == MODE_InCombat; + bool stateFlag = _vm->_mode == MODE_COMBAT; _restoreSprites.draw(screen, 0, Common::Point(8, 149)); // Handle drawing the party faces @@ -711,6 +712,11 @@ void Interface::perform() { QuickReferenceDialog::show(_vm); break; + case Common::KEYCODE_r: + // Rest + rest(); + break; + case Common::KEYCODE_v: // Show the quests dialog Quests::show(_vm); @@ -949,4 +955,135 @@ bool Interface::checkMoveDirection(int key) { return true; } +void Interface::rest() { + EventsManager &events = *_vm->_events; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Screen &screen = *_vm->_screen; + SoundManager &sound = *_vm->_sound; + + map.cellFlagLookup(party._mazePosition); + + if ((map._currentCantRest || (map.mazeData()._mazeFlags & RESTRICTION_REST)) + && _vm->_mode != MODE_12) { + ErrorScroll::show(_vm, TOO_DANGEROUS_TO_REST, WT_NONFREEZED_WAIT); + } else { + // Check whether any character is in danger of dying + bool dangerFlag = false; + for (uint charIdx = 0; charIdx < party._activeParty.size(); ++charIdx) { + for (int attrib = MIGHT; attrib <= LUCK; ++attrib) { + if (party._activeParty[charIdx].getStat((Attribute)attrib) < 1) + dangerFlag = true; + } + } + + if (dangerFlag) { + if (!Confirm::show(_vm, SOME_CHARS_MAY_DIE)) + return; + } + + // Mark all the players as being asleep + for (uint charIdx = 0; charIdx < party._activeParty.size(); ++charIdx) { + party._activeParty[charIdx]._conditions[ASLEEP] = 1; + } + charIconsPrint(true); + + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_SLEEPING; + + if (oldMode == MODE_12) { + party.changeTime(8 * 60); + } else { + for (int idx = 0; idx < 10; ++idx) { + chargeStep(); + draw3d(true); + + if (_vm->_mode == MODE_1) { + _vm->_mode = oldMode; + return; + } + } + + party.changeTime(map._isOutdoors ? 380 : 470); + } + + if (_vm->getRandomNumber(1, 20) == 1) { + // Show dream + screen.saveBackground(); + screen.fadeOut(4); + events.hideCursor(); + + screen.loadBackground("scene1.raw"); + screen._windows[0].update(); + screen.fadeIn(4); + + events.updateGameCounter(); + while (!_vm->shouldQuit() && events.timeElapsed() < 7) + events.pollEventsAndWait(); + + File f("dreams2.voc"); + sound.playSample(&f, 1); + while (!_vm->shouldQuit() && sound.playSample(1, 0)) + events.pollEventsAndWait(); + f.close(); + + f.openFile("laff1.voc"); + sound.playSample(&f, 1); + while (!_vm->shouldQuit() && sound.playSample(1, 0)) + events.pollEventsAndWait(); + f.close(); + + events.updateGameCounter(); + while (!_vm->shouldQuit() && events.timeElapsed() < 7) + events.pollEventsAndWait(); + + screen.fadeOut(4); + events.setCursor(0); + screen.restoreBackground(); + screen._windows[0].update(); + + screen.fadeIn(4); + } + + party.resetTemps(); + + // Wake up the party + bool starving = false; + int foodConsumed = 0; + for (uint charIdx = 0; charIdx < party._activeParty.size(); ++charIdx) { + Character &c = party._activeParty[charIdx]; + c._conditions[ASLEEP] = 0; + + if (party._food == 0) { + starving = true; + } else { + party._rested = true; + Condition condition = c.worstCondition(); + + if (condition < DEAD || condition > ERADICATED) { + --party._food; + ++foodConsumed; + party._heroism = 0; + party._holyBonus = 0; + party._powerShield = 0; + party._blessed = 0; + c._conditions[UNCONSCIOUS] = 0; + c._currentHp = c.getMaxHP(); + c._currentSp = c.getMaxSP(); + } + } + } + + charIconsPrint(true); + _vm->_mode = oldMode; + doStepCode(); + draw3d(true); + + ErrorScroll::show(_vm, Common::String::format(REST_COMPLETE, + starving ? PARTY_IS_STARVING : HIT_SPELL_POINTS_RESTORED, + foodConsumed)); + party.checkPartyDead(); + } +} + } // End of namespace Xeen diff --git a/engines/xeen/interface.h b/engines/xeen/interface.h index 103b8b6607..cecc5c3a58 100644 --- a/engines/xeen/interface.h +++ b/engines/xeen/interface.h @@ -104,6 +104,8 @@ public: void unhighlightChar(); void perform(); + + void rest(); }; } // End of namespace Xeen diff --git a/engines/xeen/interface_map.cpp b/engines/xeen/interface_map.cpp index c8683a7e50..42c5ff4e07 100644 --- a/engines/xeen/interface_map.cpp +++ b/engines/xeen/interface_map.cpp @@ -426,7 +426,7 @@ void InterfaceMap::draw3d(bool updateFlag) { _flipUIFrame = (_flipUIFrame + 1) % 4; if (_flipUIFrame == 0) _flipWater = !_flipWater; - if (_tillMove && (_vm->_mode == MODE_1 || _vm->_mode == MODE_InCombat) && + if (_tillMove && (_vm->_mode == MODE_1 || _vm->_mode == MODE_COMBAT) && !_flag1 && _vm->_moveMonsters) { if (--_tillMove == 0) moveMonsters(); diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp index 51e87ef97e..dc58c2db6d 100644 --- a/engines/xeen/map.cpp +++ b/engines/xeen/map.cpp @@ -1369,7 +1369,7 @@ void Map::cellFlagLookup(const Common::Point &pt) { // Get the cell flags const MazeCell &cell = _mazeData[_mazeDataIndex]._cells[pos.y][pos.x]; _currentIsGrate = cell._flags & OUTFLAG_GRATE; - _currentCantRest = cell._flags & FLAG_WATER; + _currentCantRest = cell._flags & RESTRICTION_REST; _currentIsDrain = cell._flags & OUTFLAG_DRAIN; _currentIsEvent = cell._flags & FLAG_AUTOEXECUTE_EVENT; _currentSky = (cell._flags & OUTFLAG_OBJECT_EXISTS) ? 1 : 0; diff --git a/engines/xeen/map.h b/engines/xeen/map.h index abc36411ee..806b4084c7 100644 --- a/engines/xeen/map.h +++ b/engines/xeen/map.h @@ -137,8 +137,13 @@ public: enum MazeFlags { OUTFLAG_GRATE = 0x80, OUTFLAG_DRAIN = 0x20, OUTFLAG_OBJECT_EXISTS = 0x08, - INFLAG_INSIDE = 0x08, - FLAG_WATER = 0x40, FLAG_AUTOEXECUTE_EVENT = 0x10, + INFLAG_INSIDE = 0x08, FLAG_AUTOEXECUTE_EVENT = 0x10, + RESTRICTION_ETHERIALIZE = 0x40, RESTRICTION_80 = 0x80, + RESTRICTION_TOWN_PORTAL = 0x100, RESTRICTION_SUPER_SHELTER = 0x200, + RESTRICTION_TIME_DISTORTION = 0x400, RESTRICTION_LLOYDS_BEACON = 0x800, + RESTRICTION_TELPORT = 0x1000, RESTRICTION_2000 = 0x2000, + RESTRICTION_REST = 0x4000, RESTRICTION_SAVE = 0x8000, + FLAG_GROUND_BITS = 7 }; diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp index be8f4e6e18..ff59ed9b18 100644 --- a/engines/xeen/party.cpp +++ b/engines/xeen/party.cpp @@ -102,6 +102,7 @@ Party::Party(XeenEngine *vm) { _falling = false; _fallMaze = 0; _fallDamage = 0; + _dead = false; } void Party::synchronize(Common::Serializer &s) { @@ -360,7 +361,7 @@ void Party::addTime(int numMinutes) { if (_newDay && _minutes >= 300) { if (_vm->_mode != MODE_9 && _vm->_mode != MODE_17) { resetTemps(); - if (_rested || _vm->_mode == MODE_5) { + if (_rested || _vm->_mode == MODE_SLEEPING) { _rested = false; } else { for (int idx = 0; idx < _partyCount; ++idx) { @@ -497,4 +498,19 @@ void Party::notEnough(int consumableId, int whereId, bool mode, ErrorWaitType wa ErrorScroll::show(_vm, msg, wait); } +void Party::checkPartyDead() { + bool inCombat = _vm->_mode == MODE_COMBAT; + + for (uint charIdx = 0; charIdx < (inCombat ? _combatParty.size() : _activeParty.size()); ++charIdx) { + Character &c = inCombat ? *_combatParty[charIdx] : _activeParty[charIdx]; + Condition cond = c.worstCondition(); + if (cond <= CONFUSED || cond == NO_CONDITION) { + _dead = false; + return; + } + } + + _dead = true; +} + } // End of namespace Xeen diff --git a/engines/xeen/party.h b/engines/xeen/party.h index b1ca067df4..5b7da052ba 100644 --- a/engines/xeen/party.h +++ b/engines/xeen/party.h @@ -125,6 +125,7 @@ public: int _fallMaze; int _fallDamage; DamageType _damageType; + bool _dead; public: Party(XeenEngine *vm); @@ -147,6 +148,8 @@ public: int subtract(int mode, uint amount, int whereId, ErrorWaitType wait = WT_FREEZE_WAIT); void notEnough(int consumableId, int whereId, bool mode, ErrorWaitType wait); + + void checkPartyDead(); }; } // End of namespace Xeen diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp index 204e727326..d127ddcfc4 100644 --- a/engines/xeen/resources.cpp +++ b/engines/xeen/resources.cpp @@ -1423,4 +1423,13 @@ const char *const AUTO_NOTES_DATA = "%s\x3l\n" "%s\x3l"; +const char *const REST_COMPLETE = + "\v000\t0008 hours pass. Rest complete.\n" + "%s\n" + "%d food consumed."; +const char *const PARTY_IS_STARVING = "\f07The Party is Starving!\fd"; +const char *const HIT_SPELL_POINTS_RESTORED = "Hit Pts and Spell Pts restored."; +const char *const TOO_DANGEROUS_TO_REST = "Too dangerous to rest here!"; +const char *const SOME_CHARS_MAY_DIE = "Some Chars may die. Rest anyway?"; + } // End of namespace Xeen diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h index 9c0136c06f..517d6e4caf 100644 --- a/engines/xeen/resources.h +++ b/engines/xeen/resources.h @@ -486,6 +486,12 @@ extern const char *const QUEST_ITEMS_DATA; extern const char *const CURRENT_QUESTS_DATA; extern const char *const AUTO_NOTES_DATA; +extern const char *const REST_COMPLETE; +extern const char *const PARTY_IS_STARVING; +extern const char *const HIT_SPELL_POINTS_RESTORED; +extern const char *const TOO_DANGEROUS_TO_REST; +extern const char *const SOME_CHARS_MAY_DIE; + } // End of namespace Xeen #endif /* XEEN_RESOURCES_H */ diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp index 50e77668cd..4943d95d2a 100644 --- a/engines/xeen/spells.cpp +++ b/engines/xeen/spells.cpp @@ -92,7 +92,7 @@ void Spells::doSpell(int spellId) { &Spells::implosion, &Spells::starBurst, &Spells::divineIntervention }; - if (_vm->_mode == MODE_InCombat) { + if (_vm->_mode == MODE_COMBAT) { if (spellId == 15 || spellId == 20 || spellId == 27 || spellId == 41 || spellId == 47 || spellId == 54 || spellId == 57) { ErrorDialog::show(_vm, Common::String::format(CANT_CAST_WHILE_ENGAGED, diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h index af2044b212..537768e7e5 100644 --- a/engines/xeen/xeen.h +++ b/engines/xeen/xeen.h @@ -78,15 +78,16 @@ enum Mode { MODE_FF = -1, MODE_0 = 0, MODE_1 = 1, - MODE_InCombat = 2, + MODE_COMBAT = 2, MODE_3 = 3, MODE_4 = 4, - MODE_5 = 5, + MODE_SLEEPING = 5, MODE_6 = 6, MODE_7 = 7, MODE_8 = 8, MODE_9 = 9, MODE_CHARACTER_INFO = 10, + MODE_12 = 12, MODE_17 = 17 }; |