diff options
| -rw-r--r-- | engines/xeen/interface.cpp | 180 | ||||
| -rw-r--r-- | engines/xeen/interface.h | 10 | ||||
| -rw-r--r-- | engines/xeen/interface_map.cpp | 32 | ||||
| -rw-r--r-- | engines/xeen/interface_map.h | 2 | ||||
| -rw-r--r-- | engines/xeen/map.cpp | 47 | ||||
| -rw-r--r-- | engines/xeen/map.h | 3 | ||||
| -rw-r--r-- | engines/xeen/party.cpp | 205 | ||||
| -rw-r--r-- | engines/xeen/party.h | 18 | ||||
| -rw-r--r-- | engines/xeen/resources.cpp | 52 | ||||
| -rw-r--r-- | engines/xeen/resources.h | 4 | ||||
| -rw-r--r-- | engines/xeen/scripts.cpp | 17 | ||||
| -rw-r--r-- | engines/xeen/scripts.h | 15 | ||||
| -rw-r--r-- | engines/xeen/sprites.cpp | 1 | ||||
| -rw-r--r-- | engines/xeen/xeen.cpp | 33 | ||||
| -rw-r--r-- | engines/xeen/xeen.h | 6 | 
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; | 
