aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-01-19 11:32:57 -0500
committerPaul Gilbert2015-01-19 11:32:57 -0500
commit687423b3612d61a18a9854010af56f7a98e5563d (patch)
tree455955b56cd2898f88d94bf126b174302d5537ed
parent83442b9586e3992ab8ee0f0d06e534781f9b448b (diff)
downloadscummvm-rg350-687423b3612d61a18a9854010af56f7a98e5563d.tar.gz
scummvm-rg350-687423b3612d61a18a9854010af56f7a98e5563d.tar.bz2
scummvm-rg350-687423b3612d61a18a9854010af56f7a98e5563d.zip
XEEN: Beginnings of main game loop and waiting
-rw-r--r--engines/xeen/interface.cpp180
-rw-r--r--engines/xeen/interface.h10
-rw-r--r--engines/xeen/interface_map.cpp32
-rw-r--r--engines/xeen/interface_map.h2
-rw-r--r--engines/xeen/map.cpp47
-rw-r--r--engines/xeen/map.h3
-rw-r--r--engines/xeen/party.cpp205
-rw-r--r--engines/xeen/party.h18
-rw-r--r--engines/xeen/resources.cpp52
-rw-r--r--engines/xeen/resources.h4
-rw-r--r--engines/xeen/scripts.cpp17
-rw-r--r--engines/xeen/scripts.h15
-rw-r--r--engines/xeen/sprites.cpp1
-rw-r--r--engines/xeen/xeen.cpp33
-rw-r--r--engines/xeen/xeen.h6
15 files changed, 499 insertions, 126 deletions
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index 50f3ede109..e15c0574aa 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -39,7 +39,6 @@ Interface::Interface(XeenEngine *vm) : ButtonContainer(), InterfaceMap(vm), _vm(
_holyBonusUIFrame = 0;
_heroismUIFrame = 0;
_flipUIFrame = 0;
- _newDay = false;
_buttonsLoaded = false;
_hiliteChar = -1;
_intrIndex1 = 0;
@@ -49,6 +48,7 @@ Interface::Interface(XeenEngine *vm) : ButtonContainer(), InterfaceMap(vm), _vm(
_tillMove = 0;
_thinWall = false;
_overallFrame = 0;
+ _upDoorText = false;
Common::fill(&_combatCharIds[0], &_combatCharIds[8], 0);
initDrawStructs();
@@ -91,12 +91,12 @@ void Interface::setup() {
_charPowSprites.load("charpow.icn");
// Get mappings to the active characters in the party
- _vm->_party._activeParty.resize(_vm->_party._partyCount);
- for (int i = 0; i < _vm->_party._partyCount; ++i) {
- _vm->_party._activeParty[i] = _vm->_roster[_vm->_party._partyMembers[i]];
+ _vm->_party->_activeParty.resize(_vm->_party->_partyCount);
+ for (int i = 0; i < _vm->_party->_partyCount; ++i) {
+ _vm->_party->_activeParty[i] = _vm->_roster[_vm->_party->_partyMembers[i]];
}
- _newDay = _vm->_party._minutes >= 300;
+ _vm->_party->_newDay = _vm->_party->_minutes >= 300;
}
void Interface::manageCharacters(bool soundPlayed) {
@@ -105,7 +105,7 @@ void Interface::manageCharacters(bool soundPlayed) {
bool flag = false;
start:
- if (_vm->_party._mazeId != 0) {
+ if (_vm->_party->_mazeId != 0) {
_vm->_mode = MODE_0;
_buttonsLoaded = true;
} else {
@@ -117,8 +117,8 @@ start:
// Xeen only uses 24 of possible 30 character slots
loadCharIcons();
- for (int i = 0; i < _vm->_party._partyCount; ++i)
- _partyFaces[i] = &_charFaces[_vm->_party._partyMembers[i]];
+ for (int i = 0; i < _vm->_party->_partyCount; ++i)
+ _partyFaces[i] = &_charFaces[_vm->_party->_partyMembers[i]];
}
_vm->_mode = MODE_1;
@@ -193,7 +193,7 @@ start:
case Common::KEYCODE_SPACE:
case Common::KEYCODE_e:
case Common::KEYCODE_x:
- if (_vm->_party._partyCount == 0) {
+ if (_vm->_party->_partyCount == 0) {
ErrorScroll::show(_vm, NO_ONE_TO_ADVENTURE_WITH);
} else {
if (_vm->_mode != MODE_0) {
@@ -208,10 +208,10 @@ start:
}
w.close();
- _vm->_party._realPartyCount = _vm->_party._partyCount;
- _vm->_party._mazeId = _vm->_party._priorMazeId;
+ _vm->_party->_realPartyCount = _vm->_party->_partyCount;
+ _vm->_party->_mazeId = _vm->_party->_priorMazeId;
- _vm->_party.copyPartyToRoster(_vm->_roster);
+ _vm->_party->copyPartyToRoster(_vm->_roster);
_vm->_saves->writeCharFile();
breakFlag = true;
break;
@@ -242,7 +242,7 @@ start:
case Common::KEYCODE_d:
break;
case Common::KEYCODE_r:
- if (_vm->_party._partyCount > 0) {
+ if (_vm->_party->_partyCount > 0) {
// TODO
}
break;
@@ -299,8 +299,8 @@ void Interface::loadCharIcons() {
}
void Interface::loadPartyIcons() {
- for (int i = 0; i < _vm->_party._partyCount; ++i)
- _partyFaces[i] = &_charFaces[_vm->_party._partyMembers[i]];
+ for (int i = 0; i < _vm->_party->_partyCount; ++i)
+ _partyFaces[i] = &_charFaces[_vm->_party->_partyMembers[i]];
}
void Interface::setupBackground() {
@@ -315,19 +315,19 @@ void Interface::assembleBorder() {
_globalSprites.draw(screen._windows[0], 0, Common::Point(8, 8));
// Draw the animating bat character used to show when levitate is active
- _borderSprites.draw(screen._windows[0], _vm->_party._levitateActive ? _batUIFrame + 16 : 16,
+ _borderSprites.draw(screen._windows[0], _vm->_party->_levitateActive ? _batUIFrame + 16 : 16,
Common::Point(0, 82));
_batUIFrame = (_batUIFrame + 1) % 12;
// Draw UI element to indicate whether can spot hidden doors
_borderSprites.draw(screen,
- (_thinWall && _vm->_party.checkSkill(SPOT_DOORS)) ? _spotDoorsUIFrame + 28 : 28,
+ (_thinWall && _vm->_party->checkSkill(SPOT_DOORS)) ? _spotDoorsUIFrame + 28 : 28,
Common::Point(194, 91));
_spotDoorsUIFrame = (_spotDoorsUIFrame + 1) % 12;
// Draw UI element to indicate whether can sense danger
_borderSprites.draw(screen,
- (_vm->_dangerSenseAllowed && _vm->_party.checkSkill(DANGER_SENSE)) ? _spotDoorsUIFrame + 40 : 40,
+ (_vm->_dangerSenseAllowed && _vm->_party->checkSkill(DANGER_SENSE)) ? _spotDoorsUIFrame + 40 : 40,
Common::Point(107, 9));
_dangerSenseUIFrame = (_dangerSenseUIFrame + 1) % 12;
@@ -344,7 +344,7 @@ void Interface::assembleBorder() {
else if (_vm->_face2State == 2)
_face2UIFrame = 0;
- if (!_vm->_party._clairvoyanceActive) {
+ if (!_vm->_party->_clairvoyanceActive) {
_face1UIFrame = 0;
_face2UIFrame = 8;
}
@@ -358,54 +358,54 @@ void Interface::assembleBorder() {
// Draw resistence indicators
if (!screen._windows[10]._enabled && !screen._windows[2]._enabled
&& screen._windows[38]._enabled) {
- _fecpSprites.draw(screen, _vm->_party._fireResistence ? 1 : 0,
+ _fecpSprites.draw(screen, _vm->_party->_fireResistence ? 1 : 0,
Common::Point(2, 2));
- _fecpSprites.draw(screen, _vm->_party._electricityResistence ? 3 : 2,
+ _fecpSprites.draw(screen, _vm->_party->_electricityResistence ? 3 : 2,
Common::Point(219, 2));
- _fecpSprites.draw(screen, _vm->_party._coldResistence ? 5 : 4,
+ _fecpSprites.draw(screen, _vm->_party->_coldResistence ? 5 : 4,
Common::Point(2, 134));
- _fecpSprites.draw(screen, _vm->_party._poisonResistence ? 7 : 6,
+ _fecpSprites.draw(screen, _vm->_party->_poisonResistence ? 7 : 6,
Common::Point(219, 134));
} else {
- _fecpSprites.draw(screen, _vm->_party._fireResistence ? 9 : 8,
+ _fecpSprites.draw(screen, _vm->_party->_fireResistence ? 9 : 8,
Common::Point(8, 8));
- _fecpSprites.draw(screen, _vm->_party._electricityResistence ? 10 : 11,
+ _fecpSprites.draw(screen, _vm->_party->_electricityResistence ? 10 : 11,
Common::Point(219, 8));
- _fecpSprites.draw(screen, _vm->_party._coldResistence ? 12 : 13,
+ _fecpSprites.draw(screen, _vm->_party->_coldResistence ? 12 : 13,
Common::Point(8, 134));
- _fecpSprites.draw(screen, _vm->_party._poisonResistence ? 14 : 15,
+ _fecpSprites.draw(screen, _vm->_party->_poisonResistence ? 14 : 15,
Common::Point(219, 134));
}
// Draw UI element for blessed
_blessSprites.draw(screen, 16, Common::Point(33, 137));
- if (_vm->_party._blessedActive) {
+ if (_vm->_party->_blessedActive) {
_blessedUIFrame = (_blessedUIFrame + 1) % 4;
_blessSprites.draw(screen, _blessedUIFrame, Common::Point(33, 137));
}
// Draw UI element for power shield
- if (_vm->_party._powerShieldActive) {
+ if (_vm->_party->_powerShieldActive) {
_powerShieldUIFrame = (_powerShieldUIFrame + 1) % 4;
_blessSprites.draw(screen, _powerShieldUIFrame + 4,
Common::Point(55, 137));
}
// Draw UI element for holy bonus
- if (_vm->_party._holyBonusActive) {
+ if (_vm->_party->_holyBonusActive) {
_holyBonusUIFrame = (_holyBonusUIFrame + 1) % 4;
_blessSprites.draw(screen, _holyBonusUIFrame + 8, Common::Point(160, 137));
}
// Draw UI element for heroism
- if (_vm->_party._heroismActive) {
+ if (_vm->_party->_heroismActive) {
_heroismUIFrame = (_heroismUIFrame + 1) % 4;
_blessSprites.draw(screen, _heroismUIFrame + 12, Common::Point(182, 137));
}
// Draw direction character if direction sense is active
- if (_vm->_party.checkSkill(DIRECTION_SENSE) && !_vm->_noDirectionSense) {
- const char *dirText = DIRECTION_TEXT[_vm->_party._mazeDirection];
+ if (_vm->_party->checkSkill(DIRECTION_SENSE) && !_vm->_noDirectionSense) {
+ const char *dirText = DIRECTION_TEXT[_vm->_party->_mazeDirection];
Common::String msg = Common::String::format(
"\002""08\003""c\013""139\011""116%c\014""d\001", *dirText);
screen._windows[0].writeString(msg);
@@ -426,7 +426,7 @@ void Interface::setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool
for (posIndex = 0; posIndex < 4; ++posIndex) {
charId = xeenSideChars[charIndex];
- bool isInParty = _vm->_party.isInParty(charId);
+ bool isInParty = _vm->_party->isInParty(charId);
if (charId == 0xff) {
while ((int)_buttons.size() > (7 + posIndex))
@@ -469,10 +469,10 @@ void Interface::charIconsPrint(bool updateFlag) {
_restoreSprites.draw(screen, 0, Common::Point(8, 149));
// Handle drawing the party faces
- for (int idx = 0; idx < (stateFlag ? _vm->_party._combatPartyCount :
- _vm->_party._partyCount); ++idx) {
+ for (int idx = 0; idx < (stateFlag ? _vm->_party->_combatPartyCount :
+ _vm->_party->_partyCount); ++idx) {
int charIndex = stateFlag ? _combatCharIds[idx] : idx;
- PlayerStruct &ps = _vm->_party._activeParty[charIndex];
+ PlayerStruct &ps = _vm->_party->_activeParty[charIndex];
Condition charCondition = ps.worstCondition();
int charFrame = FACE_CONDITION_FRAMES[charCondition];
@@ -485,10 +485,10 @@ void Interface::charIconsPrint(bool updateFlag) {
}
if (!_hpSprites.empty()) {
- for (int idx = 0; idx < (stateFlag ? _vm->_party._combatPartyCount :
- _vm->_party._partyCount); ++idx) {
+ for (int idx = 0; idx < (stateFlag ? _vm->_party->_combatPartyCount :
+ _vm->_party->_partyCount); ++idx) {
int charIndex = stateFlag ? _combatCharIds[idx] : idx;
- PlayerStruct &ps = _vm->_party._activeParty[charIndex];
+ PlayerStruct &ps = _vm->_party->_activeParty[charIndex];
// Draw the Hp bar
int maxHp = ps.getMaxHp();
@@ -555,7 +555,7 @@ void Interface::draw3d(bool updateFlag) {
}
MazeObject &objObject = map._mobData._objects[_objNumber];
- Direction partyDirection = _vm->_party._mazeDirection;
+ Direction partyDirection = _vm->_party->_mazeDirection;
int objNum = _objNumber - 1;
// Loop to update the frame numbers for each maze object, applying the animation frame
@@ -2312,4 +2312,102 @@ void Interface::updateAutoMap() {
// TODO
}
+/**
+ * Waits for a keypress or click, whilst still allowing the game scene to
+ * be animated.
+ */
+void Interface::wait() {
+ EventsManager &events = *_vm->_events;
+ Map &map = *_vm->_map;
+ Party &party = *_vm->_party;
+ Scripts &scripts = *_vm->_scripts;
+ const Common::Rect waitBounds(8, 8, 224, 140);
+
+ while (!_vm->shouldQuit()) {
+ events.updateGameCounter();
+ draw3d(true);
+
+ // Wait for a frame
+ while (!_vm->shouldQuit()) {
+ events.pollEventsAndWait();
+ checkEvents(_vm);
+ } while (!_buttonValue && events.timeElapsed() < 1 && !_vm->_party->_partyDead);
+
+ if (!_buttonValue && !_vm->_party->_partyDead)
+ continue;
+
+ if (_buttonValue == Common::KEYCODE_SPACE ||
+ (events._leftButton && waitBounds.contains(events._mousePos))) {
+ int lookupId = map.mazeLookup(party._mazePosition,
+ WALL_NUMBERS[party._mazeDirection][2]);
+
+ bool eventsFlag = true;
+ switch (lookupId) {
+ case 1:
+ if (!map._isOutdoors) {
+ scripts.openGrate(13, 1);
+ eventsFlag = _buttonValue != 0;
+ }
+
+ case 6:
+ if (!map._isOutdoors) {
+ scripts.openGrate(9, 0);
+ eventsFlag = _buttonValue != 0;
+ }
+ break;
+ case 9:
+ if (!map._isOutdoors) {
+ scripts.openGrate(6, 0);
+ eventsFlag = _buttonValue != 0;
+ }
+ break;
+ case 13:
+ if (!map._isOutdoors) {
+ scripts.openGrate(1, 1);
+ eventsFlag = _buttonValue != 0;
+ }
+ break;
+ default:
+ break;
+ }
+ if (eventsFlag) {
+ scripts.checkEvents();
+ if (_vm->shouldQuit())
+ return;
+ }
+ }
+
+ switch (_buttonValue) {
+ case Common::KEYCODE_TAB:
+ // Stop mosters doing any movement
+ _vm->_moveMonsters = false;
+ warning("TODO: showControlPanel");
+ break;
+
+ case Common::KEYCODE_SPACE:
+ case Common::KEYCODE_w:
+ // Wait one turn
+ chargeStep();
+ moveMonsters();
+ _upDoorText = false;
+ _flipDefaultGround = !_flipDefaultGround;
+ _flipGround = !_flipGround;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void Interface::chargeStep() {
+ if (_vm->_party->_partyDead) {
+ _vm->_party->changeTime(_vm->_map->_isOutdoors ? 10 : 1);
+ if (!_tillMove) {
+ moveMonsters();
+ }
+
+ _tillMove = 3;
+ }
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/interface.h b/engines/xeen/interface.h
index df06f5d86b..c6fee9e0d4 100644
--- a/engines/xeen/interface.h
+++ b/engines/xeen/interface.h
@@ -63,7 +63,6 @@ private:
int _holyBonusUIFrame;
int _heroismUIFrame;
int _flipUIFrame;
- bool _newDay;
bool _buttonsLoaded;
Common::String _interfaceText;
int _hiliteChar;
@@ -74,6 +73,7 @@ private:
byte _tillMove;
bool _thinWall;
int _overallFrame;
+ bool _upDoorText;
void initDrawStructs();
@@ -85,8 +85,6 @@ private:
void setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag);
- void charIconsPrint(bool updateFlag);
-
void drawViewBackground(int bgType);
void moveCharacterToRoster();
@@ -100,6 +98,8 @@ private:
void setMazeBits();
void updateAutoMap();
+
+ void chargeStep();
public:
Interface(XeenEngine *vm);
@@ -116,6 +116,10 @@ public:
void startup();
void mainIconsPrint();
+
+ void charIconsPrint(bool updateFlag);
+
+ void wait();
};
} // End of namespace Xeen
diff --git a/engines/xeen/interface_map.cpp b/engines/xeen/interface_map.cpp
index 93c3d9a679..1f927112b8 100644
--- a/engines/xeen/interface_map.cpp
+++ b/engines/xeen/interface_map.cpp
@@ -165,7 +165,7 @@ OutdoorDrawList::OutdoorDrawList() : _skySprite(_data[1]), _groundSprite(_data[2
/*------------------------------------------------------------------------*/
IndoorDrawList::IndoorDrawList() :
- _sky(_data[1]), _ground(_data[2]), _horizon(_data[28]),
+ _sky1(_data[0]), _sky2(_data[1]), _ground(_data[2]), _horizon(_data[28]),
_swl_0F1R(_data[146]), _swl_0F1L(_data[144]), _swl_1F1R(_data[134]),
_swl_1F1L(_data[133]), _swl_2F2R(_data[110]), _swl_2F1R(_data[109]),
_swl_2F1L(_data[108]), _swl_2F2L(_data[107]), _swl_3F1R(_data[ 78]),
@@ -378,8 +378,8 @@ InterfaceMap::InterfaceMap(XeenEngine *vm): _vm(vm) {
void InterfaceMap::setIndoorsMonsters() {
Combat &combat = *_vm->_combat;
Map &map = *_vm->_map;
- Common::Point mazePos = _vm->_party._mazePosition;
- Direction dir = _vm->_party._mazeDirection;
+ Common::Point mazePos = _vm->_party->_mazePosition;
+ Direction dir = _vm->_party->_mazeDirection;
const int INDOOR_MONSTERS_Y[4] = { 2, 34, 53, 59 };
combat.clear();
@@ -645,8 +645,8 @@ void InterfaceMap::setMonsterSprite(DrawStruct &drawStruct, MazeMonster &monster
}
void InterfaceMap::setIndoorsObjects() {
- Common::Point mazePos = _vm->_party._mazePosition;
- Direction dir = _vm->_party._mazeDirection;
+ Common::Point mazePos = _vm->_party->_mazePosition;
+ Direction dir = _vm->_party->_mazeDirection;
Common::Point pt;
_objNumber = 0;
@@ -871,8 +871,8 @@ void InterfaceMap::setIndoorsObjects() {
void InterfaceMap::setIndoorsWallPics() {
Map &map = *_vm->_map;
- const Common::Point &mazePos = _vm->_party._mazePosition;
- Direction dir = _vm->_party._mazeDirection;
+ const Common::Point &mazePos = _vm->_party->_mazePosition;
+ Direction dir = _vm->_party->_mazeDirection;
Common::fill(&_wp[0], &_wp[20], -1);
@@ -1912,7 +1912,7 @@ void InterfaceMap::drawIndoors() {
_indoorList._swl_0F1R._frame = 25;
}
- map.cellFlagLookup(_vm->_party._mazePosition);
+ map.cellFlagLookup(_vm->_party->_mazePosition);
// WORKAROUND: Original did an array lookup on _skySprites.
// Was this a feature for multiple skys that was abandoned?
@@ -1922,19 +1922,19 @@ void InterfaceMap::drawIndoors() {
if (_vm->_openDoor) {
Common::Point pt(
- _vm->_party._mazePosition.x + SCREEN_POSITIONING_X[
- _vm->_party._mazeDirection][_vm->_party._mazePosition.x],
- _vm->_party._mazePosition.y + SCREEN_POSITIONING_Y[
- _vm->_party._mazeDirection][_vm->_party._mazePosition.y]
+ _vm->_party->_mazePosition.x + SCREEN_POSITIONING_X[
+ _vm->_party->_mazeDirection][_vm->_party->_mazePosition.x],
+ _vm->_party->_mazePosition.y + SCREEN_POSITIONING_Y[
+ _vm->_party->_mazeDirection][_vm->_party->_mazePosition.y]
);
map.cellFlagLookup(pt);
- _indoorList._sky._sprites = &map._skySprites;
+ _indoorList._sky2._sprites = &map._skySprites;
} else {
- _indoorList._sky._sprites = _indoorList[0]._sprites;
+ _indoorList._sky2._sprites = _indoorList[0]._sprites;
}
- _indoorList._sky._flags = _flipSky ? SPRFLAG_HORIZ_FLIPPED : 0;
+ _indoorList._sky2._flags = _flipSky ? SPRFLAG_HORIZ_FLIPPED : 0;
_indoorList._ground._flags = _flipDefaultGround ? SPRFLAG_HORIZ_FLIPPED : 0;
_indoorList._horizon._frame = 7;
@@ -1943,7 +1943,7 @@ void InterfaceMap::drawIndoors() {
// Check for any character shooting
_isShooting = false;
- for (int i = 0; i < _vm->_party._partyCount; ++i) {
+ for (int i = 0; i < _vm->_party->_partyCount; ++i) {
if (_vm->_combat->_shooting[i])
_isShooting = true;
}
diff --git a/engines/xeen/interface_map.h b/engines/xeen/interface_map.h
index fd807a03d2..be17ef0024 100644
--- a/engines/xeen/interface_map.h
+++ b/engines/xeen/interface_map.h
@@ -50,7 +50,7 @@ public:
class IndoorDrawList {
public:
DrawStruct _data[170];
- DrawStruct &_sky;
+ DrawStruct &_sky1, &_sky2;
DrawStruct &_ground;
DrawStruct &_horizon;
DrawStruct * const _groundTiles;
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index 99fe5ada0b..bef0511c81 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -887,7 +887,7 @@ void Map::load(int mapId) {
}
_stepped = true;
- _vm->_party._mazeId = mapId;
+ _vm->_party->_mazeId = mapId;
_vm->_events->clearEvents();
_sideObjects = 1;
@@ -970,7 +970,7 @@ void Map::load(int mapId) {
if (isDarkCc && mapId == 50)
mazeDataP->setAllTilesStepped();
- if (!isDarkCc && _vm->_party._gameFlags[25] &&
+ if (!isDarkCc && _vm->_party->_gameFlags[25] &&
(mapId == 42 || mapId == 43 || mapId == 4)) {
mazeDataP->clearCellSurfaces();
}
@@ -1004,14 +1004,14 @@ void Map::load(int mapId) {
_headData.synchronize(headFile);
headFile.close();
- if (!isDarkCc && _vm->_party._mazeId)
+ if (!isDarkCc && _vm->_party->_mazeId)
_mobData._monsters.clear();
if (!isDarkCc && mapId == 15) {
if ((_mobData._monsters[0]._position.x > 31 || _mobData._monsters[0]._position.y > 31) &&
(_mobData._monsters[1]._position.x > 31 || _mobData._monsters[1]._position.y > 31) &&
(_mobData._monsters[2]._position.x > 31 || _mobData._monsters[2]._position.y > 31)) {
- _vm->_party._gameFlags[56] = true;
+ _vm->_party->_gameFlags[56] = true;
}
}
}
@@ -1029,7 +1029,7 @@ void Map::load(int mapId) {
// TODO: Switch setting flags that don't seem to ever be used
// Reload the monster data for the main maze that we're loading
- mapId = _vm->_party._mazeId;
+ mapId = _vm->_party->_mazeId;
Common::String filename = Common::String::format("maze%c%03d.mob",
(mapId >= 100) ? 'x' : '0', mapId);
File mobFile(filename, *_vm->_saves);
@@ -1039,10 +1039,10 @@ void Map::load(int mapId) {
// Load sprites for the objects
for (uint i = 0; i < _mobData._objectSprites.size(); ++i) {
- if (_vm->_party._cloudsEnd && _mobData._objectSprites[i]._spriteId == 85 &&
+ if (_vm->_party->_cloudsEnd && _mobData._objectSprites[i]._spriteId == 85 &&
mapId == 27 && isDarkCc) {
// TODO: Flags set that don't seem to be used
- } else if (mapId == 12 && _vm->_party._gameFlags[43] &&
+ } else if (mapId == 12 && _vm->_party->_gameFlags[43] &&
_mobData._objectSprites[i]._spriteId == 118 && !isDarkCc) {
filename = "085.obj";
_mobData._objectSprites[0]._spriteId = 85;
@@ -1081,7 +1081,6 @@ void Map::load(int mapId) {
if (_isOutdoors) {
warning("TODO"); // Sound loading
- _skySprites.load(isDarkCc ? "night.sky" : "sky.sky");
_groundSprites.load("water.out");
_tileSprites.load("outdoor.til");
outdoorList._skySprite._sprites = &_skySprites;
@@ -1102,7 +1101,6 @@ void Map::load(int mapId) {
} else {
warning("TODO"); // Sound loading
- _skySprites.load(isDarkCc ? "night.sky" : "sky.sky");
_mazeSkySprites.load(Common::String::format("%s.sky",
TERRAIN_TYPES[_mazeData[0]._wallKind]));
_groundSprites.load(Common::String::format("%s.gnd",
@@ -1193,18 +1191,20 @@ void Map::load(int mapId) {
indoorList._horizon._sprites = nullptr;
}
}
+
+ loadSky();
}
-int Map::mazeLookup(const Common::Point &pt, int directionLayerIndex) {
+int Map::mazeLookup(const Common::Point &pt, int layerShift) {
Common::Point pos = pt;
- int mapId = _vm->_party._mazeId;
+ int mapId = _vm->_party->_mazeId;
if (pt.x < -16 || pt.y < -16 || pt.x >= 32 || pt.y >= 32)
error("Invalid coordinate");
// Find the correct maze data out of the set to use
_mazeDataIndex = 0;
- while (_mazeData[_mazeDataIndex]._mazeId != _vm->_party._mazeId)
+ while (_mazeData[_mazeDataIndex]._mazeId != _vm->_party->_mazeId)
++_mazeDataIndex;
// Handle map changing to the north or south as necessary
@@ -1259,7 +1259,7 @@ int Map::mazeLookup(const Common::Point &pt, int directionLayerIndex) {
_currentSteppedOn = _mazeData[_mazeDataIndex]._steppedOnTiles[pos.y][pos.x];
}
- return (_mazeData[_mazeDataIndex]._wallData[pos.y][pos.x]._data >> (directionLayerIndex * 4)) & 0xF;
+ return (_mazeData[_mazeDataIndex]._wallData[pos.y][pos.x]._data >> layerShift) & 0xF;
} else {
_currentSteppedOn = _isOutdoors;
@@ -1312,7 +1312,7 @@ void Map::saveMaze() {
void Map::cellFlagLookup(const Common::Point &pt) {
Common::Point pos = pt;
- int mapId = _vm->_party._mazeId;
+ int mapId = _vm->_party->_mazeId;
_mazeDataIndex = 0;
while (_mazeData[_mazeDataIndex]._mazeId != mapId)
++_mazeDataIndex;
@@ -1364,11 +1364,11 @@ void Map::setCellSurfaceFlags(const Common::Point &pt, int bits) {
int Map::getCell(int idx) {
- int mapId = _vm->_party._mazeId;
- Direction dir = _vm->_party._mazeDirection;
+ int mapId = _vm->_party->_mazeId;
+ Direction dir = _vm->_party->_mazeDirection;
Common::Point pt(
- _vm->_party._mazePosition.x + SCREEN_POSITIONING_X[_vm->_party._mazeDirection][idx],
- _vm->_party._mazePosition.y + SCREEN_POSITIONING_Y[_vm->_party._mazeDirection][idx]
+ _vm->_party->_mazePosition.x + SCREEN_POSITIONING_X[_vm->_party->_mazeDirection][idx],
+ _vm->_party->_mazePosition.y + SCREEN_POSITIONING_Y[_vm->_party->_mazeDirection][idx]
);
if (pt.x > 31 || pt.y > 31) {
@@ -1484,10 +1484,19 @@ int Map::getCell(int idx) {
_currentSurfaceId = _mazeData[_mazeDataIndex]._cells[pt.y][pt.x]._surfaceId;
_currentWall = wallLayers;
- return (_currentWall._data >> (WALL_NUMBERS[dir][idx * 2] * 4)) & 0xF;
+ return (_currentWall._data >> WALL_NUMBERS[dir][idx]) & 0xF;
}
return _currentWall._data;
}
+void Map::loadSky() {
+ Party &party = *_vm->_party;
+
+ party._isNight = party._minutes < (5 * 60) || party._minutes >= (21 * 60);
+ _skySprites.load(((party._mazeId >= 89 && party._mazeId <= 112) ||
+ party._mazeId == 128 || party._mazeId == 129) || !party._isNight
+ ? "sky.sky" : "night.sky");
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/map.h b/engines/xeen/map.h
index c97de72a23..ae8ad28efd 100644
--- a/engines/xeen/map.h
+++ b/engines/xeen/map.h
@@ -392,7 +392,7 @@ public:
void load(int mapId);
- int mazeLookup(const Common::Point &pt, int directionLayerIndex);
+ int mazeLookup(const Common::Point &pt, int layerShift);
void cellFlagLookup(const Common::Point &pt);
@@ -404,6 +404,7 @@ public:
MazeData mazeData() { return _mazeData[0]; }
+ void loadSky();
};
} // End of namespace Xeen
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index ad6d2145de..6d5cc22ffa 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -23,9 +23,11 @@
#include "common/scummsys.h"
#include "common/algorithm.h"
#include "xeen/party.h"
+#include "xeen/dialogs_error.h"
#include "xeen/files.h"
-#include "xeen/xeen.h"
+#include "xeen/resources.h"
#include "xeen/saves.h"
+#include "xeen/xeen.h"
namespace Xeen {
@@ -155,6 +157,16 @@ int PlayerStruct::getMaxHp() {
return 20;
}
+int PlayerStruct::getStat(int statNum, int v2) {
+ // TODO
+ return 10;
+}
+
+bool PlayerStruct::charSavingThrow() {
+ // TODO
+ return false;
+}
+
/*------------------------------------------------------------------------*/
void Roster::synchronize(Common::Serializer &s) {
@@ -167,7 +179,7 @@ void Roster::synchronize(Common::Serializer &s) {
/*------------------------------------------------------------------------*/
-Party::Party() {
+Party::Party(XeenEngine *vm): _vm(vm) {
_partyCount = 0;
_realPartyCount = 0;
Common::fill(&_partyMembers[0], &_partyMembers[8], 0);
@@ -216,6 +228,9 @@ Party::Party() {
Common::fill(&_characterFlags[i][0], &_characterFlags[i][24], false);
_combatPartyCount = 0;
+ _partyDead = false;
+ _newDay = false;
+ _isNight = false;
}
void Party::synchronize(Common::Serializer &s) {
@@ -343,4 +358,190 @@ void Party::copyPartyToRoster(Roster &r) {
}
}
+/**
+ * Adds time to the party's playtime, taking into account the effect of any
+ * stat modifier changes
+ */
+void Party::changeTime(int numMinutes) {
+ bool killed = false;
+
+ if (((_minutes + numMinutes) / 480) != (_minutes / 480)) {
+ for (int idx = 0; idx < _partyCount; ++idx) {
+ PlayerStruct &player = _activeParty[idx];
+
+ if (!player._conditions[DEAD] && !player._conditions[STONED] &&
+ !player._conditions[ERADICATED]) {
+ for (int statNum = 0; statNum < TOTAL_STATS; ++statNum) {
+ int statVal = player.getStat(statNum, 0);
+ if (statVal < 1)
+ player._conditions[DEAD] = 1;
+ }
+ }
+
+ // Handle heart broken condition becoming depression
+ if (player._conditions[HEART_BROKEN]) {
+ if (++player._conditions[HEART_BROKEN] > 10) {
+ player._conditions[HEART_BROKEN] = 0;
+ player._conditions[DEPRESSED] = 1;
+ }
+ }
+
+ // Handle poisoning
+ if (!player._conditions[POISONED]) {
+ if (_vm->getRandomNumber(9) != 1 || !player.charSavingThrow())
+ player._conditions[POISONED] *= 2;
+ else
+ // Poison wears off
+ player._conditions[POISONED] = 0;
+ }
+
+ // Handle poisoning
+ if (!player._conditions[DISEASED]) {
+ if (_vm->getRandomNumber(9) != 1 || !player.charSavingThrow())
+ player._conditions[DISEASED] *= 2;
+ else
+ // Disease wears off
+ player._conditions[DISEASED] = 0;
+ }
+
+ // Handle insane status
+ if (player._conditions[INSANE])
+ player._conditions[INSANE]++;
+
+ if (player._conditions[DEAD]) {
+ if (++player._conditions[DEAD] == 0)
+ player._conditions[DEAD] = -1;
+ }
+
+ if (player._conditions[STONED]) {
+ if (++player._conditions[STONED] == 0)
+ player._conditions[STONED] = -1;
+ }
+
+ if (player._conditions[ERADICATED]) {
+ if (++player._conditions[ERADICATED] == 0)
+ player._conditions[ERADICATED] = -1;
+ }
+
+ if (player._conditions[IN_LOVE]) {
+ if (++player._conditions[IN_LOVE] > 10) {
+ player._conditions[IN_LOVE] = 0;
+ player._conditions[HEART_BROKEN] = 1;
+ }
+ }
+
+ player._conditions[WEAK] = player._conditions[DRUNK];
+ player._conditions[DRUNK] = 0;
+
+ if (player._conditions[DEPRESSED]) {
+ player._conditions[DEPRESSED] = (player._conditions[DEPRESSED] + 1) % 4;
+ }
+ }
+ }
+
+ // Increment the time
+ addTime(numMinutes);
+
+ for (int idx = 0; idx < _partyCount; ++idx) {
+ PlayerStruct &player = _activeParty[idx];
+
+ if (player._conditions[CONFUSED] && _vm->getRandomNumber(2) == 1) {
+ if (player.charSavingThrow()) {
+ player._conditions[CONFUSED] = 0;
+ } else {
+ player._conditions[CONFUSED]--;
+ }
+ }
+
+ if (player._conditions[PARALYZED] && _vm->getRandomNumber(4) == 1)
+ player._conditions[PARALYZED]--;
+ }
+
+ if (killed)
+ _vm->_interface->charIconsPrint(true);
+
+ if (_isNight != (_minutes < (5 * 60) || _minutes >= (21 * 60)))
+ _vm->_map->loadSky();
+}
+
+void Party::addTime(int numMinutes) {
+ int day = _day;
+ _minutes += numMinutes;
+
+ // If the total minutes has exceeded a day, move to next one
+ while (_minutes >= (24 * 60)) {
+ _minutes -= 24 * 60;
+ if (++_day >= 100) {
+ _day -= 100;
+ ++_year;
+ }
+ }
+
+ if ((_day % 10) == 1 || numMinutes > (24 * 60)) {
+ if (_day != day) {
+ warning("TODO: resetBlacksmith? and giveInterest?");
+ }
+ }
+
+ if (_day != day)
+ _newDay = true;
+
+ if (_newDay && _minutes >= 300) {
+ if (_vm->_mode != MODE_9 && _vm->_mode != MODE_17) {
+ resetTemps();
+ if (_rested || _vm->_mode == MODE_5) {
+ _rested = false;
+ } else {
+ for (int idx = 0; idx < _partyCount; ++idx) {
+ if (_activeParty[idx]._conditions[WEAK] >= 0)
+ _activeParty[idx]._conditions[WEAK]++;
+ }
+
+ ErrorScroll::show(_vm, THE_PARTY_NEEDS_REST, WT_NONFREEZED_WAIT);
+ }
+
+ _vm->_interface->charIconsPrint(true);
+ }
+
+ _newDay = false;
+ }
+}
+
+void Party::resetTemps() {
+ for (int idx = 0; idx < _partyCount; ++idx) {
+ PlayerStruct &player = _activeParty[idx];
+
+ player._magicResistence._temporary = 0;
+ player._energyResistence._temporary = 0;
+ player._poisonResistence._temporary = 0;
+ player._electricityResistence._temporary = 0;
+ player._coldResistence._temporary = 0;
+ player._fireResistence._temporary = 0;
+ player._ACTemp = 0;
+ player._level._temporary = 0;
+ player._luck._temporary = 0;
+ player._accuracy._temporary = 0;
+ player._speed._temporary = 0;
+ player._endurance._temporary = 0;
+ player._personality._temporary = 0;
+ player._intellect._temporary = 0;
+ player._might._temporary = 0;
+ }
+
+ _poisonResistence = 0;
+ _coldResistence = 0;
+ _electricityResistence = 0;
+ _fireResistence = 0;
+ _lightCount = 0;
+ _levitateActive = false;
+ _walkOnWaterActive = false;
+ _wizardEyeActive = false;
+ _clairvoyanceActive = false;
+ _heroismActive = false;
+ _holyBonusActive = false;
+ _powerShieldActive = false;
+ _blessedActive = false;
+}
+
+
} // End of namespace Xeen
diff --git a/engines/xeen/party.h b/engines/xeen/party.h
index d8fe2ab79d..75a6c2b07b 100644
--- a/engines/xeen/party.h
+++ b/engines/xeen/party.h
@@ -66,6 +66,7 @@ enum Condition { CURSED = 0, HEART_BROKEN = 1, WEAK = 2, POISONED = 3,
#define TOTAL_CHARACTERS 30
#define XEEN_TOTAL_CHARACTERS 24
#define MAX_ACTIVE_PARTY 6
+#define TOTAL_STATS 7
class XeenEngine;
@@ -133,6 +134,10 @@ public:
int getAge(int partyYear, bool ignoreTemp);
int getMaxHp();
+
+ int getStat(int statNum, int v2);
+
+ bool charSavingThrow();
};
class Roster: public Common::Array<PlayerStruct> {
@@ -143,6 +148,8 @@ public:
};
class Party {
+private:
+ XeenEngine *_vm;
public:
// Dynamic data that's saved
int _partyCount;
@@ -202,8 +209,11 @@ public:
// Other party related runtime data
Common::Array<PlayerStruct> _activeParty;
int _combatPartyCount;
+ bool _partyDead;
+ bool _newDay;
+ bool _isNight;
public:
- Party();
+ Party(XeenEngine *vm);
void synchronize(Common::Serializer &s);
@@ -212,6 +222,12 @@ public:
bool isInParty(int charId);
void copyPartyToRoster(Roster &r);
+
+ void changeTime(int numMinutes);
+
+ void addTime(int numMinutes);
+
+ void resetTemps();
};
} // End of namespace Xeen
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 51f26fe668..085f84aa73 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -66,6 +66,8 @@ const char *const OPTIONS_TITLE =
"\v117Copyright (c) 1993 NWC, Inc.\n"
"All Rights Reserved\x01";
+const char *const THE_PARTY_NEEDS_REST = "\x0B""012The Party needs rest!";
+
const char *const TERRAIN_TYPES[6] = {
"town", "cave", "towr", "cstl", "dung", "scfi"
};
@@ -392,43 +394,27 @@ const int DIRECTION_ANIM_POSITIONS[4][4] = {
{ 0, 1, 2, 3 }, { 3, 0, 1, 2 }, { 2, 3, 0, 1 }, { 1, 2, 3, 0 }
};
-const byte WALL_NUMBERS[4][96] = {
+const byte WALL_NUMBERS[4][48] = {
{
- 3, 0, 0, 0, 3, 0, 2, 0, 3, 0, 3, 0,
- 0, 0, 3, 0, 2, 0, 3, 0, 3, 0, 0, 0,
- 3, 0, 0, 0, 3, 0, 2, 0, 3, 0, 2, 0,
- 3, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0,
- 0, 0, 3, 0, 0, 0, 3, 0, 2, 0, 3, 0,
- 2, 0, 3, 0, 2, 0, 3, 0, 2, 0, 3, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,
- 2, 0, 2, 0, 0, 0, 0, 0, 1, 0, 1, 0
+ 12, 0, 12, 8, 12, 12, 0, 12, 8, 12, 12, 0,
+ 12, 0, 12, 8, 12, 8, 12, 12, 0, 12, 0, 12,
+ 0, 12, 0, 12, 8, 12, 8, 12, 8, 12, 8, 12,
+ 0, 0, 0, 0, 8, 8, 8, 8, 0, 0, 4, 4
}, {
- 2, 0, 3, 0, 2, 0, 1, 0, 2, 0, 2, 0,
- 3, 0, 2, 0, 1, 0, 2, 0, 2, 0, 3, 0,
- 2, 0, 3, 0, 2, 0, 1, 0, 2, 0, 1, 0,
- 2, 0, 2, 0, 3, 0, 2, 0, 3, 0, 2, 0,
- 3, 0, 2, 0, 3, 0, 2, 0, 1, 0, 2, 0,
- 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0,
- 3, 0, 3, 0, 3, 0, 3, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 8, 12, 8, 4, 8, 8, 12, 8, 4, 8, 8, 12,
+ 8, 12, 8, 4, 8, 4, 8, 8, 12, 8, 12, 8,
+ 12, 8, 12, 8, 4, 8, 4, 8, 4, 8, 4, 8,
+ 12, 12, 12, 12, 4, 4, 4, 4, 0, 0, 0, 0
}, {
- 1, 0, 2, 0, 1, 0, 0, 0, 1, 0, 1, 0,
- 2, 0, 1, 0, 0, 0, 1, 0, 1, 0, 2, 0,
- 1, 0, 2, 0, 1, 0, 0, 0, 1, 0, 0, 0,
- 1, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0,
- 2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 1, 0,
- 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0,
- 2, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0
+ 4, 8, 4, 0, 4, 4, 8, 4, 0, 4, 4, 8,
+ 4, 8, 4, 0, 4, 0, 4, 4, 8, 4, 8, 4,
+ 8, 4, 8, 4, 0, 4, 0, 4, 0, 4, 0, 4,
+ 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 12, 12
}, {
- 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
- 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0,
- 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 3, 0,
- 3, 0, 3, 0, 0, 0, 0, 0, 2, 0, 2, 0
+ 0, 4, 0, 12, 0, 0, 4, 0, 12, 0, 0, 4,
+ 0, 4, 0, 12, 0, 12, 0, 0, 4, 0, 4, 0,
+ 4, 0, 4, 0, 12, 0, 12, 0, 12, 0, 12, 0,
+ 4, 4, 4, 4, 12, 12, 12, 12, 0, 0, 8, 8
}
};
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index 0ef9211288..f6bcffaf4e 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -32,6 +32,8 @@ extern const char *const CREDITS;
extern const char *const OPTIONS_TITLE;
+extern const char *const THE_PARTY_NEEDS_REST;
+
extern const char *const TERRAIN_TYPES[6];
extern const char *const SURFACE_TYPE_NAMES[15];
@@ -88,7 +90,7 @@ extern const int OUTDOOR_OBJECT_Y[2][12];
extern const int DIRECTION_ANIM_POSITIONS[4][4];
-extern const byte WALL_NUMBERS[4][96];
+extern const byte WALL_NUMBERS[4][48];
extern const int DRAW_NUMBERS[25];
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 0a864aa2cb..5a36a32a7e 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -61,4 +61,21 @@ void MazeEvents::synchronize(XeenSerializer &s) {
}
}
+/*------------------------------------------------------------------------*/
+
+Scripts::Scripts(XeenEngine *vm) : _vm(vm) {
+}
+
+void Scripts::checkEvents() {
+ // TODO
+}
+
+void Scripts::giveTreasure() {
+ // TODO
+}
+
+void Scripts::openGrate(int v1, int v2) {
+ // TODO
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/scripts.h b/engines/xeen/scripts.h
index 727d37f681..4f49018e2b 100644
--- a/engines/xeen/scripts.h
+++ b/engines/xeen/scripts.h
@@ -95,6 +95,8 @@ enum Opcode {
OP_PlayCD = 0x3C
};
+class XeenEngine;
+
class MazeEvent {
public:
Common::Point _position;
@@ -115,6 +117,19 @@ public:
void synchronize(XeenSerializer &s);
};
+class Scripts {
+private:
+ XeenEngine *_vm;
+public:
+ Scripts(XeenEngine *vm);
+
+ void checkEvents();
+
+ void giveTreasure();
+
+ void openGrate(int v1, int v2);
+};
+
} // End of namespace Xeen
#endif /* XEEN_SCRIPTS_H */
diff --git a/engines/xeen/sprites.cpp b/engines/xeen/sprites.cpp
index 448ec0ec57..1d9a5c8abf 100644
--- a/engines/xeen/sprites.cpp
+++ b/engines/xeen/sprites.cpp
@@ -230,6 +230,7 @@ void SpriteResource::drawOffset(XSurface &dest, uint16 offset, const Common::Poi
void SpriteResource::draw(XSurface &dest, int frame, const Common::Point &destPos,
int flags, int scale) const {
+ scale = 0; // ***DEBUG***
if (scale == 0) {
drawOffset(dest, _index[frame]._offset1, destPos, flags);
if (_index[frame]._offset2)
diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp
index 6b73de6939..b8f9030c85 100644
--- a/engines/xeen/xeen.cpp
+++ b/engines/xeen/xeen.cpp
@@ -42,8 +42,10 @@ XeenEngine::XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc)
_files = nullptr;
_interface = nullptr;
_map = nullptr;
+ _party = nullptr;
_saves = nullptr;
_screen = nullptr;
+ _scripts = nullptr;
_sound = nullptr;
_eventData = nullptr;
_loadDarkSide = 1;
@@ -63,8 +65,10 @@ XeenEngine::~XeenEngine() {
delete _events;
delete _interface;
delete _map;
+ delete _party;
delete _saves;
delete _screen;
+ delete _scripts;
delete _sound;
delete _eventData;
delete _files;
@@ -84,8 +88,10 @@ void XeenEngine::initialize() {
_events = new EventsManager(this);
_interface = new Interface(this);
_map = new Map(this);
- _saves = new SavesManager(this, _party, _roster);
+ _party = new Party(this);
+ _saves = new SavesManager(this, *_party, _roster);
_screen = new Screen(this);
+ _scripts = new Scripts(this);
_screen->setupWindows();
_sound = new SoundManager(this);
@@ -281,13 +287,13 @@ void XeenEngine::play() {
if (getGameID() != GType_WorldOfXeen && !_loadDarkSide) {
_loadDarkSide = true;
- _party._mazeId = 29;
- _party._mazeDirection = DIR_NORTH;
- _party._mazePosition.x = 25;
- _party._mazePosition.y = 21;
+ _party->_mazeId = 29;
+ _party->_mazeDirection = DIR_NORTH;
+ _party->_mazePosition.x = 25;
+ _party->_mazePosition.y = 21;
}
- _map->load(_party._mazeId);
+ _map->load(_party->_mazeId);
_interface->startup();
if (_mode == MODE_0) {
@@ -307,9 +313,22 @@ void XeenEngine::play() {
_moveMonsters = true;
+ gameLoop();
+}
+
+void XeenEngine::gameLoop() {
// Main game loop
while (!shouldQuit()) {
- _events->pollEventsAndWait();
+ _map->cellFlagLookup(_party->_mazePosition);
+ if (_map->_currentIsEvent) {
+ _scripts->checkEvents();
+ if (shouldQuit())
+ return;
+ }
+ _scripts->giveTreasure();
+
+ // Wait loop
+ _interface->wait();
}
}
diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h
index e6bcd8c0b7..59816b0d91 100644
--- a/engines/xeen/xeen.h
+++ b/engines/xeen/xeen.h
@@ -41,6 +41,7 @@
#include "xeen/party.h"
#include "xeen/saves.h"
#include "xeen/screen.h"
+#include "xeen/scripts.h"
#include "xeen/sound.h"
/**
@@ -102,6 +103,8 @@ private:
void play();
void pleaseWait();
+
+ void gameLoop();
protected:
/**
* Play the game
@@ -131,14 +134,15 @@ public:
FileManager *_files;
Interface *_interface;
Map *_map;
+ Party *_party;
SavesManager *_saves;
Screen *_screen;
+ Scripts *_scripts;
SoundManager *_sound;
Mode _mode;
GameEvent _gameEvent;
Common::SeekableReadStream *_eventData;
Roster _roster;
- Party _party;
int _loadDarkSide;
bool _dangerSenseAllowed;
int _face1State;