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

dreammaster at users.sourceforge.net dreammaster at users.sourceforge.net
Mon May 29 01:13:04 CEST 2006


Revision: 22731
Author:   dreammaster
Date:     2006-05-29 01:12:07 -0700 (Mon, 29 May 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=22731&view=rev

Log Message:
-----------
Player now moves out of the way if he's blocking an entrance when an NPC enters. Also changed errors in unimplemented NPC actions to warnings

Modified Paths:
--------------
    scummvm/trunk/engines/lure/game.cpp
    scummvm/trunk/engines/lure/hotspots.cpp
    scummvm/trunk/engines/lure/hotspots.h
    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/game.cpp
===================================================================
--- scummvm/trunk/engines/lure/game.cpp	2006-05-29 03:12:51 UTC (rev 22730)
+++ scummvm/trunk/engines/lure/game.cpp	2006-05-29 08:12:07 UTC (rev 22731)
@@ -310,7 +310,7 @@
 		if (response != MENUITEM_NONE)
 			handleMenuResponse(response);
 	} else if ((room.cursorState() == CS_SEQUENCE) ||
-			   (room.cursorState() == CS_UNKNOWN)) { 
+			   (room.cursorState() == CS_BUMPED)) { 
 		// No action necessary
 	} else {
 		if (mouse.lButton())

Modified: scummvm/trunk/engines/lure/hotspots.cpp
===================================================================
--- scummvm/trunk/engines/lure/hotspots.cpp	2006-05-29 03:12:51 UTC (rev 22730)
+++ scummvm/trunk/engines/lure/hotspots.cpp	2006-05-29 08:12:07 UTC (rev 22731)
@@ -75,6 +75,8 @@
 	_actionCtr = 0;
 	_blockedOffset = 0;
 	_exitCtr = 0;
+	_blockedState = BS_NONE;
+	_unknownFlag = false;
 
 	if (_data->npcSchedule != 0) {
 		CharacterScheduleEntry *entry = resources.charSchedules().getEntry(_data->npcSchedule);
@@ -96,6 +98,8 @@
 	_destHotspotId = character->hotspotId();
 	_blockedOffset = 0;
 	_exitCtr = 0;
+	_blockedState = BS_NONE;
+	_unknownFlag = false;
 
 	switch (objType) {
 	case VOICE_ANIM_ID:
@@ -389,6 +393,31 @@
 	}
 }
 
+// Sets a character walking to a random destination position
+
+void Hotspot::setRandomDest() {
+	Resources &res = Resources::getReference();
+	RoomData *roomData = res.getRoom(roomNumber());
+	Common::Rect &rect = roomData->walkBounds;
+	Common::RandomSource _rnd;
+	int tryCtr = 0;
+	int16 xp, yp;
+
+	if (_currentActions.isEmpty())
+		_currentActions.addFront(START_WALKING, roomNumber());
+	else
+		_currentActions.top().setAction(START_WALKING);
+	
+	while (tryCtr ++ <= 20) {
+		xp = rect.left + _rnd.getRandomNumber(rect.right - rect.left);
+		yp = rect.left + _rnd.getRandomNumber(rect.right - rect.left);
+		setDestPosition(xp, yp);
+
+		if (!roomData->paths.isOccupied(xp, yp) && !roomData->paths.isOccupied(xp, yp)) 
+			break;
+	}
+}
+
 // Sets or clears the hotspot as occupying an area in its room's pathfinding data
 
 void Hotspot::setOccupied(bool occupiedFlag) {
@@ -464,6 +493,30 @@
 	return false;
 }
 
+void Hotspot::updateMovement() {
+	assert(_data != NULL);
+	if (_currentActions.action() == EXEC_HOTSPOT_SCRIPT) {
+		if (_data->coveredFlag) {
+			// Reset position and direction
+			resetPosition();
+		} else {
+			// Make sure the cell occupied by character is covered
+			_data->coveredFlag = true;
+			setOccupied(true);
+		}
+	}
+}
+
+void Hotspot::updateMovement2(CharacterMode value) {
+	setCharacterMode(value);
+	updateMovement();
+}
+
+void Hotspot::resetPosition() {
+	setPosition(x() & 0xf8 | 5, y());
+	setDirection(direction());
+}
+
 /*-------------------------------------------------------------------------*/
 /* Hotspot action handling                                                 */
 /*                                                                         */
@@ -1302,7 +1355,7 @@
 
 void Hotspot::npcSetRandomDest(HotspotData *hotspot) {
 	endAction();
-	Support::setRandomDest(*this);
+	setRandomDest();
 }
 
 void Hotspot::npcWalkingCheck(HotspotData *hotspot) {
@@ -1373,19 +1426,23 @@
 }
 
 void Hotspot::npcUnknown3(HotspotData *hotspot) {
-	error("npcUnknown3: Not yet implemented");
+	warning("npcUnknown3: Not yet implemented");
+	endAction();
 }
 
 void Hotspot::npcUnknown4(HotspotData *hotspot) {
-	error("npcUnknown4: Not yet implemented");
+	warning("npcUnknown4: Not yet implemented");
+	endAction();
 }
 
 void Hotspot::npcStartTalking(HotspotData *hotspot) {
-	error("npcStartTalking: Not yet implemented");
+	warning("npcStartTalking: Not yet implemented");
+	endAction();
 }
 
 void Hotspot::npcJumpAddress(HotspotData *hotspot) {
-	error("npcJumpAddress: Not yet implemented");
+	warning("npcJumpAddress: Not yet implemented");
+	endAction();
 }
 
 /*------------------------------------------------------------------------*/
@@ -1460,7 +1517,7 @@
 	CurrentActionStack &actions = h.currentActions();
 	uint16 impingingList[MAX_NUM_IMPINGING];
 	int numImpinging;
-	int index;
+	bool bumpedPlayer;
 
 	// TODO: handle talk dialogs countdown if necessary
 
@@ -1471,26 +1528,74 @@
 	}
 
 	numImpinging = Support::findIntersectingCharacters(h, impingingList);
