[Scummvm-cvs-logs] SF.net SVN: scummvm: [27606] scummvm/trunk/engines/lure

dreammaster at users.sourceforge.net dreammaster at users.sourceforge.net
Fri Jun 22 14:36:15 CEST 2007


Revision: 27606
          http://scummvm.svn.sourceforge.net/scummvm/?rev=27606&view=rev
Author:   dreammaster
Date:     2007-06-22 05:36:04 -0700 (Fri, 22 Jun 2007)

Log Message:
-----------
Lots of bugfixes - game is now completable

Modified Paths:
--------------
    scummvm/trunk/engines/lure/events.cpp
    scummvm/trunk/engines/lure/events.h
    scummvm/trunk/engines/lure/game.cpp
    scummvm/trunk/engines/lure/game.h
    scummvm/trunk/engines/lure/hotspots.cpp
    scummvm/trunk/engines/lure/hotspots.h
    scummvm/trunk/engines/lure/intro.cpp
    scummvm/trunk/engines/lure/intro.h
    scummvm/trunk/engines/lure/lure.cpp
    scummvm/trunk/engines/lure/lure.h
    scummvm/trunk/engines/lure/luredefs.h
    scummvm/trunk/engines/lure/menu.cpp
    scummvm/trunk/engines/lure/menu.h
    scummvm/trunk/engines/lure/res.cpp
    scummvm/trunk/engines/lure/res_struct.cpp
    scummvm/trunk/engines/lure/res_struct.h
    scummvm/trunk/engines/lure/room.cpp
    scummvm/trunk/engines/lure/room.h

Modified: scummvm/trunk/engines/lure/events.cpp
===================================================================
--- scummvm/trunk/engines/lure/events.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/events.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -44,10 +44,10 @@
 
 	_lButton = false; 
 	_rButton = false;
-	_cursorNum = 0;
+	_cursorNum = CURSOR_ARROW;
 	_x = 0;
 	_y = 0;
-	setCursorNum(0);
+	setCursorNum(CURSOR_ARROW);
 }
 
 Mouse::~Mouse() {
@@ -84,7 +84,7 @@
 	CursorMan.showMouse(false);
 }
 
