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

dreammaster at users.sourceforge.net dreammaster at users.sourceforge.net
Thu Feb 22 07:29:11 CET 2007


Revision: 25780
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25780&view=rev
Author:   dreammaster
Date:     2007-02-21 22:29:09 -0800 (Wed, 21 Feb 2007)

Log Message:
-----------
Added proper support for the random actions your sidekick can do in each room

Modified Paths:
--------------
    scummvm/trunk/engines/lure/hotspots.cpp
    scummvm/trunk/engines/lure/luredefs.h
    scummvm/trunk/engines/lure/res.cpp
    scummvm/trunk/engines/lure/res.h
    scummvm/trunk/engines/lure/res_struct.cpp
    scummvm/trunk/engines/lure/res_struct.h

Modified: scummvm/trunk/engines/lure/hotspots.cpp
===================================================================
--- scummvm/trunk/engines/lure/hotspots.cpp	2007-02-22 06:25:59 UTC (rev 25779)
+++ scummvm/trunk/engines/lure/hotspots.cpp	2007-02-22 06:29:09 UTC (rev 25780)
@@ -2581,17 +2581,13 @@
 	{0, 0}};
 
 void HotspotTickHandlers::followerAnimHandler(Hotspot &h) {
+	static int countdownCtr = 0;
 	Resources &res = Resources::getReference();
 	ValueTableData &fields = res.fieldList();
 	Hotspot *player = res.getActiveHotspot(PLAYER_ID);
 
-	if ((fields.getField(37) == 0) && h.currentActions().isEmpty()) {
-		
-		if (h.roomNumber() == player->roomNumber()) {
-			// In same room as player - set a random destination
-			h.setRandomDest();
-
-		} else {
+	if ((fields.getField(37) == 0) && (h.currentActions().size() <= 1))	{
+		if (h.roomNumber() != player->roomNumber()) {
 			// Character in different room than player
 			if (h.hotspotId() == GOEWIN_ID) 
 				h.currentActions().addFront(DISPATCH_ACTION, player->roomNumber());
@@ -2606,12 +2602,78 @@
 		}
 	}
 
-	if (h.characterMode() == CHARMODE_IDLE) {
-		// TODO: Checks on ds:[4f8ah] to figure out
+	// If some action is in progress, do standard handling
+	if (h.characterMode() != CHARMODE_IDLE) {
 		standardCharacterAnimHandler(h);
 		return;
 	}
 
+	if (fields.wanderingCharsLoaded()) {
+		// Start Ratpouch to sewer exit to meet player
+		fields.wanderingCharsLoaded() = false;
+		h.setBlockedFlag(false);
+		CharacterScheduleEntry *newEntry = res.charSchedules().getEntry(RETURN_SUPPORT_ID);
+		h.currentActions().addFront(DISPATCH_ACTION, newEntry, 7);
+		h.setActionCtr(0);
+
+		standardCharacterAnimHandler(h);
+		return;
+	}
+
+	// Handle any pause countdown
+	if (countdownCtr > 0)
+	{
+		--countdownCtr;
+		standardCharacterAnimHandler(h);
+		return;
+	}
+
+	// Handle selecting a random action for the character to do
+	RandomActionSet *set = res.randomActions().getRoom(h.roomNumber());
+	if (!set) return;
+	Common::RandomSource rnd;
+	RandomActionType actionType;
+	uint16 scheduleId;
+	int actionIndex = rnd.getRandomNumber(set->numActions() - 1);
+	set->getEntry(actionIndex, actionType, scheduleId);
+
+	if (actionType == REPEAT_ONCE_DONE)
+	{
+		// Repeat once random action that's already done, so don't repeat it
+		standardCharacterAnimHandler(h);
+		return;
+	}
+
+	// For repeat once actions, make sure the character is in the same room as the player
+	if (actionType == REPEAT_ONCE)
+	{
+		if (player->roomNumber() != h.roomNumber())
+		{
+			// Not in the same room, so don't do the action
+			standardCharacterAnimHandler(h);
+			return;
+		}
+		
+		// Flag the action as having been done, so it won't be repeated
+		set->setDone(actionIndex);
+	}
+
+	if (scheduleId == 0)
+	{
+		// No special schedule to perform, so simply set a random action
+		h.setRandomDest();
+	}
+	else
+	{
+		// Prepare the follower to standard the specified schedule
+		CharacterScheduleEntry *newEntry = res.charSchedules().getEntry(scheduleId);
+		assert(newEntry);
+		h.currentActions().addFront(DISPATCH_ACTION, newEntry, h.roomNumber());
+
+		// Set a random delay before beginning the action
+		countdownCtr = rnd.getRandomNumber(32);
+	}
+
 	standardCharacterAnimHandler(h);
 }
 

Modified: scummvm/trunk/engines/lure/luredefs.h
===================================================================
--- scummvm/trunk/engines/lure/luredefs.h	2007-02-22 06:25:59 UTC (rev 25779)
+++ scummvm/trunk/engines/lure/luredefs.h	2007-02-22 06:29:09 UTC (rev 25780)
@@ -31,7 +31,7 @@
 
 #define SUPPORT_FILENAME "lure.dat"
 #define LURE_DAT_MAJOR 1
-#define LURE_DAT_MINOR 13
+#define LURE_DAT_MINOR 14
 
 #define LURE_DEBUG 1
 

Modified: scummvm/trunk/engines/lure/res.cpp
===================================================================
--- scummvm/trunk/engines/lure/res.cpp	2007-02-22 06:25:59 UTC (rev 25779)
+++ scummvm/trunk/engines/lure/res.cpp	2007-02-22 06:29:09 UTC (rev 25780)
@@ -55,6 +55,7 @@
 	_exitJoins.clear();
 	_delayList.clear();
 	_charSchedules.clear();
+	_randomActions.clear();
 	_indexedRoomExitHospots.clear();
 	_pausedList.clear();
 	_stringList.clear();
@@ -283,6 +284,15 @@
 	for (ctr = 0; ctr < numCharOffsets; ++ctr, ++offset) 
 		_charOffsets[ctr] = READ_LE_UINT16(offset);
 
+	// Next load up the list of random actions your follower can do in each room
+
+	++offset;
+	while (READ_LE_UINT16(offset) != 0xffff)
+	{
+		RandomActionSet *actionSet = new RandomActionSet(offset);
+		_randomActions.push_back(actionSet);
+	}
+
 	// Loop through loading the schedules
 	ctr = 0;
 	while ((startOffset = READ_LE_UINT16(++offset)) != 0xffff) {
@@ -515,8 +525,25 @@
 		if (loadFlag) {
 			Hotspot *hotspot = addHotspot(hotspotId);
 			assert(hotspot);
+
+			// Special post-load handling
 			if (res->loadOffset == 0x7167) hotspot->setPersistant(true);
 			if (res->loadOffset == 0x8617) hotspot->handleTalkDialog();
+			
+			// TODO: Figure out why there's a room set in the animation decode for a range of characters,
+			// particularly since it doesn't seem to match what happens in-game
+			/*
+			if ((hotspot->hotspotId() >= RATPOUCH_ID) &&
+				(hotspot->hotspotId() < FIRST_NONCHARACTER_ID) &&
+				(hotspot->roomNumber() < 42))
+			{
+				// Start wandering characters off in room 24
+				hotspot->setRoomNumber(24);
+				hotspot->setPosition(64, 116);
+				_fieldList.wanderingCharsLoaded() = true;
+			}
+			*/
+
 			return hotspot;
 		}
 	}

Modified: scummvm/trunk/engines/lure/res.h
===================================================================
--- scummvm/trunk/engines/lure/res.h	2007-02-22 06:25:59 UTC (rev 25779)
+++ scummvm/trunk/engines/lure/res.h	2007-02-22 06:29:09 UTC (rev 25780)
@@ -68,6 +68,7 @@
 	MemoryBlock *_talkDialogData;
 	RoomExitCoordinatesList _coordinateList;
 	CharacterScheduleList _charSchedules;
+	RandomActionList _randomActions;
 	RoomExitIndexedHotspotList _indexedRoomExitHospots;
 	PausedCharacterList _pausedList;
 	StringList _stringList;
@@ -122,6 +123,7 @@
 	MemoryBlock &getTalkDialogData() { return *_talkDialogData; }
 	RoomExitCoordinatesList &coordinateList() { return _coordinateList; }
 	CharacterScheduleList &charSchedules() { return _charSchedules; }
+	RandomActionList &randomActions() { return _randomActions; }
 	RoomExitIndexedHotspotList &exitHotspots() { return _indexedRoomExitHospots; }
 	PausedCharacterList &pausedList() { return _pausedList; }
 	StringList &stringList() { return _stringList; }

Modified: scummvm/trunk/engines/lure/res_struct.cpp
===================================================================
--- scummvm/trunk/engines/lure/res_struct.cpp	2007-02-22 06:25:59 UTC (rev 25779)
+++ scummvm/trunk/engines/lure/res_struct.cpp	2007-02-22 06:29:09 UTC (rev 25780)
@@ -34,7 +34,7 @@
 
 int actionNumParams[NPC_JUMP_ADDRESS+1] = {0, 
 	1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1,
-	0, 1, 1, 1, 1, 0, 0, 2, 0, 1, 0, 0, 1, 1, 2, 2, 5, 2, 2, 1};
+	0, 1, 1, 1, 1, 0, 0, 2, 1, 1, 0, 0, 1, 1, 2, 2, 5, 2, 2, 1};
 
 // Room data holding class
 
@@ -774,6 +774,55 @@
 	return result;
 }
 
+// This classes is used to store a list of random action sets - one set per room
+
+RandomActionSet::RandomActionSet(uint16 *&offset)
+{
+	_roomNumber = READ_LE_UINT16(offset++);
+	uint16 actionDetails = READ_LE_UINT16(offset++);
+	_numActions = (actionDetails & 0xff);
+	assert(_numActions <= 8);
+	_types = new RandomActionType[_numActions];
+	_ids = new uint16[_numActions];
+
+	for (int actionIndex = 0; actionIndex < _numActions; ++actionIndex)
+	{
+		_ids[actionIndex] = READ_LE_UINT16(offset++);
+		_types[actionIndex] = (actionDetails & (0x100 << actionIndex)) != 0 ? REPEATABLE : REPEAT_ONCE;
+	}
+}
+
+RandomActionSet::~RandomActionSet()
+{
+	delete _types;
+	delete _ids;
+}
+
+RandomActionSet *RandomActionList::getRoom(uint16 roomNumber)
+{
+	iterator i;
+	for (i = begin(); i != end(); ++i) 
+	{
+		RandomActionSet *v = *i;
+		if (v->roomNumber() == roomNumber)
+			return v;
+	}
+	return NULL;
+}
+
+void RandomActionList::saveToStream(Common::WriteStream *stream)
+{
+
+}
+
+void RandomActionList::loadFromStream(Common::ReadStream *stream)
+{
+
+}
+
+
+
+
 // This class handles an indexed hotspot entry - which is used by the NPC code to
 // determine whether exiting a room to another given room has an exit hotspot or not
 
@@ -950,6 +999,7 @@
 	_playerPendingPos.isSet = false;
 	_flags = GAMEFLAG_4 | GAMEFLAG_1;
 	_hdrFlagMask = 1;
+	_wanderingCharsLoaded = false;
 
 	for (uint16 index = 0; index < NUM_VALUE_FIELDS; ++index)
 		_fieldList[index] = 0;
@@ -996,6 +1046,7 @@
 	stream->writeSint16LE(_playerPendingPos.pos.y);
 	stream->writeByte(_flags);
 	stream->writeByte(_hdrFlagMask);
+	stream->writeByte(_wanderingCharsLoaded);
 	
 	// Write out the special fields
 	for (int index = 0; index < NUM_VALUE_FIELDS; ++index)
@@ -1014,6 +1065,7 @@
 	_playerPendingPos.pos.y = stream->readSint16LE();
 	_flags = stream->readByte();
 	_hdrFlagMask = stream->readByte();
+	_wanderingCharsLoaded = stream->readByte() != 0;
 	
 	// Read in the field list
 	for (int index = 0; index < NUM_VALUE_FIELDS; ++index)

Modified: scummvm/trunk/engines/lure/res_struct.h
===================================================================
--- scummvm/trunk/engines/lure/res_struct.h	2007-02-22 06:25:59 UTC (rev 25779)
+++ scummvm/trunk/engines/lure/res_struct.h	2007-02-22 06:29:09 UTC (rev 25780)
@@ -633,6 +633,43 @@
 
 typedef List<uint16> CharacterScheduleOffsets;
 
+// The follow classes are used to store the NPC schedule Ids for the random actions a follower can do in each room
+
+enum RandomActionType {REPEATABLE, REPEAT_ONCE, REPEAT_ONCE_DONE};
+
+class RandomActionSet {
+private:
+	uint16 _roomNumber;
+	int _numActions;
+	RandomActionType *_types;
+	uint16 *_ids;
+public:
+	RandomActionSet(uint16 *&offset);
+	~RandomActionSet();
+
+	uint16 roomNumber() { return _roomNumber; }
+	int numActions() { return _numActions; }
+	void getEntry(int index, RandomActionType &actionType, uint16 &id)
+	{
+		assert((index >= 0) && (index < _numActions));
+		actionType = _types[index];
+		id = _ids[index];
+	}
+	void setDone(int index)
+	{
+		assert((index >= 0) && (index < _numActions));
+		assert(_types[index] == REPEAT_ONCE);
+		_types[index] = REPEAT_ONCE_DONE;
+	}
+};
+
+class RandomActionList: public ManagedList<RandomActionSet *> {
+public:
+	RandomActionSet *getRoom(uint16 roomNumber);
+	void saveToStream(Common::WriteStream *stream);
+	void loadFromStream(Common::ReadStream *stream);
+};
+
 class PausedCharacter {
 public:
 	PausedCharacter(uint16 SrcCharId, uint16 DestCharId);
@@ -730,6 +767,7 @@
 	PlayerPendingPosition _playerPendingPos;
 	uint8 _flags;
 	uint8 _hdrFlagMask;
+	bool _wanderingCharsLoaded;
 
 	uint16 _fieldList[NUM_VALUE_FIELDS];
 	bool isKnownField(uint16 fieldIndex);
@@ -747,6 +785,7 @@
 	uint8 &hdrFlagMask() { return _hdrFlagMask; }
 	PlayerNewPosition &playerNewPos() { return _playerNewPos; }
 	PlayerPendingPosition &playerPendingPos() { return _playerPendingPos; }
+	bool &wanderingCharsLoaded() { return _wanderingCharsLoaded; }
 
 	void saveToStream(Common::WriteStream *stream);
 	void loadFromStream(Common::ReadStream *stream);


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