+	bumpedPlayer = (numImpinging == 0) ? false :
+		Support::isCharacterInList(impingingList, numImpinging, PLAYER_ID);
+
+	// Check for character having just changed room
 	if (h.skipFlag()) {
 		if (numImpinging > 0) {
-			index = 0;
-			while ((index < numImpinging) && (impingingList[index] != PLAYER_ID))
-				++index;
-			
-			if (index != numImpinging) {
-				// Character has bumped into player
-				// TODO: Figure out handling code
-				error("Unimplemented - character bumping into player");
+			// Scan to check if the character has bumped into player
+			Hotspot *player = res.getActiveHotspot(PLAYER_ID);
+
+			if (bumpedPlayer && (player->characterMode() == CHARMODE_IDLE)) {
+				// Signal the player to move out of the way automatically
+				player->setBlockedState(BS_INITIAL);
+				player->setDestHotspot(0);
+
+				Room::getReference().setCursorState(CS_BUMPED);
+				player->setRandomDest();
+			} else {
+				// Signal the character to pause briefly to allow bumped
+				// character time to start moving out of the way
+				h.setDelayCtr(10);
+				h.setCharacterMode(CHARMODE_PAUSED);
 			}
 			return;
 		}
-		
+
 		h.setSkipFlag(false);
 	}
 
 	// TODO: Handling of any set Tick Script Offset, as well as certain other
 	// as of yet unknown hotspot flags
 
+	if (h.characterMode() != CHARMODE_NONE) {
+		if (h.characterMode() == CHARMODE_6) {
+			// TODO: Figure out what mode 6 is
+			h.updateMovement();
+			if (bumpedPlayer) return;
+
+		} else {
+			// All other character modes
+			if (h.delayCtr() > 0) {
+				// There is some countdown left to do
+				bool decrementFlag = true; //TODO: = HS[50h] == 0
+
+				if (!decrementFlag) {
+					HotspotData *hotspot = res.getHotspot(0); // TODO: HS[50h]
+					decrementFlag = (hotspot->roomNumber != h.roomNumber()) ? false :
+						Support::charactersIntersecting(hotspot, h.resource());
+				}			
+
+				if (decrementFlag) {
+					h.setDelayCtr(h.delayCtr() - 1);
+					return;
+				}
+			}
+		}
+
+		// TODO: HS[50h]=0
+		CharacterMode currentMode = h.characterMode();
+		h.setCharacterMode(CHARMODE_NONE);
+		h.pathFinder().clear();
+
+		if ((currentMode == CHARMODE_4) || (currentMode == CHARMODE_7)) {
+			// TODO: HS[33h]=0
+			Dialog::showMessage(1, h.hotspotId());
+		}
+		return;
+	}
+
 	CurrentAction action = actions.action();
 
 	switch (action) {
@@ -1639,6 +1744,7 @@
 	case NO_ACTION:
 		// Make sure there is no longer any destination
 		h.setDestHotspot(0);
+		h.updateMovement2(CHARMODE_IDLE);
 		break;
 
 	case DISPATCH_ACTION:
@@ -1678,9 +1784,17 @@
 		// Deliberate fall through to processing walking path
 
 	case PROCESSING_PATH:
+		h.setCharacterMode(CHARMODE_NONE);
 		if (!pathFinder.process()) break;
 
 		// Pathfinding is now complete 
+/*
+		if ((pathFinder.result() != PF_OK) && (h.unknownFlag() ||
+			(pathFinder.result() != PF_DEST_OCCUPIED))) {
+			// TODO: occupiedFlag
+			
+		}
+*/
 		actions.pop();
 
 		if (pathFinder.isEmpty()) {
@@ -1709,6 +1823,9 @@
 
 		if (h.walkingStep()) {
 			// Walking done
+			Room &room = Room::getReference();
+			if (room.cursorState() == CS_BUMPED)
+				room.setCursorState(CS_NONE);
 			h.currentActions().pop();
 		}
 	
@@ -2003,7 +2120,7 @@
 		}
 
 		if (numCharacters >= 4) {
-error("npcChangeRoom - too many characters - yet to be tested");
+warning("XYZZY npcChangeRoom - too many characters - yet to be tested");
 			uint16 dataId = res.getCharOffset(0);
 			CharacterScheduleEntry *entry = res.charSchedules().getEntry(dataId);
 			h.currentActions().addFront(DISPATCH_ACTION, entry, h.roomNumber());
@@ -2062,14 +2179,18 @@
 	_stepCtr = 0; 
 }
 
-void PathFinder::reset(RoomPathsData &src) {
+void PathFinder::clear() {
 	_stepCtr = 0;
 	_list.clear();
-	src.decompress(_layer, _hotspot->widthCopy());
 	_inProgress = false;
 	_countdownCtr = PATHFIND_COUNTDOWN;
 }
 
+void PathFinder::reset(RoomPathsData &src) {
+	clear();
+	src.decompress(_layer, _hotspot->widthCopy());
+}
+
 // Does the next stage of processing to figure out a path to take to a given
 // destination. Returns true if the path finding has been completed
 
@@ -2439,6 +2560,7 @@
 	int numImpinging = 0;
 	Resources &res = Resources::getReference();
 	Rect r;
+	uint16 hotspotY;
 
 	r.left = h.x();
 	r.right = h.x() + h.widthCopy();
@@ -2456,12 +2578,13 @@
 			hotspot.skipFlag()) continue;
 		// TODO: See why si+ANIM_HOTSPOT_OFFSET compared aganst di+ANIM_VOICE_CTR
 
+		hotspotY = hotspot.y() + hotspot.heightCopy();
+
 		if ((hotspot.x() > r.right) || (hotspot.x() + hotspot.widthCopy() <= r.left) ||
-			(hotspot.y() + hotspot.heightCopy() + hotspot.charRectY() > r.bottom) ||
-			(hotspot.y() + hotspot.heightCopy() - hotspot.charRectY() 
-			- hotspot.yCorrection() <= r.top)) 
+			(hotspotY + hotspot.charRectY() < r.top) ||
+			(hotspotY - hotspot.charRectY() - hotspot.yCorrection() >= r.bottom))
 			continue;
-	
+
 		// Add hotspot Id to list
 		if (numImpinging == MAX_NUM_IMPINGING)
 			error("Exceeded maximum allowable number of impinging characters");
@@ -2534,26 +2657,6 @@
 	}
 }
 
