aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/xeen/character.h2
-rw-r--r--engines/xeen/dialogs_char_info.cpp12
-rw-r--r--engines/xeen/dialogs_error.cpp2
-rw-r--r--engines/xeen/dialogs_items.cpp6
-rw-r--r--engines/xeen/dialogs_spells.cpp2
-rw-r--r--engines/xeen/interface.cpp139
-rw-r--r--engines/xeen/interface.h2
-rw-r--r--engines/xeen/interface_map.cpp2
-rw-r--r--engines/xeen/map.cpp2
-rw-r--r--engines/xeen/map.h9
-rw-r--r--engines/xeen/party.cpp18
-rw-r--r--engines/xeen/party.h3
-rw-r--r--engines/xeen/resources.cpp9
-rw-r--r--engines/xeen/resources.h6
-rw-r--r--engines/xeen/spells.cpp2
-rw-r--r--engines/xeen/xeen.h5
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
};