Skip to content

Commit

Permalink
XEEN: Implemented resting
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Feb 8, 2015
1 parent 65ecc9b commit d6e7605
Show file tree
Hide file tree
Showing 16 changed files with 200 additions and 21 deletions.
2 changes: 1 addition & 1 deletion engines/xeen/character.h
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions engines/xeen/dialogs_char_info.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion engines/xeen/dialogs_error.cpp
Expand Up @@ -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);
}

Expand Down
6 changes: 3 additions & 3 deletions engines/xeen/dialogs_items.cpp
Expand Up @@ -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) {
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion engines/xeen/dialogs_spells.cpp
Expand Up @@ -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];
Expand Down
139 changes: 138 additions & 1 deletion engines/xeen/interface.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
2 changes: 2 additions & 0 deletions engines/xeen/interface.h
Expand Up @@ -104,6 +104,8 @@ class Interface: public ButtonContainer, public InterfaceMap {
void unhighlightChar();

void perform();

void rest();
};

} // End of namespace Xeen
Expand Down
2 changes: 1 addition & 1 deletion engines/xeen/interface_map.cpp
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion engines/xeen/map.cpp
Expand Up @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions engines/xeen/map.h
Expand Up @@ -137,8 +137,13 @@ class MazeDifficulties {

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
};

Expand Down
18 changes: 17 additions & 1 deletion engines/xeen/party.cpp
Expand Up @@ -102,6 +102,7 @@ Party::Party(XeenEngine *vm) {
_falling = false;
_fallMaze = 0;
_fallDamage = 0;
_dead = false;
}

void Party::synchronize(Common::Serializer &s) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
3 changes: 3 additions & 0 deletions engines/xeen/party.h
Expand Up @@ -125,6 +125,7 @@ class Party {
int _fallMaze;
int _fallDamage;
DamageType _damageType;
bool _dead;
public:
Party(XeenEngine *vm);

Expand All @@ -147,6 +148,8 @@ class Party {
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
Expand Down
9 changes: 9 additions & 0 deletions engines/xeen/resources.cpp
Expand Up @@ -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
6 changes: 6 additions & 0 deletions engines/xeen/resources.h
Expand Up @@ -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 */
2 changes: 1 addition & 1 deletion engines/xeen/spells.cpp
Expand Up @@ -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,
Expand Down

0 comments on commit d6e7605

Please sign in to comment.