-void Support::setRandomDest(Hotspot &h) {
-	Resources &res = Resources::getReference();
-	RoomData *roomData = res.getRoom(h.roomNumber());
-	Common::Rect &rect = roomData->walkBounds;
-	Common::RandomSource _rnd;
-	int tryCtr = 0;
-	int16 xp, yp;
-
-	h.currentActions().top().setAction(DISPATCH_ACTION);
-	
-	while (tryCtr ++ <= 20) {
-		xp = rect.left + _rnd.getRandomNumber(rect.right - rect.left);
-		yp = rect.left + _rnd.getRandomNumber(rect.right - rect.left);
-		h.setDestPosition(xp, yp);
-
-		if (!roomData->paths.isOccupied(xp, yp) && !roomData->paths.isOccupied(xp, yp)) 
-			break;
-	}
-}
-
 bool Support::charactersIntersecting(HotspotData *hotspot1, HotspotData *hotspot2) {
 	return !((hotspot1->startX + hotspot1->widthCopy + 4 < hotspot2->startX) ||
 		(hotspot2->startX + hotspot2->widthCopy + 4 < hotspot1->startX) ||
@@ -2563,4 +2666,10 @@
 			hotspot1->startY + hotspot1->heightCopy - hotspot1->yCorrection - 2));
 }
 