-void Mouse::setCursorNum(uint8 cursorNum) {
+void Mouse::setCursorNum(CursorType cursorNum) {
 	int hotspotX = 7, hotspotY = 7;
 	if ((cursorNum == CURSOR_ARROW) || (cursorNum == CURSOR_MENUBAR)) {
 		hotspotX = 0; 
@@ -94,7 +94,7 @@
 	setCursorNum(cursorNum, hotspotX, hotspotY);
 }
 
-void Mouse::setCursorNum(uint8 cursorNum, int hotspotX, int hotspotY) {
+void Mouse::setCursorNum(CursorType cursorNum, int hotspotX, int hotspotY) {
 	Resources &res = Resources::getReference();
 
 	_cursorNum = cursorNum;
@@ -102,7 +102,7 @@
 	CursorMan.replaceCursor(cursorAddr, CURSOR_WIDTH, CURSOR_HEIGHT, hotspotX, hotspotY, 0);
 }
 
-void Mouse::pushCursorNum(uint8 cursorNum) {
+void Mouse::pushCursorNum(CursorType cursorNum) {
 	int hotspotX = 7, hotspotY = 7;
 	if ((cursorNum == CURSOR_ARROW) || (cursorNum == CURSOR_MENUBAR)) {
 		hotspotX = 0; 
@@ -112,7 +112,7 @@
 	pushCursorNum(cursorNum, hotspotX, hotspotY);
 }
 
-void Mouse::pushCursorNum(uint8 cursorNum, int hotspotX, int hotspotY) {
+void Mouse::pushCursorNum(CursorType cursorNum, int hotspotX, int hotspotY) {
 	Resources &res = Resources::getReference();
 
 	_cursorNum = cursorNum;
@@ -193,4 +193,29 @@
 	}
 }
 
+// interruptableDelay
+// Delays for a given number of milliseconds. If it returns true, it indicates that
+// the Escape has been pressed to abort whatever sequence is being displayed
+
+bool Events::interruptableDelay(uint32 milliseconds) {
+	Events &events = Events::getReference();
+	uint32 delayCtr = g_system->getMillis() + milliseconds;
+
+	while (g_system->getMillis() < delayCtr) {
+		if (events.quitFlag) return true;
+
+		if (events.pollEvent()) {
+			if (events.type() == Common::EVENT_KEYDOWN) 
+				return events.event().kbd.keycode == 27;
+			else if (events.type() == Common::EVENT_LBUTTONDOWN)
+				return false;
+		}
+
+		uint32 delayAmount = delayCtr - g_system->getMillis();
+		if (delayAmount > 10) delayAmount = 10;
+		g_system->delayMillis(delayAmount);
+	}
+	return false;
+}
+
 } // end of namespace Lure

Modified: scummvm/trunk/engines/lure/events.h
===================================================================
--- scummvm/trunk/engines/lure/events.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/events.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -36,7 +36,7 @@
 
 class Mouse {
 private:
-	uint8 _cursorNum;
+	CursorType _cursorNum;
 	int16 _x, _y;
 	bool _lButton, _rButton;
 public:
@@ -47,17 +47,17 @@
 
 	void cursorOn();
 	void cursorOff();
-	void setCursorNum(uint8 cursorNum);
-	void setCursorNum(uint8 cursorNum, int hotspotX, int hotspotY);
-	uint8 getCursorNum() { return _cursorNum; }
+	void setCursorNum(CursorType cursorNum);
+	void setCursorNum(CursorType cursorNum, int hotspotX, int hotspotY);
+	CursorType getCursorNum() { return _cursorNum; }
 	void setPosition(int x, int y);
 	int16 x() { return _x; }
 	int16 y() { return _y; }
 	bool lButton() { return _lButton; }
 	bool rButton() { return _rButton; }
 	void waitForRelease();
-	void pushCursorNum(uint8 cursorNum);
-	void pushCursorNum(uint8 cursorNum, int hotspotX, int hotspotY);	
+	void pushCursorNum(CursorType cursorNum);
+	void pushCursorNum(CursorType cursorNum, int hotspotX, int hotspotY);	
 	void popCursor();
 };
 
@@ -72,6 +72,8 @@
 
 	bool pollEvent();
 	void waitForPress();
+	bool interruptableDelay(uint32 milliseconds);
+
 	Common::Event event() { return _event; }
 	Common::EventType type() { return _event.type; }
 };

Modified: scummvm/trunk/engines/lure/game.cpp
===================================================================
--- scummvm/trunk/engines/lure/game.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/game.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -29,8 +29,10 @@
 #include "lure/scripts.h"
 #include "lure/res_struct.h"
 #include "lure/animseq.h"
+#include "lure/fights.h"
 
 #include "common/config-manager.h"
+#include <sdl_keysym.h>
 
 namespace Lure {
 
@@ -51,20 +53,14 @@
 	delete _debugger;
 }
 
-void Game::nextFrame() {
-	Resources &res = Resources::getReference();
-	ValueTableData &fields = res.fieldList();
-	Room &room = Room::getReference();
-	HotspotList::iterator i;
-
-	res.pausedList().countdown();
-	room.checkCursor();
-	room.update();
-
+void Game::tick() {
 	// Call the tick method for each hotspot - this is somewaht complicated
 	// by the fact that a tick proc can unload both itself and/or others,
 	// so we first get a list of the Ids, and call the tick proc for each 
 	// id in sequence if it's still active
+	Resources &res = Resources::getReference();
+	ValueTableData &fields = res.fieldList();
+	HotspotList::iterator i;
 
 	uint16 *idList = new uint16[res.activeHotspots().size()];
 	int idSize = 0;
@@ -84,6 +80,20 @@
 	debugC(ERROR_DETAILED, kLureDebugAnimations, "Hotspot ticks end");
 
 	delete[] idList;
+}
+
+void Game::nextFrame() {
+	Resources &res = Resources::getReference();
+	Room &room = Room::getReference();
+
+	if (Fights.isFighting()) 
+		Fights.fightLoop();
+
+	res.pausedList().countdown();
+	room.update();
+	room.checkCursor();
+	tick();
+
 	Screen::getReference().update();
 }
 
@@ -137,6 +147,24 @@
 						break;
 					}
 
+					// Handle special keys
+					bool handled = true;
+					switch (events.event().kbd.keycode) {
+						case SDLK_F5:
+							SaveRestoreDialog::show(true);
+							break;
+
+						case SDLK_F7:
+							SaveRestoreDialog::show(false);
+							break;
+
+						default:
+							handled = false;
+					}
+					if (handled)
+						continue;
+
+					// Handle any remaining standard keys
 					switch (events.event().kbd.ascii) {
 					case 27:
 						events.quitFlag = true;
@@ -443,7 +471,7 @@
 			strcat(statusLine, stringList.getString(S_FOR));
 			statusLine += strlen(statusLine);
 
-			itemId = PopupMenu::ShowItems(GET);
+			itemId = PopupMenu::ShowItems(GET, player->roomNumber());
 			breakFlag = ((itemId != 0xffff) && (itemId != 0xfffe));
 			break;
 
@@ -570,6 +598,10 @@
 	_tellCommands[0] = room.hotspotId();
 	_numTellCommands = 0;
 
+	// Set up a room transfer list
+	Common::List<uint16> roomList;
+	roomList.push_front(room.roomNumber());
+
 	// Loop for getting tell commands
 
 	while ((_numTellCommands >= 0) && (_numTellCommands < MAX_TELL_COMMANDS)) {
@@ -618,9 +650,9 @@
 				if (action != RETURN) {
 					// Prompt for selection
 					if ((action != USE) && (action != DRINK) && (action != GIVE)) 
-						selectionId = PopupMenu::ShowItems(action);
+						selectionId = PopupMenu::ShowItems(action, *roomList.begin());
 					else
-						selectionId = PopupMenu::ShowItems(GET);
+						selectionId = PopupMenu::ShowItems(GET, *roomList.begin());
 
 					if ((selectionId == 0xffff) || (selectionId == 0xfffe)) {
 						// Move back to prompting for action
@@ -633,6 +665,7 @@
 					if (selectionId < NOONE_ID) {
 						// Must be a room selection
 						strings.getString(selectionId, selectionName);
+						roomList.push_front(selectionId);
 					} else {
 						hotspot = res.getHotspot(selectionId);
 						assert(hotspot);
@@ -663,7 +696,7 @@
 				}
 
 				// Get the second parameter
-				selectionId = PopupMenu::ShowItems(GET);
+				selectionId = PopupMenu::ShowItems(GET, *roomList.begin());
 				if ((selectionId == 0xfffe) || (selectionId == 0xffff)) {
 					--paramIndex;
 					statusLine = statusLinePos[_numTellCommands][paramIndex];
@@ -712,9 +745,13 @@
 							paramIndex = 0;
 						else if ((action == ASK) || (action == GIVE) || (action == USE))
 							paramIndex = 2;
-						else
+						else {
 							paramIndex = 1;
-					
+							if (action == GO_TO)
+								// Remove top of the cached room change list
+								roomList.erase(roomList.begin());
+						}
+
 						statusLine = statusLinePos[_numTellCommands][paramIndex];
 						*statusLine = '\0';
 					}
@@ -864,10 +901,6 @@
 
 		room.setRoomNumber(2);
 		break;
-
-	default:
-		room.setRoomNumber(value);
-		break;
 	}
 }
 

Modified: scummvm/trunk/engines/lure/game.h
===================================================================
--- scummvm/trunk/engines/lure/game.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/game.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -39,7 +39,7 @@
 
 namespace Lure {
 
-enum GameState {GS_RESTORE_RESTART = 1, GS_CAUGHT = 2};
+enum GameState {GS_RESTORE_RESTART = 1, GS_CAUGHT = 2, GS_EXIT = 3};
 
 class Game {
 private:
@@ -66,6 +66,7 @@
 
 	static Game &getReference();
 
+	void tick();
 	void nextFrame();
 	void execute();
 	void setState(uint8 flags) { _state = flags; }

Modified: scummvm/trunk/engines/lure/hotspots.cpp
===================================================================
--- scummvm/trunk/engines/lure/hotspots.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/hotspots.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -34,6 +34,7 @@
 #include "lure/res_struct.h"
 #include "lure/events.h"
 #include "lure/game.h"
+#include "lure/fights.h"
 #include "common/endian.h"
 
 namespace Lure {
@@ -108,6 +109,7 @@
 	_exitCtr = 0;
 	_voiceCtr = 0;
 	_walkFlag = false;
+	_skipFlag = false;
 
 	switch (objType) {
 	case VOICE_ANIM_ID:
@@ -171,6 +173,9 @@
 	Resources &r = Resources::getReference();
 	HotspotAnimData *tempAnim;
 	_animId = newAnimId;
+	if (_data)
+		_data->animRecordId = newAnimId;
+
 	if (newAnimId == 0) 
 		tempAnim = NULL;
 	else {
@@ -217,30 +222,29 @@
 	_anim = newRecord;
 	MemoryBlock *src = Disk::getReference().getEntry(_anim->animId);
 	
-	uint16 *numEntries = (uint16 *) src->data();
+	uint16 numEntries = READ_LE_UINT16(src->data());
 	uint16 *headerEntry = (uint16 *) (src->data() + 2);
-	assert((*numEntries >= 1) && (*numEntries < 100));
+	assert((numEntries >= 1) && (numEntries < 100));
 
 	// Calculate total needed size for output and create memory block to hold it
 	uint32 totalSize = 0;
-	for (uint16 ctr = 0; ctr < *numEntries; ++ctr, ++headerEntry) {
-		totalSize += (*headerEntry + 31) / 32;
+	for (uint16 ctr = 0; ctr < numEntries; ++ctr, ++headerEntry) {
+		totalSize += (READ_LE_UINT16(headerEntry) + 31) / 32;
 	}
 	totalSize = (totalSize + 0x81) << 4;
 	MemoryBlock *dest = Memory::allocate(totalSize);
 
-	uint32 srcStart = (*numEntries + 1) * sizeof(uint16) + 6;
+	uint32 srcStart = (numEntries + 1) * sizeof(uint16) + 6;
 	AnimationDecoder::decode_data(src, dest, srcStart);
 
-	_numFrames = *numEntries;
+	_numFrames = numEntries;
 	_frameNumber = 0;
 	
 	// Special handling need
 	if (newRecord->animRecordId == SERF_ANIM_ID) {
 		_frameStartsUsed = true;
 		_frames = new Surface(416, 27);
-	}
-	else {
+	} else {
 		_frames = new Surface(_width * _numFrames, _height);
 		_frameStartsUsed = false;
 	}
@@ -350,7 +354,7 @@
 			return;
 
 		// Reduce the source rectangle to only the on-screen portion
-		r.top += -(yPos + MENUBAR_Y_SIZE);
+		r.top += -yPos + MENUBAR_Y_SIZE;
 		yPos = MENUBAR_Y_SIZE;
 	}
 	else if (yPos >= FULL_SCREEN_HEIGHT)
@@ -414,9 +418,10 @@
 }
 
 void Hotspot::tick() {
-	debugC(ERROR_BASIC, kLureDebugAnimations, "Hotspot %xh tick begin", _hotspotId);
+	uint16 id = _hotspotId;
+	debugC(ERROR_BASIC, kLureDebugAnimations, "Hotspot %xh tick begin", id);
 	_tickHandler(*this);
-	debugC(ERROR_BASIC, kLureDebugAnimations, "Hotspot %xh tick end", _hotspotId);
+	debugC(ERROR_BASIC, kLureDebugAnimations, "Hotspot %xh tick end", id);
 }
 
 void Hotspot::setTickProc(uint16 newVal) {
@@ -828,7 +833,7 @@
 	} else if (hotspot->roomNumber != roomNumber()) {
 		// loc_884
 		if (actionCtr() == 0) 
-			converse(0, hotspotId());
+			converse(NOONE_ID, 0);
 		setActionCtr(0);
 		return PC_NOT_IN_ROOM;
 	} else if (actionCtr() != 0) {
@@ -992,7 +997,6 @@
 	}
 
 	// Default walking handling
-	// TODO: ANIM[27h] = 1 if hotspot has walk co-ordinates
 	if ((ABS(x() - xp) >= 8) ||
 		(ABS(y() + heightCopy() - yp - 1) >= 19)) {
 		walkTo(xp, yp);
@@ -1242,7 +1246,8 @@
 		joinRec->blocked = 0;
 
 		if (hotspotId() != PLAYER_ID) {
-			// TODO: HS[44h]=3, HS[42h]W = 4
+			setCharacterMode(CHARMODE_PAUSED);
+			setDelayCtr(4);
 		}
 	}
 }
@@ -1465,8 +1470,8 @@
 			character->setBlockedFlag(false);
 
 			for (int index = 1; index < cmdData.numParams(); index += 3) {
-				character->currentActions().addBack((Action) cmdData.param(index),
-					character->roomNumber(), cmdData.param(index + 1), cmdData.param(index + 2));
+				character->currentActions().addBack((Action) cmdData.param(index), 0,
+					cmdData.param(index + 1), cmdData.param(index + 2));
 			}
 		}
 	}
@@ -1966,8 +1971,8 @@
 	Resources &res = Resources::getReference();
 	ValueTableData &fields = res.fieldList();
 	int procIndex = _currentActions.top().supportData().param(0);
-	HotspotData *player;
-	CharacterScheduleEntry *newEntry;
+	Hotspot *player;
+	CharacterScheduleEntry *entry;
 	endAction();
 
 	switch (procIndex) {
@@ -1980,9 +1985,14 @@
 		break;
 
 	case 1:
-		player = res.getHotspot(PLAYER_ID);
-		newEntry = res.charSchedules().getEntry(JUMP_ADDR_2_SUPPORT_ID, NULL);
-		_currentActions.top().setSupportData(newEntry);
+		player = res.getActiveHotspot(PLAYER_ID);
+		if (player->y() < 52) {
+			entry = res.charSchedules().getEntry(JUMP_ADDR_2_SUPPORT_ID, NULL);
+			assert(entry);
+
+			_currentActions.clear();
+			_currentActions.addFront(DISPATCH_ACTION, entry, ROOMNUM_CELLAR);
+		}
 		break;
 
 	default:
@@ -2131,9 +2141,11 @@
 	case PLAYER_TICK_PROC_ID:
 		return playerAnimHandler;
 	case 0x7C14:
+	case FOLLOWER_TICK_PROC_2:
 		return followerAnimHandler;
-	case 0x7EFA:
-		return skorlAnimHandler;
+	case JAILOR_TICK_PROC_ID:
+	case 0x7F02:
+		return jailorAnimHandler;
 	case STANDARD_ANIM_2_TICK_PROC:
 		return standardAnimHandler2;
 	case STANDARD_ANIM_TICK_PROC:
@@ -2163,16 +2175,30 @@
 	case 0x82A0:
 		return barmanAnimHandler;
 	case 0x85ce:
-		return skorlGaurdAnimHandler;
+		return skorlAnimHandler;
 	case 0x862D:
 		return gargoyleAnimHandler;
+	case GOEWIN_SHOP_TICK_PROC:
+		return goewinShopAnimHandler;
 	case 0x86FA:
 	case 0x86FF:
+	case 0x871E:
+	case 0x873D:
+	case 0x8742:
+	case 0x8747:
 		return skullAnimHandler;
+	case 0x87B3:
+		return dragonFireAnimHandler;
+	case 0x87EC:
+		return castleSkorlAnimHandler;
 	case 0x882A:
 		return rackSerfAnimHandler;
 	case TALK_TICK_PROC_ID:
 		return talkAnimHandler;
+	case 0x982D:
+		return fighterAnimHandler;
+	case PLAYER_FIGHT_TICK_PROC_ID:
+		return playerFightAnimHandler;
 	default:
 		error("Unknown tick proc %xh for hotspot", procOffset);
 //		return defaultHandler;
@@ -2493,25 +2519,25 @@
 	debugC(ERROR_DETAILED, kLureDebugAnimations, 
 		"Voice Bubble anim handler: char = %xh, ctr = %d, char speaking ctr = %d", 
 		h.hotspotId(), h.voiceCtr(), 
-		res.getActiveHotspot(res.getTalkingCharacter())->resource()->talkCountdown);
+		res.getHotspot(res.getTalkingCharacter())->talkCountdown);
 
 	if (h.voiceCtr() != 0) 
 		h.setVoiceCtr(h.voiceCtr() - 1);
 
 	if (h.voiceCtr() != 0) {
 		// Countdown not yet ended
-		Hotspot *charHotspot = res.getActiveHotspot(res.getTalkingCharacter());
-		if (charHotspot->roomNumber() == h.roomNumber()) {
+		HotspotData *charHotspot = res.getHotspot(res.getTalkingCharacter());
+		if (charHotspot->roomNumber == h.roomNumber()) {
 			// Character is still in the same room as when it began speaking
-			if (charHotspot->resource()->talkCountdown != 0) {
+			if (charHotspot->talkCountdown != 0) {
 				// Character still talking
-				if (!res.checkHotspotExtent(charHotspot->resource())) {
+				if (!res.checkHotspotExtent(charHotspot)) {
 					// Set voice bubble off screen to hide it
 					h.setPosition(h.x(), -100);
 				} else {
 					// Keep voice bubble in track with character
-					h.setPosition(charHotspot->x() + charHotspot->talkX() + 12,
-						charHotspot->y() + charHotspot->talkY() - 18);
+					h.setPosition(charHotspot->startX + charHotspot->talkX + 12,
+						charHotspot->startY + charHotspot->talkY - 18);
 				}
 				return;
 			}
@@ -2796,8 +2822,8 @@
 	ValueTableData &fields = res.fieldList();
 	Hotspot *player = res.getActiveHotspot(PLAYER_ID);
 
-	if ((fields.getField(37) == 0) && h.currentActions().isEmpty()) {
-		if (h.roomNumber() != player->roomNumber()) {
+	if ((h.resource()->tickProcOffset == FOLLOWER_TICK_PROC_2) || (fields.getField(37) == 0)) {
+		if (h.currentActions().isEmpty() && (h.roomNumber() != player->roomNumber())) {
 			// Character in different room than player
 			if (h.hotspotId() == GOEWIN_ID) 
 				h.currentActions().addFront(DISPATCH_ACTION, player->roomNumber());
@@ -2872,18 +2898,17 @@
 	standardCharacterAnimHandler(h);
 }
 
-void HotspotTickHandlers::skorlAnimHandler(Hotspot &h) {
+void HotspotTickHandlers::jailorAnimHandler(Hotspot &h) {
 	Resources &res = Resources::getReference();
 	ValueTableData &fields = res.fieldList();
 	HotspotData *player = res.getHotspot(PLAYER_ID);
 
-	if ((fields.getField(11) != 0) && !h.skipFlag() && 
-		(h.roomNumber() == player->roomNumber)) {
-		// TODO: Need extra check on data_669
-
-		if (Support::charactersIntersecting(h.resource(), player)) {
-			// Skorl has caught the player
-			Game::getReference().setState(GS_RESTORE_RESTART | GS_CAUGHT);
+	if ((fields.getField(11) != 0) || (h.hotspotId() == CASTLE_SKORL_ID)) {
+		if (!h.skipFlag() && (h.roomNumber() == player->roomNumber)) {
+			if (Support::charactersIntersecting(h.resource(), player)) {
+				// Skorl has caught the player
+				Game::getReference().setState(GS_RESTORE_RESTART | GS_CAUGHT);
+			}
 		}
 	}
 
@@ -3290,6 +3315,14 @@
 	}
 }
 
+void HotspotTickHandlers::fighterAnimHandler(Hotspot &h) {
+	Fights.fighterAnimHandler(h);
+}
+
+void HotspotTickHandlers::playerFightAnimHandler(Hotspot &h) {
+	Fights.playerAnimHandler(h);
+}
+
 void HotspotTickHandlers::grubAnimHandler(Hotspot &h) {
 	Resources &res = Resources::getReference();
 	h.handleTalkDialog();
@@ -3521,10 +3554,8 @@
 	h.setFrameNumber(h.actionCtr());
 }
 
-void HotspotTickHandlers::skorlGaurdAnimHandler(Hotspot &h) {
+void HotspotTickHandlers::skorlAnimHandler(Hotspot &h) {
 	h.handleTalkDialog();
-
-	// Set the frame number
 	h.setFrameNumber(h.actionCtr());
 }
 
@@ -3532,14 +3563,82 @@
 	h.handleTalkDialog();
 }
 
+void HotspotTickHandlers::goewinShopAnimHandler(Hotspot &h) {
+	Resources &res = Resources::getReference();
+	ValueTableData &fields = res.fieldList();
+
+	h.setDirection(UP);
+	h.setCharacterMode(CHARMODE_WAIT_FOR_INTERACT);
+
+	h.handleTalkDialog();
+	if (h.frameCtr() > 0) {
+		h.decrFrameCtr();
+		return;
+	}
+
+	h.executeScript();
+
+	if (h.delayCtr() > 0) {
+		h.setDelayCtr(h.delayCtr() - 1);
+
+		if (h.delayCtr() == 0) {
+			Hotspot *playerHotspot = res.getActiveHotspot(PLAYER_ID);
+			uint16 talkIndex = fields.getField(TALK_INDEX);
+
+			if ((talkIndex == 12) || (talkIndex == 13) || (talkIndex == 14) ||
+				(playerHotspot->roomNumber() == 34))
+				h.setDelayCtr(1500);
+			else 
+				Script::normalGoewin(0, 0, 0);
+		}
+	}
+}
+
 void HotspotTickHandlers::skullAnimHandler(Hotspot &h) {
 	Resources &res = Resources::getReference();
-	RoomExitJoinData *joinRec = res.getExitJoin(
-		(h.hotspotId() == 0x42f) ? 0x272A : 0x272C);
+	uint16 doorId = 0x272E;
+	if ((h.hotspotId() == 0x42E) || (h.hotspotId() == 0x431) || (h.hotspotId() == 0x432))
+		doorId = 0x272A;
+	else if ((h.hotspotId() == 0x42f) || (h.hotspotId() == 0x433))
+		doorId = 0x272C;
 
-	h.setFrameNumber(joinRec->blocked ? 0 : 1);
+	RoomExitJoinData *joinRec = res.getExitJoin(doorId);
+	if ((h.hotspotId() == 0x42E) || (h.hotspotId() == 0x42F)) {
+		h.setFrameNumber(joinRec->blocked ? 0 : 1);
+	} else {
+		h.setFrameNumber(joinRec->blocked ? 1 : 0);
+	}
 }
 
+void HotspotTickHandlers::dragonFireAnimHandler(Hotspot &h) {
+	if (h.executeScript()) 
+		// Script is finished - player is dead
+		Game::getReference().setState(GS_RESTORE_RESTART);
+}
+
+void HotspotTickHandlers::castleSkorlAnimHandler(Hotspot &h) {
+	Resources &res = Resources::getReference();
+
+	h.handleTalkDialog();
+	if (h.frameCtr() > 0) {
+		h.decrFrameCtr();
+		return;
+	}
+
+	if (h.executeScript()) {
+		HotspotData *hotspot = res.getHotspot(h.hotspotId());
+		assert(hotspot);
+		res.deactivateHotspot(hotspot->hotspotId);
+		hotspot->layer = 255;
+		hotspot->talkCountdown = 0;
+		hotspot->flags |= HOTSPOTFLAG_MENU_EXCLUSION;
+
+		hotspot = res.getHotspot(CASTLE_SKORL_ID);
+		hotspot->roomNumber = 45;
+		res.activateHotspot(CASTLE_SKORL_ID);
+	}
+}
+
 void HotspotTickHandlers::rackSerfAnimHandler(Hotspot &h) {
 	Resources &res = Resources::getReference();
 

Modified: scummvm/trunk/engines/lure/hotspots.h
===================================================================
--- scummvm/trunk/engines/lure/hotspots.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/hotspots.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -67,7 +67,7 @@
 	static void roomExitAnimHandler(Hotspot &h);
 	static void playerAnimHandler(Hotspot &h);
 	static void followerAnimHandler(Hotspot &h);
-	static void skorlAnimHandler(Hotspot &h);
+	static void jailorAnimHandler(Hotspot &h);
 	static void sonicRatAnimHandler(Hotspot &h);
 	static void droppingTorchAnimHandler(Hotspot &h);
 	static void playerSewerExitAnimHandler(Hotspot &h);
@@ -81,11 +81,15 @@
 	static void talkAnimHandler(Hotspot &h);
 	static void grubAnimHandler(Hotspot &h);
 	static void barmanAnimHandler(Hotspot &h);
-	static void skorlGaurdAnimHandler(Hotspot &h);
+	static void skorlAnimHandler(Hotspot &h);
 	static void gargoyleAnimHandler(Hotspot &h);
+	static void goewinShopAnimHandler(Hotspot &h);
 	static void skullAnimHandler(Hotspot &h);
+	static void dragonFireAnimHandler(Hotspot &h);
+	static void castleSkorlAnimHandler(Hotspot &h);
 	static void rackSerfAnimHandler(Hotspot &h);
-
+	static void fighterAnimHandler(Hotspot &h);
+	static void playerFightAnimHandler(Hotspot &h);
 public:
 	static HandlerMethodPtr getHandler(uint16 procOffset);
 };
@@ -129,6 +133,10 @@
 class CurrentActionStack {
 private:
 	ManagedList<CurrentActionEntry *> _actions;
+	void validateStack() { 
+		if (_actions.size() > 20) 
+			error("NPC character got an excessive number of pending actions");
+	}
 public:
 	CurrentActionStack() { _actions.clear(); }
 
@@ -143,21 +151,27 @@
 
 	void addBack(CurrentAction newAction, uint16 roomNum) {
 		_actions.push_back(new CurrentActionEntry(newAction, roomNum));
+		validateStack();
 	}
 	void addBack(CurrentAction newAction, CharacterScheduleEntry *rec, uint16 roomNum) {
 		_actions.push_back(new CurrentActionEntry(newAction, rec, roomNum));
+		validateStack();
 	}
 	void addBack(Action newAction, uint16 roomNum, uint16 param1, uint16 param2) {
 		_actions.push_back(new CurrentActionEntry(newAction, roomNum, param1, param2));
+		validateStack();
 	}
 	void addFront(CurrentAction newAction, uint16 roomNum) {
 		_actions.push_front(new CurrentActionEntry(newAction, roomNum));
+		validateStack();
 	}
 	void addFront(CurrentAction newAction, CharacterScheduleEntry *rec, uint16 roomNum) {
 		_actions.push_front(new CurrentActionEntry(newAction, rec, roomNum));
+		validateStack();
 	}
 	void addFront(Action newAction, uint16 roomNum, uint16 param1, uint16 param2) {
 		_actions.push_front(new CurrentActionEntry(newAction, roomNum, param1, param2));
+		validateStack();
 	}
 
 	void saveToStream(WriteStream *stream);
@@ -373,6 +387,8 @@
 	void setTickProc(uint16 newVal);
 	bool persistant() { return _persistant; }
 	void setPersistant(bool value) { _persistant = value; }
+	uint8 colourOffset() { return _colourOffset; }
+	void setColourOffset(uint8 value) { _colourOffset = value; }
 	void setRoomNumber(uint16 roomNum) { 
 		_roomNumber = roomNum; 
 		if (_data) _data->roomNumber = roomNum;

Modified: scummvm/trunk/engines/lure/intro.cpp
===================================================================
--- scummvm/trunk/engines/lure/intro.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/intro.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -47,47 +47,24 @@
 // should be aborted
 
 bool Introduction::showScreen(uint16 screenId, uint16 paletteId, uint16 delaySize) {
+	Events &events = Events::getReference();
 	_screen.screen().loadScreen(screenId);
 	_screen.update();
 	Palette p(paletteId);
 	_screen.paletteFadeIn(&p);
 	
-	bool result = delay(delaySize);
-	if (Events::getReference().quitFlag) return true;
+	bool result = events.interruptableDelay(delaySize);
+	if (events.quitFlag) return true;
 
 	_screen.paletteFadeOut();
 	return result;
 }
 
-// delay
-// Delays for a given number of milliseconds. If it returns true, it indicates that
-// Escape has been pressed, and the introduction should be aborted.
-
-bool Introduction::delay(uint32 milliseconds) {
-	Events &events = Events::getReference();
-	uint32 delayCtr = _system.getMillis() + milliseconds;
-
-	while (_system.getMillis() < delayCtr) {
-		if (events.quitFlag) return true;
-
-		if (events.pollEvent()) {
-			if (events.type() == Common::EVENT_KEYDOWN) 
-				return events.event().kbd.keycode == 27;
-			else if (events.type() == Common::EVENT_LBUTTONDOWN)
-				return false;
-		}
-
-		uint32 delayAmount = delayCtr - _system.getMillis();
-		if (delayAmount > 10) delayAmount = 10;
-		_system.delayMillis(delayAmount);
-	}
-	return false;
-}
-
 // show
 // Main method for the introduction sequence
 
 bool Introduction::show() {
+	Events &events = Events::getReference();
 	_screen.setPaletteEmpty();
 
 	// Initial game company and then game screen
@@ -109,13 +86,13 @@
 		anim = new AnimationSequence(_screen, _system, curr_anim->resourceId, 
 			coll.getPalette(curr_anim->paletteIndex), fadeIn);
 		if (curr_anim->initialPause) 
-			if (delay(12000)) return true;
+			if (events.interruptableDelay(12000)) return true;
 
 		result = false;
 		switch (anim->show()) {
 			case ABORT_NONE:
 				if (curr_anim->endingPause) {
-					result = delay(12000);
+					result = events.interruptableDelay(12000);
 				}
 				break;
 
@@ -136,9 +113,9 @@
 	result = false;
 	anim = new AnimationSequence(_screen, _system, 0x48, coll.getPalette(4), false);
 	do {
-		result = delay(2000);
+		result = events.interruptableDelay(2000);
 		_screen.paletteFadeOut();
-		if (!result) result = delay(500);
+		if (!result) result = events.interruptableDelay(500);
 		if (result) break;
 	} while (anim->step());
 	delete anim;

Modified: scummvm/trunk/engines/lure/intro.h
===================================================================
--- scummvm/trunk/engines/lure/intro.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/intro.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -36,7 +36,6 @@
 	OSystem &_system;
 
 	bool showScreen(uint16 screenId, uint16 paletteId, uint16 delaySize);
-	bool delay(uint32 milliseconds);
 public:
 	Introduction(Screen &screen, OSystem &system): _screen(screen), _system(system) {}
 

Modified: scummvm/trunk/engines/lure/lure.cpp
===================================================================
--- scummvm/trunk/engines/lure/lure.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/lure.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -44,6 +44,8 @@
 	Common::addSpecialDebugLevel(kLureDebugScripts, "scripts", "Scripts debugging");
 	Common::addSpecialDebugLevel(kLureDebugAnimations, "animations", "Animations debugging");
 	Common::addSpecialDebugLevel(kLureDebugHotspots, "hotspots", "Hotspots debugging");
+	Common::addSpecialDebugLevel(kLureDebugFights, "fights", "Fights debugging");
+
 	// Setup mixer
 /*
 	if (!_mixer->isReady()) {
@@ -75,6 +77,7 @@
 	_menu = new Menu();
 	Surface::initialise();
 	_room = new Room();
+	_fights = new FightsManager();
 	int_engine = this;
 	return 0;
 }
@@ -85,6 +88,7 @@
 
 	// Delete and deinitialise subsystems
 	Surface::deinitialise();
+	delete _fights;
 	delete _room;
 	delete _menu;
 	delete _events;
@@ -146,6 +150,7 @@
 
 	Resources::getReference().saveToStream(f);
 	Room::getReference().saveToStream(f);
+	Fights.saveToStream(f);
 
 	delete f;
 	return true;
@@ -187,6 +192,7 @@
 	// Load in the data
 	Resources::getReference().loadFromStream(f);
 	Room::getReference().loadFromStream(f);
+	Fights.loadFromStream(f);
 
 	delete f;
 	return true;

Modified: scummvm/trunk/engines/lure/lure.h
===================================================================
--- scummvm/trunk/engines/lure/lure.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/lure.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -38,6 +38,7 @@
 #include "lure/menu.h"
 #include "lure/strings.h"
 #include "lure/room.h"
+#include "lure/fights.h"
 
 namespace Lure {
 
@@ -54,6 +55,7 @@
 	Menu *_menu;
 	StringData *_strings;
 	Room *_room;
+	FightsManager *_fights;
 
 	void detectGame();
 	const char *generateSaveName(int slotNumber);

Modified: scummvm/trunk/engines/lure/luredefs.h
===================================================================
--- scummvm/trunk/engines/lure/luredefs.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/luredefs.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -34,7 +34,7 @@
 
 #define SUPPORT_FILENAME "lure.dat"
 #define LURE_DAT_MAJOR 1
-#define LURE_DAT_MINOR 19
+#define LURE_DAT_MINOR 20
 
 #define LURE_DEBUG 1
 
@@ -44,7 +44,8 @@
 enum {
 	kLureDebugScripts = 1 << 0,
 	kLureDebugAnimations = 1 << 1,
-	kLureDebugHotspots = 1 << 2
+	kLureDebugHotspots = 1 << 2,
+	kLureDebugFights = 1 << 3
 };
 
 #define ERROR_BASIC 1
@@ -126,6 +127,9 @@
 // Palette and animation for hiding in barrel
 #define BARREL_PALETTE_ID 0xE9F0
 #define BARREL_ANIM_ID 0xE9F1
+// Endgame animation constants
+#define ENDGAME_PALETTE_ID 0xFF00
+#define ENDGAME_ANIM_ID 0xFF01
 
 // Specifies the maximum buffer sized allocated for decoding animation data
 #define MAX_ANIM_DECODER_BUFFER_SIZE 300000
@@ -142,15 +146,13 @@
 #define CURSOR_HEIGHT 16
 #define CURSOR_SIZE 256
 #define CURSOR_RESOURCE_ID 1
-#define CURSOR_ARROW 0
-#define CURSOR_DISK 1
-#define CURSOR_TIME_START 2
-#define CURSOR_TIME_END 9
-#define CURSOR_CROSS 10
-#define CURSOR_CAMERA 15
-#define CURSOR_TALK 16
-#define CURSOR_MENUBAR 17
 
+enum CursorType {CURSOR_ARROW = 0, CURSOR_DISK = 1, CURSOR_TIME_START = 2,
+	CURSOR_TIME_END = 9, CURSOR_CROSS = 10, CURSOR_UP_ARROW = 11, CURSOR_DOWN_ARROW = 12,
+	CURSOR_LEFT_ARROW = 13, CURSOR_RIGHT_ARROW = 14, CURSOR_CAMERA = 15, CURSOR_TALK = 16,
+	CURSOR_MENUBAR = 17, CURSOR_FIGHT_UPPER = 23, CURSOR_FIGHT_MIDDLE = 24, 
+	CURSOR_FIGHT_LOWER = 25};
+
 // Font details
 #define FONT_RESOURCE_ID 4
 #define NUM_CHARS_IN_FONT 122
@@ -216,7 +218,8 @@
 #define ROOM_PATHS_RESOURCE_ID 0x3f13
 #define EXIT_COORDINATES_RESOURCE_ID 0x3f14
 #define EXIT_HOTSPOT_ID_LIST 0x3f15
-#define STRING_LIST_RESOURCE_ID 0x3f16
+#define FIGHT_DATA_RESOURCE_ID 0x3f16
+#define STRING_LIST_RESOURCE_ID 0x3f17
 
 // Script constants
 #define STARTUP_SCRIPT 0x23FC
@@ -230,6 +233,8 @@
 #define SKORL_ID 0x3EA
 #define BLACKSMITH_ID 0x3EB
 #define GOEWIN_ID 0x3EF
+#define WAYNE_ID 0x3f1
+#define CASTLE_SKORL_ID 0x3F3
 #define FIRST_NONCHARACTER_ID 0x408
 #define SACK_ID 0x40D
 #define PRISONER_ID 0x412
@@ -238,10 +243,12 @@
 #define TRANSFORM_ID 0x425
 #define NELLIE_ID 0x429
 #define EWAN_ID 0x436
-#define WAYNE_ID 0x3f1
+#define PIG_ID 0x43F
+#define SKORL_FIGHTER_ID 0x444
 #define START_EXIT_ID 0x2710
 #define BOTTLE_HOTSPOT_ID 0x2710
 #define BRICKS_ID 0x2714
+#define BOOK_ID 0x2723
 #define START_NONVISUAL_HOTSPOT_ID 0x7530
 
 // Milliseconds delay between game frames
@@ -252,9 +259,13 @@
 #define PLAYER_TICK_PROC_ID 0x5E44
 #define VOICE_TICK_PROC_ID 0x625E
 #define PUZZLED_TICK_PROC_ID 0x6571
+#define FOLLOWER_TICK_PROC_2 0x7C24
+#define JAILOR_TICK_PROC_ID 0x7efa
 #define STANDARD_ANIM_2_TICK_PROC 0x7F37
 #define STANDARD_ANIM_TICK_PROC 0x7f3a
+#define GOEWIN_SHOP_TICK_PROC 0x865A
 #define TALK_TICK_PROC_ID 0x8ABD
+#define PLAYER_FIGHT_TICK_PROC_ID 0x98B6
 
 // String constants
 #define STRANGER_ID 0x17A
@@ -263,6 +274,7 @@
 
 // Misc constants
 #define GENERAL_MAGIC_ID 42
+#define PLAYER_FIGHT_ANIM_ID 0x55F6
 #define VOICE_ANIM_ID 0x5810
 #define PUZZLED_ANIM_ID 0x8001
 #define EXCLAMATION_ANIM_ID 0x8002
@@ -279,6 +291,10 @@
 #define MAX_TELL_COMMANDS 8
 #define MAX_SAVEGAME_SLOTS 10
 
+#define ROOMNUM_CAVE 38
+#define ROOMNUM_CELLAR 42
+#define ROOMNUM_DINING_HALL 45
+
 // Countdown for # operations in path finder before breaking until next
 // tick - set it to 0 if you'd like all pathfinding to be done at once
 //#define PATHFIND_COUNTDOWN 4000
@@ -290,12 +306,15 @@
 // Hotspot flags
 #define HOTSPOTFLAG_FOUND 0x80
 #define HOTSPOTFLAG_SKIP 0x40
-#define HOTSPOTFLAG_20 0x20
+#define HOTSPOTFLAG_MENU_EXCLUSION 0x20
+#define HOTSPOTFLAG_ROOM_SPECIFIC 0x10
 
 // Constants used to reference entries in the reworked support data entry lists
 #define RETURN_SUPPORT_ID 0x400
 #define EXIT_BLOCKED_SUPPORT_ID 0x800
 #define JUMP_ADDR_2_SUPPORT_ID 0x1403
+#define GOEWIN_CAVE_SUPPORT_ID 0x1800
+#define GOEWIN_STANDARD_SUPPORT_ID 0x1C00
 
 // Constants used in animation Serf on the rack
 #define RACK_SERF_SCRIPT_ID_1 0x35C

Modified: scummvm/trunk/engines/lure/menu.cpp
===================================================================
--- scummvm/trunk/engines/lure/menu.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/menu.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -257,7 +257,7 @@
 
 #define MAX_NUM_DISPLAY_ITEMS 20
 
-uint16 PopupMenu::ShowItems(Action contextAction) {
+uint16 PopupMenu::ShowItems(Action contextAction, uint16 roomNumber) {
 	Resources &res = Resources::getReference();
 	ValueTableData &fields = res.fieldList();
 	RoomDataList &rooms = res.roomData();
@@ -273,7 +273,6 @@
 	char *entryNames[MAX_NUM_DISPLAY_ITEMS];
 	int numItems = 0;
 	int itemCtr;
-	Hotspot *player = res.getActiveHotspot(PLAYER_ID);
 	uint32 contextBitflag = 1 << (contextAction - 1);
 
 	// Loop for rooms
@@ -282,7 +281,7 @@
 		// Pre-condition checks for whether to skip room
 		if ((roomData->hdrFlags != 15) && ((roomData->hdrFlags & fields.hdrFlagMask()) == 0))
 			continue;
-		if (((roomData->flags & HOTSPOTFLAG_20) != 0) || ((roomData->flags & HOTSPOTFLAG_FOUND) == 0))
+		if (((roomData->flags & HOTSPOTFLAG_MENU_EXCLUSION) != 0) || ((roomData->flags & HOTSPOTFLAG_FOUND) == 0))
 			continue;
 		if ((roomData->actions & contextBitflag) == 0)
 			continue;
@@ -304,20 +303,21 @@
 			((hotspot->headerFlags & fields.hdrFlagMask()) == 0))
 			continue;
 
-		if (((hotspot->flags & HOTSPOTFLAG_20) != 0) || ((hotspot->flags & HOTSPOTFLAG_FOUND) == 0))
+		if (((hotspot->flags & HOTSPOTFLAG_MENU_EXCLUSION) != 0) || ((hotspot->flags & HOTSPOTFLAG_FOUND) == 0))
 			// Skip the current hotspot		
 			continue;
 
-		// Following checks are done for room list - still need to include check against [3350h]
-		if (((hotspot->flags & 0x10) != 0) && (hotspot->roomNumber != player->roomNumber()))
+		// If the hotspot is room specific, skip if the character will not be in the specified room
+		if (((hotspot->flags & HOTSPOTFLAG_ROOM_SPECIFIC) != 0) && 
+			(hotspot->roomNumber != roomNumber))
 			continue;
 
+		// If hotspot does not allow action, then skip it
 		if ((hotspot->actions & contextBitflag) == 0)
-			// If hotspot does not allow action, then skip it
 			continue;
 
+		// If a special hotspot Id, then skip displaying
 		if ((hotspot->nameId == 0x17A) || (hotspot->nameId == 0x147))
-			// Special hotspot names to skip 
 			continue;
 
 		// Check if the hotspot's name is already used in an already set item

Modified: scummvm/trunk/engines/lure/menu.h
===================================================================
--- scummvm/trunk/engines/lure/menu.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/menu.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -83,7 +83,7 @@
 	static Action Show(int numEntries, Action *actions);
 	static uint16 Show(int numEntries, const char *actions[]);
 	static uint16 ShowInventory();
-	static uint16 ShowItems(Action contextAction);
+	static uint16 ShowItems(Action contextAction, uint16 roomNumber);
 };
 
 } // End of namespace Lure

Modified: scummvm/trunk/engines/lure/res.cpp
===================================================================
--- scummvm/trunk/engines/lure/res.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/res.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -268,7 +268,7 @@
 	// Load in the list of room exit coordinates
 	mb = d.getEntry(EXIT_COORDINATES_RESOURCE_ID);
 	RoomExitCoordinateEntryResource *coordRec = (RoomExitCoordinateEntryResource *) mb->data();	
-	while (*((uint16 *) coordRec) != 0xffff) {
+	while (READ_LE_UINT16(coordRec) != 0xffff) {
 		RoomExitCoordinates *newEntry = new RoomExitCoordinates(coordRec);
 		_coordinateList.push_back(newEntry);
 		++coordRec;

Modified: scummvm/trunk/engines/lure/res_struct.cpp
===================================================================
--- scummvm/trunk/engines/lure/res_struct.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/res_struct.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -94,6 +94,8 @@
 
 	clippingXStart = FROM_LE_16(rec->clippingXStart);
 	clippingXEnd = FROM_LE_16(rec->clippingXEnd);
+	exitTime = FROM_LE_32(rec->exitTime);
+	areaFlag = rec->areaFlag;
 	walkBounds.left = FROM_LE_16(rec->walkBounds.xs);
 	walkBounds.right = FROM_LE_16(rec->walkBounds.xe);
 	walkBounds.top = FROM_LE_16(rec->walkBounds.ys);
@@ -285,6 +287,7 @@
 
 	for (i = begin(); i != end(); ++i) {
 		RoomData *rec = *i;
+		stream->writeByte(rec->flags);
 		const byte *pathData = rec->paths.data();
 		stream->write(pathData, ROOM_PATHS_HEIGHT * ROOM_PATHS_WIDTH);
 	}
@@ -296,6 +299,7 @@
 
 	for (i = begin(); i != end(); ++i) {
 		RoomData *rec = *i;
+		rec->flags = stream->readByte();
 		stream->read(data, ROOM_PATHS_HEIGHT * ROOM_PATHS_WIDTH);
 		rec->paths.load(data);
 	}
@@ -730,6 +734,7 @@
 }
 
 void SequenceDelayList::tick() {
+	Resources &res = Resources::getReference();
 	uint32 currTime = g_system->getMillis();
 	SequenceDelayList::iterator i;
 
@@ -738,6 +743,15 @@
 		if (currTime >= entry->timeoutCtr) {
 			// Timeout reached - delete entry from list and execute the sequence
 			uint16 seqOffset = entry->sequenceOffset;
+
+			// FIXME: At current speed the player can enter the cave a bit too quickly ahead of Goewin. 
+			// Use a hard-coded check to make sure Goewin is in the room
+			if (seqOffset == 0xebd) {
+				Hotspot *goewinHotspot = res.getActiveHotspot(GOEWIN_ID);
+				if (goewinHotspot->roomNumber() != 38) 
+					return;
+			}
+
 			erase(i);
 			Script::execute(seqOffset);
 			return;

Modified: scummvm/trunk/engines/lure/res_struct.h
===================================================================
--- scummvm/trunk/engines/lure/res_struct.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/res_struct.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -129,6 +129,8 @@
 	uint16 sequenceOffset;
 	int16 clippingXStart;
 	int16 clippingXEnd;
+	uint32 exitTime;
+	uint8 areaFlag;
 	RoomRect walkBounds;
 	uint16 numExits;
 };
@@ -206,8 +208,8 @@
 #define ROOM_EXIT_COORDINATES_NUM_ROOMS 52
 
 struct RoomExitCoordinateEntryResource {
+	uint8 roomIndex[ROOM_EXIT_COORDINATES_NUM_ROOMS];
 	RoomExitCoordinateResource entries[ROOM_EXIT_COORDINATES_NUM_ENTRIES];
-	uint8 roomIndex[ROOM_EXIT_COORDINATES_NUM_ROOMS];
 };
 
 #define MAX_SCHEDULE_ENTRY_PARAMS 5
@@ -337,6 +339,8 @@
 	uint16 sequenceOffset;
 	int16 clippingXStart;
 	int16 clippingXEnd;
+	uint8 areaFlag;
+	uint32 exitTime;
 	Common::Rect walkBounds;
 	RoomExitHotspotList exitHotspots;
 	RoomExitList exits;

Modified: scummvm/trunk/engines/lure/room.cpp
===================================================================
--- scummvm/trunk/engines/lure/room.cpp	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/room.cpp	2007-06-22 12:36:04 UTC (rev 27606)
@@ -1,9 +1,6 @@
-/* ScummVM - Graphic Adventure Engine
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
  *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -171,7 +168,7 @@
 			if (!skipFlag) {
 				skipFlag = (((entry->flags & HOTSPOTFLAG_FOUND) == 0) && 
 							((entry->flags & HOTSPOTFLAG_SKIP) != 0)) ||
-						    ((entry->flags & HOTSPOTFLAG_20) != 0);
+						    ((entry->flags & HOTSPOTFLAG_MENU_EXCLUSION) != 0);
 			}
 
 			if ((!skipFlag) && (entry->hotspotId < 0x409))
@@ -225,7 +222,7 @@
 	}
 }
 
-uint8 Room::checkRoomExits() {
+CursorType Room::checkRoomExits() {
 	Mouse &m = Mouse::getReference();
 	Resources &res = Resources::getReference();
 	_destRoomNumber = 0;
@@ -249,7 +246,7 @@
 		if (!skipFlag && (m.x() >= rec->xs) && (m.x() <= rec->xe) &&
 			(m.y() >= rec->ys) && (m.y() <= rec->ye)) {
 			// Cursor is within exit area
-			uint8 cursorNum = rec->cursorNum;
+			CursorType cursorNum = (CursorType)rec->cursorNum;
 			_destRoomNumber = rec->destRoomNumber;
 
 			// If it's a hotspotted exit, change arrow to the + arrow
@@ -258,7 +255,7 @@
 				_hotspot = res.getHotspot(_hotspotId);
 				_hotspotNameId = _hotspot->nameId;
 				_isExit = true;
-				cursorNum += 7;
+				cursorNum = (CursorType)((int)cursorNum + 7);
 			}
 
 			return cursorNum;
@@ -315,6 +312,9 @@
 	int16 yEnd = (hsY + h.heightCopy() - 1) / RECT_SIZE;
 	int16 numY = yEnd - yStart + 1;
 	
+	if ((xStart < 0) || (yEnd < 0))
+		return;
+
 	for (int16 xCtr = 0; xCtr < numX; ++xCtr, ++xStart) {
 		int16 xs = xStart - 4;
 		if (xs < 0) continue;
@@ -457,6 +457,11 @@
 		Memory::dealloc(statusLineCopy);
 	}
 
+	// Debug - if the bottle object is on layer 0FEh, then display it's surface
+	Hotspot *displayHotspot = res.getActiveHotspot(BOTTLE_HOTSPOT_ID);
+	if ((displayHotspot != NULL) && (displayHotspot->layer() == 0xfe)) 
+		displayHotspot->frames().copyTo(&s);
+
 	// If show information is turned on, show extra debugging information
 	if (_showInfo) {
 		char buffer[64];
@@ -490,6 +495,7 @@
 	_roomData = r.getRoom(newRoomNumber);
 	if (!_roomData)
 		error("Tried to change to non-existant room: %d", newRoomNumber);
+	bool leaveFlag = (_layers[0] && (newRoomNumber != _roomNumber));
 
 	_roomNumber = _roomData->roomNumber;
 	_descId = _roomData->descId;
@@ -497,7 +503,7 @@
 	_screen.empty();
 	_screen.resetPalette();
 
-	if (_layers[0]) leaveRoom();
+	if (leaveFlag) leaveRoom();
 	_numLayers = _roomData->numLayers;
 	if (showOverlay) ++_numLayers;
 
@@ -532,15 +538,15 @@
 	Mouse &mouse = Mouse::getReference();
 	Resources &res = Resources::getReference();
 	uint16 oldHotspotId = _hotspotId;
-	uint16 currentCursor = mouse.getCursorNum();
-	uint16 newCursor = currentCursor;
+	CursorType currentCursor = mouse.getCursorNum();
+	CursorType newCursor = currentCursor;
 	CurrentAction playerAction = res.getActiveHotspot(PLAYER_ID)->currentActions().action();
 	uint16 oldRoomNumber = res.fieldList().getField(OLD_ROOM_NUMBER);
 
 	if ((currentCursor >= CURSOR_TIME_START) && (currentCursor <= CURSOR_TIME_END) &&
 		((playerAction == START_WALKING) || (playerAction == PROCESSING_PATH))) {
 		// Animate the clock when processing the player path
-		++newCursor;
+		newCursor = (CursorType)((int)newCursor + 1);
 		if (newCursor == CURSOR_CROSS) newCursor = CURSOR_TIME_START;
 	} else if (checkInTalkDialog() && (oldRoomNumber == 0)) {
 		newCursor = CURSOR_TALK;
@@ -628,8 +634,8 @@
 }
 
 void Room::loadFromStream(Common::ReadStream *stream) {
-	int roomNum = stream->readUint16LE();
-	setRoomNumber(roomNum, false);
+	_roomNumber = stream->readUint16LE();
+	setRoomNumber(_roomNumber, false);
 
 	_destRoomNumber = stream->readUint16LE();
 	_showInfo = stream->readByte() != 0;

Modified: scummvm/trunk/engines/lure/room.h
===================================================================
--- scummvm/trunk/engines/lure/room.h	2007-06-22 12:31:27 UTC (rev 27605)
+++ scummvm/trunk/engines/lure/room.h	2007-06-22 12:36:04 UTC (rev 27606)
@@ -78,7 +78,7 @@
 	CursorState _cursorState;
 
 	void checkRoomHotspots();
-	uint8 checkRoomExits();
+	CursorType checkRoomExits();
 	void loadRoomHotspots();
 	bool sub_112() { return false; } // not yet implemented
 	void flagCoveredCells(Hotspot &h);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list