aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2008-01-10 13:37:34 +0000
committerPaul Gilbert2008-01-10 13:37:34 +0000
commitd804bad5512577b2a268f8985422038eb5d3927d (patch)
tree949ceec06a093ab2575b9254e17868c988dafd5e /engines
parent286a3da49b60974793add684226884ba2db3bcbc (diff)
downloadscummvm-rg350-d804bad5512577b2a268f8985422038eb5d3927d.tar.gz
scummvm-rg350-d804bad5512577b2a268f8985422038eb5d3927d.tar.bz2
scummvm-rg350-d804bad5512577b2a268f8985422038eb5d3927d.zip
Replaced the Blacksmith hack with an NPC Schedules list that stores the active schedule of an NPC when it's deactivated in case it's later reactivated again.
svn-id: r30378
Diffstat (limited to 'engines')
-rw-r--r--engines/lure/hotspots.cpp111
-rw-r--r--engines/lure/hotspots.h20
-rw-r--r--engines/lure/luredefs.h2
-rw-r--r--engines/lure/res.cpp9
-rw-r--r--engines/lure/res.h2
-rw-r--r--engines/lure/res_struct.cpp22
-rw-r--r--engines/lure/res_struct.h1
7 files changed, 149 insertions, 18 deletions
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 534fe41acf..b585f2a968 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -43,6 +43,7 @@ namespace Lure {
Hotspot::Hotspot(HotspotData *res): _pathFinder(this) {
Resources &resources = Resources::getReference();
+ HotspotSchedules &schedules = resources.hotspotSchedules();
bool isEGA = LureEngine::getReference().isEGA();
_data = res;
@@ -88,7 +89,14 @@ Hotspot::Hotspot(HotspotData *res): _pathFinder(this) {
_startRoomNumber = 0;
_supportValue = 0;
- if (_data->npcSchedule != 0) {
+ HotspotScheduleRecord *rec = schedules.check(_hotspotId);
+ if (rec != NULL) {
+ // Hotspot was previously active, so restore prior schedule
+ _currentActions.copyFrom(*rec);
+ schedules.remove(_hotspotId);
+
+ } else if (_data->npcSchedule != 0) {
+ // Set up default schedule based on given Schedule Id
CharacterScheduleEntry *entry = resources.charSchedules().getEntry(_data->npcSchedule);
_currentActions.addFront(DISPATCH_ACTION, entry, _roomNumber);
}
@@ -204,13 +212,9 @@ Hotspot::Hotspot(): _pathFinder(NULL) {
}
Hotspot::~Hotspot() {
- // WORKAROUND: If Blacksmith is being deactivated, make sure his animation is
- // reset back to his standard movement set
- if (_hotspotId == BLACKSMITH_ID) {
- Resources &res = Resources::getReference();
- HotspotAnimData *tempAnim = res.animRecords()[BLACKSMITH_DEFAULT_ANIM_INDEX];
- assert(tempAnim);
- _data->animRecordId = tempAnim->animRecordId;
+ if ((_data != NULL) && (_data->npcSchedule != 0)) {
+ // When deactivating an NPC schedule, store in case the NPC is later reactivated
+ Resources::getReference().hotspotSchedules().add(_hotspotId, _currentActions);
}
if (_frames) delete _frames;
@@ -4464,6 +4468,19 @@ CurrentActionEntry::CurrentActionEntry(Action newAction, uint16 roomNum, uint16
_roomNumber = roomNum;
}
+CurrentActionEntry::CurrentActionEntry(CurrentActionEntry *src) {
+ _action = src->_action;
+ _dynamicSupportData = src->_dynamicSupportData;
+ _roomNumber = src->_roomNumber;
+ if (!_dynamicSupportData)
+ _supportData = src->_supportData;
+ else if (src->_supportData == NULL)
+ _supportData = NULL;
+ else {
+ _supportData = new CharacterScheduleEntry(src->_supportData);
+ }
+}
+
void CurrentActionEntry::setSupportData(uint16 entryId) {
CharacterScheduleEntry &entry = supportData();
@@ -4624,6 +4641,15 @@ void CurrentActionStack::loadFromStream(ReadStream *stream) {
_actions.push_back(rec);
}
+void CurrentActionStack::copyFrom(CurrentActionStack &stack) {
+ ManagedList<CurrentActionEntry *>::iterator i;
+
+ for (i = stack._actions.begin(); i != stack._actions.end(); ++i) {
+ CurrentActionEntry *rec = *i;
+ _actions.push_back(new CurrentActionEntry(rec));
+ }
+}
+
/*-------------------------------------------------------------------------*/
/* Support methods */
/* */
@@ -4813,4 +4839,73 @@ void HotspotList::loadFromStream(ReadStream *stream) {
}
}
+HotspotScheduleRecord::HotspotScheduleRecord(uint16 hotspotId, CurrentActionStack &stack) {
+ this->hotspotId = hotspotId;
+ copyFrom(stack);
+}
+
+HotspotScheduleRecord::HotspotScheduleRecord(uint16 hotspotId) {
+ this->hotspotId = hotspotId;
+}
+
+void HotspotSchedules::saveToStream(WriteStream *stream) {
+ iterator i;
+
+ debugC(ERROR_DETAILED, kLureDebugAnimations, "Saving hotspot schedules stack");
+
+ for (i = begin(); i != end(); ++i) {
+ HotspotScheduleRecord *rec = *i;
+ stream->writeUint16LE(rec->hotspotId);
+ rec->saveToStream(stream);
+ }
+ stream->writeUint16LE(0xffff); // End of list marker
+ debugC(ERROR_DETAILED, kLureDebugAnimations, "Finished saving hotspot schedules stack");
+}
+
+void HotspotSchedules::loadFromStream(ReadStream *stream) {
+ iterator i;
+ uint16 hId;
+
+ debugC(ERROR_DETAILED, kLureDebugAnimations, "Loading hotspot schedules stack");
+
+ clear();
+ while ((hId = stream->readUint16LE()) != 0xffff) {
+ HotspotScheduleRecord *rec = new HotspotScheduleRecord(hId);
+ rec->loadFromStream(stream);
+ }
+
+ debugC(ERROR_DETAILED, kLureDebugAnimations, "Loading saving hotspot schedules stack");
+}
+
+void HotspotSchedules::add(uint16 hotspotId, CurrentActionStack &actions) {
+ HotspotScheduleRecord *rec = new HotspotScheduleRecord(hotspotId, actions);
+ push_back(rec);
+}
+
+void HotspotSchedules::remove(uint16 hotspotId) {
+ iterator i;
+
+ for (i = begin(); i != end(); ++i) {
+ HotspotScheduleRecord *rec = *i;
+
+ if (rec->hotspotId == hotspotId) {
+ erase(i);
+ return;
+ }
+ }
+}
+
+HotspotScheduleRecord *HotspotSchedules::check(uint16 hotspotId) {
+ iterator i;
+
+ for (i = begin(); i != end(); ++i) {
+ HotspotScheduleRecord *rec = *i;
+
+ if (rec->hotspotId == hotspotId)
+ return rec;
+ }
+
+ return NULL;
+}
+
} // end of namespace Lure
diff --git a/engines/lure/hotspots.h b/engines/lure/hotspots.h
index 75953b9259..789776167e 100644
--- a/engines/lure/hotspots.h
+++ b/engines/lure/hotspots.h
@@ -108,6 +108,7 @@ public:
CurrentActionEntry(CurrentAction newAction, uint16 roomNum);
CurrentActionEntry(CurrentAction newAction, CharacterScheduleEntry *data, uint16 roomNum);
CurrentActionEntry(Action newAction, uint16 roomNum, uint16 param1, uint16 param2);
+ CurrentActionEntry(CurrentActionEntry *src);
virtual ~CurrentActionEntry() {
if (_dynamicSupportData) delete _supportData;
}
@@ -177,6 +178,7 @@ public:
void saveToStream(WriteStream *stream);
void loadFromStream(ReadStream *stream);
+ void copyFrom(CurrentActionStack &stack);
};
class WalkingActionEntry {
@@ -249,6 +251,24 @@ struct DestStructure {
Point position;
};
+class HotspotScheduleRecord: public CurrentActionStack {
+public:
+ uint16 hotspotId;
+
+ HotspotScheduleRecord(uint16 hotspotId, CurrentActionStack &stack);
+ HotspotScheduleRecord(uint16 hotspotId);
+};
+
+class HotspotSchedules: public ManagedList<HotspotScheduleRecord *> {
+public:
+ void add(uint16 hotspotId, CurrentActionStack &actions);
+ void remove(uint16 hotspotId);
+ HotspotScheduleRecord *check(uint16 hotspotId);
+ void saveToStream(Common::WriteStream *stream);
+ void loadFromStream(Common::ReadStream *stream);
+};
+
+
#define MAX_NUM_FRAMES 16
class Hotspot {
diff --git a/engines/lure/luredefs.h b/engines/lure/luredefs.h
index 4cdee1343f..ea05a51b41 100644
--- a/engines/lure/luredefs.h
+++ b/engines/lure/luredefs.h
@@ -36,7 +36,7 @@ namespace Lure {
#define LURE_DAT_MAJOR 1
#define LURE_DAT_MINOR 28
#define LURE_MIN_SAVEGAME_MINOR 25
-#define LURE_SAVEGAME_MINOR 30
+#define LURE_SAVEGAME_MINOR 31
#define LURE_DEBUG 1
diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp
index fd6fe357aa..a3eb33660d 100644
--- a/engines/lure/res.cpp
+++ b/engines/lure/res.cpp
@@ -98,6 +98,7 @@ void Resources::reset() {
_fieldList.reset();
_barmanLists.reset();
+ _hotspotSchedules.clear();
_talkState = TALK_NONE;
_activeTalkData = NULL;
@@ -732,6 +733,7 @@ void Resources::saveToStream(Common::WriteStream *stream) {
// Save sublist data
_hotspotData.saveToStream(stream);
_activeHotspots.saveToStream(stream);
+ _hotspotSchedules.saveToStream(stream);
_fieldList.saveToStream(stream);
_randomActions.saveToStream(stream);
_barmanLists.saveToStream(stream);
@@ -757,6 +759,13 @@ void Resources::loadFromStream(Common::ReadStream *stream) {
_hotspotData.loadFromStream(stream);
debugC(ERROR_DETAILED, kLureDebugScripts, "Loading active hotspots");
_activeHotspots.loadFromStream(stream);
+
+ _hotspotSchedules.clear();
+ if (saveVersion >= 31) {
+ _hotspotSchedules.loadFromStream(stream);
+ debugC(ERROR_DETAILED, kLureDebugScripts, "Loading hotspot schedules");
+ }
+
debugC(ERROR_DETAILED, kLureDebugScripts, "Loading fields");
_fieldList.loadFromStream(stream);
debugC(ERROR_DETAILED, kLureDebugScripts, "Loading random actions");
diff --git a/engines/lure/res.h b/engines/lure/res.h
index ac0430e32d..aaf50754f9 100644
--- a/engines/lure/res.h
+++ b/engines/lure/res.h
@@ -79,6 +79,7 @@ private:
PausedCharacterList _pausedList;
BarmanLists _barmanLists;
StringList _stringList;
+ HotspotSchedules _hotspotSchedules;
int numCharOffsets;
uint16 *_charOffsets;
@@ -134,6 +135,7 @@ public:
RoomExitIndexedHotspotList &exitHotspots() { return _indexedRoomExitHospots; }
PausedCharacterList &pausedList() { return _pausedList; }
BarmanLists &barmanLists() { return _barmanLists; }
+ HotspotSchedules &hotspotSchedules() { return _hotspotSchedules; }
StringList &stringList() { return _stringList; }
uint16 getCharOffset(int index) {
if (index >= numCharOffsets)
diff --git a/engines/lure/res_struct.cpp b/engines/lure/res_struct.cpp
index 991eca7b7f..2d4e3a9d8c 100644
--- a/engines/lure/res_struct.cpp
+++ b/engines/lure/res_struct.cpp
@@ -741,6 +741,8 @@ SequenceDelayData *SequenceDelayData::load(uint32 delay, uint16 seqOffset, bool
}
void SequenceDelayList::add(uint16 delay, uint16 seqOffset, bool canClear) {
+ debugC(ERROR_DETAILED, kLureDebugScripts, "Delay List add sequence=%xh delay=%d canClear=%d",
+ seqOffset, delay, (int)canClear);
SequenceDelayData *entry = new SequenceDelayData(delay, seqOffset, canClear);
push_front(entry);
}
@@ -750,20 +752,15 @@ void SequenceDelayList::tick() {
uint32 currTime = g_system->getMillis();
SequenceDelayList::iterator i;
+ debugC(ERROR_DETAILED, kLureDebugScripts, "Delay List check start at time %d", currTime);
+
for (i = begin(); i != end(); i++) {
SequenceDelayData *entry = *i;
+ debugC(ERROR_DETAILED, kLureDebugScripts, "Delay List check %xh at time %d", entry->sequenceOffset, entry->timeoutCtr);
+
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;
@@ -842,6 +839,13 @@ CharacterScheduleEntry::CharacterScheduleEntry(CharacterScheduleSet *parentSet,
(_numParams + 1) * sizeof(uint16));
}
+CharacterScheduleEntry::CharacterScheduleEntry(CharacterScheduleEntry *src) {
+ _parent = src->_parent;
+ _action = src->_action;
+ _numParams = src->_numParams;
+ Common::copy(src->_params, src->_params + MAX_TELL_COMMANDS * 3 * sizeof(uint16), _params);
+}
+
uint16 CharacterScheduleEntry::param(int index) {
if ((index < 0) || (index >= numParams()))
error("Invalid parameter index %d on handling action %d", index, _action);
diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h
index ea2836080e..9469fa939e 100644
--- a/engines/lure/res_struct.h
+++ b/engines/lure/res_struct.h
@@ -667,6 +667,7 @@ public:
CharacterScheduleEntry(Action theAction, ...);
CharacterScheduleEntry(CharacterScheduleSet *parentSet,
CharacterScheduleResource *&rec);
+ CharacterScheduleEntry(CharacterScheduleEntry *src);
Action action() { return _action; }
int numParams() { return _numParams; }