+bool Support::isCharacterInList(uint16 *lst, int numEntries, uint16 charId) {
+	while (numEntries-- > 0) 
+		if (*lst++ == charId) return true;
+	return false;
+}
+
 } // end of namespace Lure

Modified: scummvm/trunk/engines/lure/hotspots.h
===================================================================
--- scummvm/trunk/engines/lure/hotspots.h	2006-05-29 03:12:51 UTC (rev 22730)
+++ scummvm/trunk/engines/lure/hotspots.h	2006-05-29 08:12:07 UTC (rev 22731)
@@ -41,8 +41,8 @@
 	static void checkRoomChange(Hotspot &h);
 	static void characterChangeRoom(Hotspot &h, uint16 roomNumber, 
 								  int16 newX, int16 newY, Direction dir);
-	static void setRandomDest(Hotspot &h);
 	static bool charactersIntersecting(HotspotData *hotspot1, HotspotData *hotspot2);
+	static bool isCharacterInList(uint16 *lst, int numEntries, uint16 charId);
 };
 
 typedef void(*HandlerMethodPtr)(Hotspot &h);
@@ -172,9 +172,9 @@
 	void addBack(Direction dir, int steps) { 
 		_list.push_back(new WalkingActionEntry(dir, steps)); 
 	}
-	void clear() { _list.clear(); }
 public:
 	PathFinder(Hotspot *h);
+	void clear();
 	void reset(RoomPathsData &src);
 	bool process();
 	void list();
@@ -183,10 +183,13 @@
 	WalkingActionEntry &top() { return **_list.begin(); }
 	bool isEmpty() { return _list.empty(); }
 	int &stepCtr() { return _stepCtr; }
+	PathFinderResult result() { return _result; }
 };
 
 enum HotspotPrecheckResult {PC_EXECUTE, PC_NOT_IN_ROOM, PC_UNKNOWN, PC_INITIAL, PC_EXCESS};
 
+enum BlockedState {BS_NONE, BS_INITIAL, BS_UNKNOWN};
+
 class Hotspot {
 private:
 	HotspotData *_data;
@@ -224,6 +227,8 @@
 	uint16 _destHotspotId;
 	uint16 _blockedOffset;
 	uint8 _exitCtr;
+	BlockedState _blockedState;
+	bool _unknownFlag;
 
 	// Support methods
 	void startTalk(HotspotData *charHotspot);
@@ -234,6 +239,7 @@
 	void actionPrecheck3(HotspotData *hotspot);
 	bool characterWalkingCheck(HotspotData *hotspot);
 	bool doorCloseCheck(uint16 doorId);
+	void resetDirection();
 
 	// Action set
 	void doNothing(HotspotData *hotspot);
@@ -295,6 +301,8 @@
 	uint16 destHotspotId() { return _destHotspotId; }
 	uint16 blockedOffset() { return _blockedOffset; }
 	uint8 exitCtr() { return _exitCtr; }
+	BlockedState blockedState() { return _blockedState; }
+	bool unknownFlag() { return _unknownFlag; }
 	uint16 width() { return _width; }
 	uint16 height() { return _height; }
 	uint16 widthCopy() { return _widthCopy; }
@@ -320,14 +328,33 @@
 	void setDestPosition(int16 newX, int16 newY) { _destX = newX; _destY = newY; }
 	void setDestHotspot(uint16 id) { _destHotspotId = id; }
 	void setExitCtr(uint8 value) { _exitCtr = value; }
+	void setBlockedState(BlockedState newState) { _blockedState = newState; }
+	void setUnknownFlag(bool value) { _unknownFlag = value; }
 	void setSize(uint16 newWidth, uint16 newHeight);
 	void setScript(uint16 offset) {
+		assert(_data != NULL);
 		_sequenceOffset = offset;
 		_data->sequenceOffset = offset; 
 	}
 	void setActions(uint32 newActions) { _actions = newActions; }
 	void setCharRectY(uint16 value) { _charRectY = value; }
 	void setSkipFlag(bool value) { _skipFlag = value; }
+	CharacterMode characterMode() {
+		assert(_data != NULL);
+		return _data->characterMode;
+	}
+	void setCharacterMode(CharacterMode value) {
+		assert(_data != NULL);
+		_data->characterMode = value;
+	}
+	uint16 delayCtr() { 
+		assert(_data != NULL);
+		return _data->delayCtr;
+	}
+	void setDelayCtr(uint16 value) { 
+		assert(_data != NULL);
+		_data->delayCtr = value;
+	}
 
 	void copyTo(Surface *dest);
 	bool executeScript();
@@ -340,8 +367,12 @@
 	void endAction();
 	void setDirection(Direction dir);
 	void faceHotspot(HotspotData *hotspot);
+	void setRandomDest();
 	void setOccupied(bool occupiedFlag);
 	bool walkingStep();
+	void updateMovement();
+	void updateMovement2(CharacterMode value);
+	void resetPosition();
 
 	// Actions
 	void doAction();

Modified: scummvm/trunk/engines/lure/res_struct.cpp
===================================================================
--- scummvm/trunk/engines/lure/res_struct.cpp	2006-05-29 03:12:51 UTC (rev 22730)
+++ scummvm/trunk/engines/lure/res_struct.cpp	2006-05-29 08:12:07 UTC (rev 22731)
@@ -291,6 +291,11 @@
 	tickTimeout = READ_LE_UINT16(&rec->tickTimeout);
 	tickSequenceOffset = READ_LE_UINT16(&rec->tickSequenceOffset);
 	npcSchedule = READ_LE_UINT16(&rec->npcSchedule);
+
+	// Initialise dynamic fields
+	delayCtr = 0; 
+	characterMode = CHARMODE_NONE;
+	coveredFlag = false;
 }
 
 // Hotspot override data

Modified: scummvm/trunk/engines/lure/res_struct.h
===================================================================
--- scummvm/trunk/engines/lure/res_struct.h	2006-05-29 03:12:51 UTC (rev 22730)
+++ scummvm/trunk/engines/lure/res_struct.h	2006-05-29 08:12:07 UTC (rev 22731)
@@ -373,6 +373,9 @@
 	HotspotActionList *getActions(uint16 recordId);
 };
 
+enum CharacterMode {CHARMODE_NONE, CHARMODE_1, CHARMODE_IDLE, CHARMODE_PAUSED,
+	CHARMODE_4, CHARMODE_5, CHARMODE_6, CHARMODE_7};
+
 class HotspotData {
 public:
 	HotspotData(HotspotResource *rec);
@@ -405,8 +408,12 @@
 	uint16 tickProcOffset;
 	uint16 tickTimeout;
 	uint16 tickSequenceOffset;
-	uint16 npcSchedule;	
+	uint16 npcSchedule;
 
+	uint16 delayCtr;
+	CharacterMode characterMode;
+	bool coveredFlag;
+
 	void enable() { flags |= 0x80; }
 	void disable() { flags &= 0x7F; }
 	Direction nonVisualDirection() { return (Direction) scriptLoadFlag; }

Modified: scummvm/trunk/engines/lure/room.cpp
===================================================================
--- scummvm/trunk/engines/lure/room.cpp	2006-05-29 03:12:51 UTC (rev 22730)
+++ scummvm/trunk/engines/lure/room.cpp	2006-05-29 08:12:07 UTC (rev 22731)
@@ -535,7 +535,7 @@
 		newCursor = CURSOR_TALK;
 	} else if (res.getTalkData()) {
 		newCursor = CURSOR_ARROW;
-	} else if (_cursorState == CS_UNKNOWN) {
+	} else if (_cursorState == CS_BUMPED) {
 		newCursor = CURSOR_CAMERA;
 	} else if (_cursorState == CS_TALKING) {
 		newCursor = CURSOR_ARROW;
@@ -547,7 +547,7 @@
 		newCursor = CURSOR_MENUBAR;
 	} else if (_cursorState != CS_NONE) {
 		// Currently in a special mode
-//		checkRoomHotspots();
+		checkRoomHotspots();
 		newCursor = CURSOR_CAMERA;
 	} else {
 		// Check for a highlighted hotspot

Modified: scummvm/trunk/engines/lure/room.h
===================================================================
--- scummvm/trunk/engines/lure/room.h	2006-05-29 03:12:51 UTC (rev 22730)
+++ scummvm/trunk/engines/lure/room.h	2006-05-29 08:12:07 UTC (rev 22731)
@@ -51,7 +51,7 @@
 	}
 };
 
-enum CursorState {CS_NONE, CS_ACTION, CS_SEQUENCE, CS_TALKING, CS_UNKNOWN};
+enum CursorState {CS_NONE, CS_ACTION, CS_SEQUENCE, CS_TALKING, CS_BUMPED};
 
 class Room {
 private:


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