diff options
-rw-r--r-- | engines/lure/debugger.cpp | 1 | ||||
-rw-r--r-- | engines/lure/hotspots.cpp | 377 | ||||
-rw-r--r-- | engines/lure/hotspots.h | 109 | ||||
-rw-r--r-- | engines/lure/res.cpp | 85 | ||||
-rw-r--r-- | engines/lure/res.h | 2 | ||||
-rw-r--r-- | engines/lure/res_struct.cpp | 224 | ||||
-rw-r--r-- | engines/lure/res_struct.h | 138 |
7 files changed, 429 insertions, 507 deletions
diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp index cdaf98670f..63955003a4 100644 --- a/engines/lure/debugger.cpp +++ b/engines/lure/debugger.cpp @@ -316,7 +316,6 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) { hs->talkScriptOffset, hs->tickScriptOffset); DebugPrintf("Tick Proc offset = %xh\n", hs->tickProcId); DebugPrintf("Tick timeout = %d\n", hs->tickTimeout); - DebugPrintf("NPC Shcedule = %xh\n", hs->npcSchedule); DebugPrintf("Character mode = %d, delay ctr = %d, pause ctr = %d\n", hs->characterMode, hs->delayCtr, hs->pauseCtr); diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp index b04df3a248..9dba7a55f4 100644 --- a/engines/lure/hotspots.cpp +++ b/engines/lure/hotspots.cpp @@ -43,7 +43,6 @@ namespace Lure { Hotspot::Hotspot(HotspotData *res): _pathFinder(this) { Resources &resources = Resources::getReference(); - HotspotSchedules &schedules = resources.hotspotSchedules(); bool isEGA = LureEngine::getReference().isEGA(); _data = res; @@ -88,18 +87,6 @@ Hotspot::Hotspot(HotspotData *res): _pathFinder(this) { _walkFlag = false; _startRoomNumber = 0; _supportValue = 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); - } } // Special constructor used to create a voice hotspot @@ -212,11 +199,6 @@ Hotspot::Hotspot(): _pathFinder(NULL) { } Hotspot::~Hotspot() { - 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; } @@ -507,13 +489,13 @@ void Hotspot::walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot) { _destX = endPosX; _destY = endPosY; _destHotspotId = destHotspot; - _currentActions.addFront(START_WALKING, _roomNumber); + currentActions().addFront(START_WALKING, _roomNumber); } void Hotspot::stopWalking() { _voiceCtr = 0; setActionCtr(0); - _currentActions.clear(); + currentActions().clear(); Room::getReference().setCursorState(CS_NONE); } @@ -525,9 +507,9 @@ void Hotspot::endAction() { if (_hotspotId == PLAYER_ID) room.setCursorState((CursorState) ((int) room.cursorState() & 2)); - if (_currentActions.top().hasSupportData()) { - CharacterScheduleEntry *rec = _currentActions.top().supportData().next(); - _currentActions.top().setSupportData(rec); + if (currentActions().top().hasSupportData()) { + CharacterScheduleEntry *rec = currentActions().top().supportData().next(); + currentActions().top().setSupportData(rec); } } @@ -617,10 +599,10 @@ void Hotspot::setRandomDest() { g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots"); - if (_currentActions.isEmpty()) - _currentActions.addFront(START_WALKING, roomNumber()); + if (currentActions().isEmpty()) + currentActions().addFront(START_WALKING, roomNumber()); else - _currentActions.top().setAction(START_WALKING); + currentActions().top().setAction(START_WALKING); _walkFlag = true; // Try up to 20 times to find an unoccupied destination @@ -723,7 +705,7 @@ bool Hotspot::walkingStep() { void Hotspot::updateMovement() { assert(_data != NULL); - if (_currentActions.action() == EXEC_HOTSPOT_SCRIPT) { + if (currentActions().action() == EXEC_HOTSPOT_SCRIPT) { if (_data->coveredFlag) { // Reset position and direction resetPosition(); @@ -1241,7 +1223,7 @@ void Hotspot::resetDirection() { typedef void (Hotspot::*ActionProcPtr)(HotspotData *hotspot); void Hotspot::doAction() { - CurrentActionEntry &entry = _currentActions.top(); + CurrentActionEntry &entry = currentActions().top(); HotspotData *hotspot = NULL; if (!entry.hasSupportData() || (entry.supportData().action() == NONE)) { @@ -1265,9 +1247,9 @@ void Hotspot::doAction(Action action, HotspotData *hotspot) { fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId); if (action == USE) - fields.setField(USE_HOTSPOT_ID, _currentActions.top().supportData().param(0)); + fields.setField(USE_HOTSPOT_ID, currentActions().top().supportData().param(0)); else if ((action == GIVE) || (action == ASK)) - fields.setField(USE_HOTSPOT_ID, _currentActions.top().supportData().param(1)); + fields.setField(USE_HOTSPOT_ID, currentActions().top().supportData().param(1)); else fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId); } @@ -1320,9 +1302,9 @@ void Hotspot::doAction(Action action, HotspotData *hotspot) { } void Hotspot::doNothing(HotspotData *hotspot) { - if (!_currentActions.isEmpty()) { - _currentActions.pop(); - if (!_currentActions.isEmpty()) { + if (!currentActions().isEmpty()) { + currentActions().pop(); + if (!currentActions().isEmpty()) { setBlockedFlag(false); currentActions().top().setAction(DISPATCH_ACTION); return; @@ -1375,7 +1357,7 @@ void Hotspot::doGet(HotspotData *hotspot) { void Hotspot::doOperate(HotspotData *hotspot) { Resources &res = Resources::getReference(); - Action action = _currentActions.top().supportData().action(); + Action action = currentActions().top().supportData().action(); HotspotPrecheckResult result = actionPrecheck(hotspot); if (result == PC_WAIT) return; @@ -1509,7 +1491,7 @@ void Hotspot::doClose(HotspotData *hotspot) { void Hotspot::doUse(HotspotData *hotspot) { Resources &res = Resources::getReference(); - uint16 usedId = _currentActions.top().supportData().param(0); + uint16 usedId = currentActions().top().supportData().param(0); HotspotData *usedHotspot = res.getHotspot(usedId); _data->useHotspotId = usedId; @@ -1550,7 +1532,7 @@ void Hotspot::doUse(HotspotData *hotspot) { void Hotspot::doGive(HotspotData *hotspot) { Resources &res = Resources::getReference(); - uint16 usedId = _currentActions.top().supportData().param(1); + uint16 usedId = currentActions().top().supportData().param(1); HotspotData *usedHotspot = res.getHotspot(usedId); _data->useHotspotId = usedId; @@ -1662,7 +1644,7 @@ void Hotspot::doTell(HotspotData *hotspot) { if (result == 0) { // Build up sequence of commands for character to follow - CharacterScheduleEntry &cmdData = _currentActions.top().supportData(); + CharacterScheduleEntry &cmdData = currentActions().top().supportData(); character->setStartRoomNumber(character->roomNumber()); character->currentActions().clear(); character->setBlockedFlag(false); @@ -1734,7 +1716,7 @@ void Hotspot::doLookAction(HotspotData *hotspot, Action action) { void Hotspot::doAsk(HotspotData *hotspot) { Resources &res = Resources::getReference(); - uint16 usedId = _currentActions.top().supportData().param(1); + uint16 usedId = currentActions().top().supportData().param(1); Hotspot *destCharacter = res.getActiveHotspot(hotspot->hotspotId); HotspotData *usedHotspot = res.getHotspot(usedId); _data->useHotspotId = usedId; @@ -1864,7 +1846,7 @@ void Hotspot::doStatus(HotspotData *hotspot) { void Hotspot::doGoto(HotspotData *hotspot) { _exitCtr = 0; _blockedOffset = 0; - _currentActions.top().setRoomNumber(_currentActions.top().supportData().param(0)); + currentActions().top().setRoomNumber(currentActions().top().supportData().param(0)); endAction(); } @@ -1937,7 +1919,7 @@ void Hotspot::doExamine(HotspotData *hotspot) { } void Hotspot::doLockUnlock(HotspotData *hotspot) { - Action action = _currentActions.top().supportData().action(); + Action action = currentActions().top().supportData().action(); Resources &res = Resources::getReference(); ValueTableData &fields = res.fieldList(); fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId); @@ -1964,11 +1946,11 @@ void Hotspot::doLockUnlock(HotspotData *hotspot) { } void Hotspot::npcSetRoomAndBlockedOffset(HotspotData *hotspot) { - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); _exitCtr = 0; _blockedOffset = entry.param(1); - _currentActions.top().setRoomNumber(entry.param(0)); + currentActions().top().setRoomNumber(entry.param(0)); endAction(); } @@ -1994,14 +1976,14 @@ void Hotspot::npcHeySir(HotspotData *hotspot) { setCharacterMode(CHARMODE_WAIT_FOR_PLAYER); // Set the talk override to the specified Id - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); _data->talkOverride = entry.param(0); doNothing(hotspot); } void Hotspot::npcExecScript(HotspotData *hotspot) { - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); uint16 offset = entry.param(0); endAction(); Script::execute(offset); @@ -2024,7 +2006,7 @@ void Hotspot::npcSetRandomDest(HotspotData *hotspot) { void Hotspot::npcWalkingCheck(HotspotData *hotspot) { Resources &res = Resources::getReference(); ValueTableData &fields = res.fieldList(); - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); uint16 hId = entry.param(0); endAction(); @@ -2037,17 +2019,17 @@ void Hotspot::npcWalkingCheck(HotspotData *hotspot) { } void Hotspot::npcSetSupportOffset(HotspotData *hotspot) { - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); uint16 entryId = entry.param(0); CharacterScheduleEntry *newEntry = Resources::getReference(). charSchedules().getEntry(entryId, entry.parent()); - _currentActions.top().setSupportData(newEntry); + currentActions().top().setSupportData(newEntry); } void Hotspot::npcSupportOffsetConditional(HotspotData *hotspot) { Resources &res = Resources::getReference(); - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); CharacterScheduleEntry *newEntry; uint16 scriptOffset = entry.param(0); uint16 entryId = entry.param(1); @@ -2060,7 +2042,7 @@ void Hotspot::npcSupportOffsetConditional(HotspotData *hotspot) { newEntry = res.charSchedules().getEntry(entryId, entry.parent()); } - _currentActions.top().setSupportData(newEntry); + currentActions().top().setSupportData(newEntry); HotspotData *hotspotData = (newEntry->numParams() == 0) ? NULL : res.getHotspot( (newEntry->action() == USE) ? newEntry->param(1) : newEntry->param(0)); doAction(newEntry->action(), hotspotData); @@ -2069,7 +2051,7 @@ void Hotspot::npcSupportOffsetConditional(HotspotData *hotspot) { void Hotspot::npcDispatchAction(HotspotData *hotspot) { Resources &res = Resources::getReference(); ValueTableData &fields = res.fieldList(); - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); fields.setField(USE_HOTSPOT_ID, entry.param(0)); fields.setField(ACTIVE_HOTSPOT_ID, entry.param(0)); @@ -2080,7 +2062,7 @@ void Hotspot::npcDispatchAction(HotspotData *hotspot) { } else if (result != PC_WAIT) { CharacterScheduleEntry *newEntry = Resources::getReference(). charSchedules().getEntry(entry.param(0), entry.parent()); - _currentActions.top().setSupportData(newEntry); + currentActions().top().setSupportData(newEntry); HotspotData *hotspotData = (newEntry->numParams() == 0) ? NULL : res.getHotspot(newEntry->param((newEntry->action() == USE) ? 1 : 0)); @@ -2091,7 +2073,7 @@ void Hotspot::npcDispatchAction(HotspotData *hotspot) { void Hotspot::npcTalkNpcToNpc(HotspotData *hotspot) { Resources &res = Resources::getReference(); ValueTableData &fields = res.fieldList(); - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId); fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId); @@ -2124,7 +2106,7 @@ void Hotspot::npcTalkNpcToNpc(HotspotData *hotspot) { } void Hotspot::npcPause(HotspotData *hotspot) { - uint16 delayAmount = _currentActions.top().supportData().param(0); + uint16 delayAmount = currentActions().top().supportData().param(0); endAction(); setCharacterMode(CHARMODE_PAUSED); @@ -2132,7 +2114,7 @@ void Hotspot::npcPause(HotspotData *hotspot) { } void Hotspot::npcStartTalking(HotspotData *hotspot) { - CharacterScheduleEntry &entry = _currentActions.top().supportData(); + CharacterScheduleEntry &entry = currentActions().top().supportData(); uint16 stringId = entry.param(0); uint16 destHotspot = entry.param(1); @@ -2143,7 +2125,7 @@ void Hotspot::npcStartTalking(HotspotData *hotspot) { void Hotspot::npcJumpAddress(HotspotData *hotspot) { Resources &res = Resources::getReference(); ValueTableData &fields = res.fieldList(); - int procIndex = _currentActions.top().supportData().param(0); + int procIndex = currentActions().top().supportData().param(0); Hotspot *player; CharacterScheduleEntry *entry; endAction(); @@ -2163,8 +2145,8 @@ void Hotspot::npcJumpAddress(HotspotData *hotspot) { entry = res.charSchedules().getEntry(JUMP_ADDR_2_SUPPORT_ID, NULL); assert(entry); - _currentActions.clear(); - _currentActions.addFront(DISPATCH_ACTION, entry, ROOMNUM_CELLAR); + currentActions().clear(); + currentActions().addFront(DISPATCH_ACTION, entry, ROOMNUM_CELLAR); } break; @@ -2227,7 +2209,7 @@ void Hotspot::startTalk(HotspotData *charHotspot, uint16 id) { } void Hotspot::saveToStream(Common::WriteStream *stream) { - _currentActions.saveToStream(stream); + currentActions().saveToStream(stream); _pathFinder.saveToStream(stream); stream->writeUint16LE(_roomNumber); @@ -2267,7 +2249,7 @@ void Hotspot::saveToStream(Common::WriteStream *stream) { } void Hotspot::loadFromStream(Common::ReadStream *stream) { - _currentActions.loadFromStream(stream); + currentActions().loadFromStream(stream); _pathFinder.loadFromStream(stream); _roomNumber = stream->readUint16LE(); @@ -4442,214 +4424,6 @@ void PathFinder::loadFromStream(Common::ReadStream *stream) { } } -// Current action entry class methods - -CurrentActionEntry::CurrentActionEntry(CurrentAction newAction, uint16 roomNum) { - _action = newAction; - _supportData = NULL; - _dynamicSupportData = false; - _roomNumber = roomNum; -} - -CurrentActionEntry::CurrentActionEntry(CurrentAction newAction, CharacterScheduleEntry *data, uint16 roomNum) { - assert(data->parent() != NULL); - _action = newAction; - _supportData = data; - _dynamicSupportData = false; - _roomNumber = roomNum; -} - -CurrentActionEntry::CurrentActionEntry(Action newAction, uint16 roomNum, uint16 param1, uint16 param2) { - _action = DISPATCH_ACTION; - _dynamicSupportData = true; - _supportData = new CharacterScheduleEntry(); - uint16 params[2] = {param1, param2}; - _supportData->setDetails2(newAction, 2, params); - _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(); - - CharacterScheduleEntry *newEntry = Resources::getReference(). - charSchedules().getEntry(entryId, entry.parent()); - setSupportData(newEntry); -} - -void CurrentActionEntry::saveToStream(WriteStream *stream) { - debugC(ERROR_DETAILED, kLureDebugAnimations, "Saving hotspot action entry dyn=%d id=%d", - hasSupportData(), hasSupportData() ? supportData().id() : 0); - stream->writeByte((uint8) _action); - stream->writeUint16LE(_roomNumber); - stream->writeByte(hasSupportData()); - if (hasSupportData()) { - // Handle the support data - stream->writeByte(_dynamicSupportData); - if (_dynamicSupportData) { - // Write out the dynamic data - stream->writeByte(supportData().action()); - stream->writeSint16LE(supportData().numParams()); - for (int index = 0; index < supportData().numParams(); ++index) - stream->writeUint16LE(supportData().param(index)); - } else { - // Write out the Id for the static entry - stream->writeUint16LE(supportData().id()); - } - } - debugC(ERROR_DETAILED, kLureDebugAnimations, "Finished saving hotspot action entry"); -} - -CurrentActionEntry *CurrentActionEntry::loadFromStream(ReadStream *stream) { - Resources &res = Resources::getReference(); - uint8 actionNum = stream->readByte(); - if (actionNum == 0xff) return NULL; - CurrentActionEntry *result; - - uint16 roomNumber = stream->readUint16LE(); - bool hasSupportData = stream->readByte() != 0; - - if (!hasSupportData) { - // An entry that doesn't have support data - result = new CurrentActionEntry( - (CurrentAction) actionNum, roomNumber); - } else { - // Handle support data for the entry - bool dynamicData = stream->readByte() != 0; - if (dynamicData) { - // Load action entry that has dynamic data - result = new CurrentActionEntry( - (CurrentAction) actionNum, roomNumber); - result->_supportData = new CharacterScheduleEntry(); - Action action = (Action) stream->readByte(); - int numParams = stream->readSint16LE(); - uint16 *paramList = new uint16[numParams]; - for (int index = 0; index < numParams; ++index) - paramList[index] = stream->readUint16LE(); - - result->_supportData->setDetails2(action, numParams, paramList); - delete paramList; - } else { - // Load action entry with an NPC schedule entry - uint16 entryId = stream->readUint16LE(); - CharacterScheduleEntry *entry = res.charSchedules().getEntry(entryId); - result = new CurrentActionEntry((CurrentAction) actionNum, roomNumber); - result->setSupportData(entry); - } - } - - return result; -} - -void CurrentActionStack::list(char *buffer) { - ManagedList<CurrentActionEntry *>::iterator i; - - if (buffer) { - sprintf(buffer, "CurrentActionStack::list num_actions=%d\n", size()); - buffer += strlen(buffer); - } - else - printf("CurrentActionStack::list num_actions=%d\n", size()); - - for (i = _actions.begin(); i != _actions.end(); ++i) { - CurrentActionEntry *entry = *i; - if (buffer) { - sprintf(buffer, "style=%d room#=%d", entry->action(), entry->roomNumber()); - buffer += strlen(buffer); - } - else - printf("style=%d room#=%d", entry->action(), entry->roomNumber()); - - if (entry->hasSupportData()) { - CharacterScheduleEntry &rec = entry->supportData(); - - if (buffer) { - sprintf(buffer, ", action=%d params=", rec.action()); - buffer += strlen(buffer); - } - else - printf(", action=%d params=", rec.action()); - - if (rec.numParams() == 0) - if (buffer) { - strcat(buffer, "none"); - buffer += strlen(buffer); - } - else - printf("none"); - else { - for (int ctr = 0; ctr < rec.numParams(); ++ctr) { - if (ctr != 0) { - if (buffer) { - strcpy(buffer, ", "); - buffer += strlen(buffer); - } - else - printf(", "); - } - - if (buffer) { - sprintf(buffer, "%d", rec.param(ctr)); - buffer += strlen(buffer); - } else - printf("%d", rec.param(ctr)); - } - } - } - if (buffer) { - sprintf(buffer, "\n"); - buffer += strlen(buffer); - } - else - printf("\n"); - } -} - -void CurrentActionStack::saveToStream(WriteStream *stream) { - ManagedList<CurrentActionEntry *>::iterator i; - - debugC(ERROR_DETAILED, kLureDebugAnimations, "Saving hotspot action stack"); - char buffer[MAX_DESC_SIZE]; - list(buffer); - debugC(ERROR_DETAILED, kLureDebugAnimations, "%s", buffer); - - for (i = _actions.begin(); i != _actions.end(); ++i) { - CurrentActionEntry *rec = *i; - rec->saveToStream(stream); - } - stream->writeByte(0xff); // End of list marker - debugC(ERROR_DETAILED, kLureDebugAnimations, "Finished saving hotspot action stack"); -} - -void CurrentActionStack::loadFromStream(ReadStream *stream) { - CurrentActionEntry *rec; - - _actions.clear(); - while ((rec = CurrentActionEntry::loadFromStream(stream)) != NULL) - _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 */ /* */ @@ -4839,73 +4613,4 @@ void HotspotList::loadFromStream(ReadStream *stream) { } } -HotspotScheduleRecord::HotspotScheduleRecord(uint16 hId, CurrentActionStack &stack) { - hotspotId = hId; - copyFrom(stack); -} - -HotspotScheduleRecord::HotspotScheduleRecord(uint16 hId) { - hotspotId = hId; -} - -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 e47d15b238..d07939c368 100644 --- a/engines/lure/hotspots.h +++ b/engines/lure/hotspots.h @@ -95,92 +95,6 @@ public: static HandlerMethodPtr getHandler(uint16 procIndex); }; -enum CurrentAction {NO_ACTION, START_WALKING, DISPATCH_ACTION, EXEC_HOTSPOT_SCRIPT, - PROCESSING_PATH, WALKING}; - -class CurrentActionEntry { -private: - CurrentAction _action; - CharacterScheduleEntry *_supportData; - uint16 _roomNumber; - bool _dynamicSupportData; -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; - } - - CurrentAction action() { return _action; } - CharacterScheduleEntry &supportData() { - if (!_supportData) error("Access made to non-defined action support record"); - return *_supportData; - } - bool hasSupportData() { return _supportData != NULL; } - uint16 roomNumber() { return _roomNumber; } - void setAction(CurrentAction newAction) { _action = newAction; } - void setRoomNumber(uint16 roomNum) { _roomNumber = roomNum; } - void setSupportData(CharacterScheduleEntry *newRec) { - assert((newRec == NULL) || (newRec->parent() != NULL)); - _supportData = newRec; - } - void setSupportData(uint16 entryId); - - void saveToStream(WriteStream *stream); - static CurrentActionEntry *loadFromStream(ReadStream *stream); -}; - -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(); } - - bool isEmpty() { return _actions.begin() == _actions.end(); } - void clear() { _actions.clear(); } - CurrentActionEntry &top() { return **_actions.begin(); } - CurrentAction action() { return isEmpty() ? NO_ACTION : top().action(); } - void pop() { _actions.erase(_actions.begin()); } - int size() { return _actions.size(); } - void list(char *buffer); - void list() { list(NULL); } - - 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); - void loadFromStream(ReadStream *stream); - void copyFrom(CurrentActionStack &stack); -}; - class WalkingActionEntry { private: Direction _direction; @@ -251,23 +165,6 @@ struct DestStructure { Point position; }; -class HotspotScheduleRecord: public CurrentActionStack { -public: - uint16 hotspotId; - - HotspotScheduleRecord(uint16 hId, CurrentActionStack &stack); - HotspotScheduleRecord(uint16 hId); -}; - -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 @@ -296,7 +193,6 @@ private: bool _persistant; HotspotOverrideData *_override; bool _skipFlag; - CurrentActionStack _currentActions; PathFinder _pathFinder; uint16 _frameWidth; bool _frameStartsUsed; @@ -542,7 +438,10 @@ public: void doAction(); void doAction(Action action, HotspotData *hotspot); - CurrentActionStack ¤tActions() { return _currentActions; } + CurrentActionStack ¤tActions() { + assert(_data); + return _data->npcSchedule; + } PathFinder &pathFinder() { return _pathFinder; } DestStructure &tempDest() { return _tempDest; } uint16 frameCtr() { return _frameCtr; } diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp index 78ae7ec87f..a957fcf22f 100644 --- a/engines/lure/res.cpp +++ b/engines/lure/res.cpp @@ -98,7 +98,6 @@ void Resources::reset() { _fieldList.reset(); _barmanLists.reset(); - _hotspotSchedules.clear(); _talkState = TALK_NONE; _activeTalkData = NULL; @@ -179,6 +178,35 @@ void Resources::reloadData() { } delete mb; + // Load the set of NPC schedules + mb = d.getEntry(NPC_SCHEDULES_RESOURCE_ID); + + // Load the lookup list of support data indexes used in the script engine + numCharOffsets = 0; + offset = (uint16 *) mb->data(); + while (READ_LE_UINT16(offset++) != 0xffff) ++numCharOffsets; + _charOffsets = new uint16[numCharOffsets]; + offset = (uint16 *) mb->data(); + 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) { + CharacterScheduleResource *res = (CharacterScheduleResource *) (mb->data() + startOffset); + CharacterScheduleSet *newEntry = new CharacterScheduleSet(res, ++ctr); + _charSchedules.push_back(newEntry); + } + delete mb; + // Load the hotspot list mb = d.getEntry(HOTSPOT_DATA_RESOURCE_ID); HotspotResource *hsRec = (HotspotResource *) mb->data(); @@ -314,35 +342,6 @@ void Resources::reloadData() { } delete mb; - // Load the set of NPC schedules - mb = d.getEntry(NPC_SCHEDULES_RESOURCE_ID); - - // Load the lookup list of support data indexes used in the script engine - numCharOffsets = 0; - offset = (uint16 *) mb->data(); - while (READ_LE_UINT16(offset++) != 0xffff) ++numCharOffsets; - _charOffsets = new uint16[numCharOffsets]; - offset = (uint16 *) mb->data(); - 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) { - CharacterScheduleResource *res = (CharacterScheduleResource *) (mb->data() + startOffset); - CharacterScheduleSet *newEntry = new CharacterScheduleSet(res, ++ctr); - _charSchedules.push_back(newEntry); - } - delete mb; - // Load the list of room exit hotspot Ids mb = d.getEntry(EXIT_HOTSPOT_ID_LIST); RoomExitIndexedHotspotResource *indexedRec = (RoomExitIndexedHotspotResource *) mb->data(); @@ -730,8 +729,21 @@ void Resources::saveToStream(Common::WriteStream *stream) { // Save basic fields stream->writeUint16LE(_talkingCharacter); + // Save out the schedule for any non-active NPCs + HotspotDataList::iterator i; + for (i = _hotspotData.begin(); i != _hotspotData.end(); ++i) { + HotspotData *rec = *i; + if (!rec->npcSchedule.isEmpty()) { + Hotspot *h = getActiveHotspot(rec->hotspotId); + if (h == NULL) { + stream->writeUint16LE(rec->hotspotId); + rec->npcSchedule.saveToStream(stream); + } + } + } + stream->writeUint16LE(0xffff); + // Save sublist data - _hotspotSchedules.saveToStream(stream); _hotspotData.saveToStream(stream); _activeHotspots.saveToStream(stream); _fieldList.saveToStream(stream); @@ -756,10 +768,15 @@ void Resources::loadFromStream(Common::ReadStream *stream) { _talkState = TALK_NONE; _activeTalkData = NULL; - _hotspotSchedules.clear(); if (saveVersion >= 31) { - _hotspotSchedules.loadFromStream(stream); - debugC(ERROR_DETAILED, kLureDebugScripts, "Loading hotspot schedules"); + // Load in any schedules for non-active NPCS + debugC(ERROR_DETAILED, kLureDebugScripts, "Loading NPC schedules"); + uint16 hotspotId; + while ((hotspotId = stream->readUint16LE()) != 0xffff) { + HotspotData *hotspot = getHotspot(hotspotId); + assert(hotspot); + hotspot->npcSchedule.loadFromStream(stream); + } } debugC(ERROR_DETAILED, kLureDebugScripts, "Loading hotspot data"); diff --git a/engines/lure/res.h b/engines/lure/res.h index aaf50754f9..ac0430e32d 100644 --- a/engines/lure/res.h +++ b/engines/lure/res.h @@ -79,7 +79,6 @@ private: PausedCharacterList _pausedList; BarmanLists _barmanLists; StringList _stringList; - HotspotSchedules _hotspotSchedules; int numCharOffsets; uint16 *_charOffsets; @@ -135,7 +134,6 @@ 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 ece6e40372..db2207445c 100644 --- a/engines/lure/res_struct.cpp +++ b/engines/lure/res_struct.cpp @@ -23,9 +23,10 @@ * */ -#include "lure/res.h" #include "lure/disk.h" #include "lure/lure.h" +#include "lure/res.h" +#include "lure/res_struct.h" #include "lure/scripts.h" #include "common/endian.h" @@ -412,7 +413,6 @@ HotspotData::HotspotData(HotspotResource *rec) { tickProcId = READ_LE_UINT16(&rec->tickProcId); tickTimeout = READ_LE_UINT16(&rec->tickTimeout); tickScriptOffset = READ_LE_UINT16(&rec->tickScriptOffset); - npcSchedule = READ_LE_UINT16(&rec->npcSchedule); characterMode = (CharacterMode) READ_LE_UINT16(&rec->characterMode); delayCtr = READ_LE_UINT16(&rec->delayCtr); flags2 = READ_LE_UINT16(&rec->flags2); @@ -433,6 +433,14 @@ HotspotData::HotspotData(HotspotResource *rec) { talkOverride = 0; talkGate = 0; scriptHotspotId = 0; + + // Set up NPC schedule if any + uint16 npcScheduleId = READ_LE_UINT16(&rec->npcSchedule); + if (npcScheduleId != 0) { + Resources &res = Resources::getReference(); + CharacterScheduleEntry *entry = res.charSchedules().getEntry(npcScheduleId); + npcSchedule.addFront(DISPATCH_ACTION, entry, roomNumber); + } } void HotspotData::saveToStream(WriteStream *stream) { @@ -834,7 +842,7 @@ void SequenceDelayList::loadFromStream(ReadStream *stream) { } } -// The following classes hold the NPC schedule classes +// The following classes hold the NPC schedules CharacterScheduleEntry::CharacterScheduleEntry(Action theAction, ...) { _parent = NULL; @@ -1320,4 +1328,214 @@ void ValueTableData::loadFromStream(Common::ReadStream *stream) { _fieldList[index] = stream->readUint16LE(); } +/*-------------------------------------------------------------------------*/ + +// Current action entry class methods + +CurrentActionEntry::CurrentActionEntry(CurrentAction newAction, uint16 roomNum) { + _action = newAction; + _supportData = NULL; + _dynamicSupportData = false; + _roomNumber = roomNum; +} + +CurrentActionEntry::CurrentActionEntry(CurrentAction newAction, CharacterScheduleEntry *data, uint16 roomNum) { + assert(data->parent() != NULL); + _action = newAction; + _supportData = data; + _dynamicSupportData = false; + _roomNumber = roomNum; +} + +CurrentActionEntry::CurrentActionEntry(Action newAction, uint16 roomNum, uint16 param1, uint16 param2) { + _action = DISPATCH_ACTION; + _dynamicSupportData = true; + _supportData = new CharacterScheduleEntry(); + uint16 params[2] = {param1, param2}; + _supportData->setDetails2(newAction, 2, params); + _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(); + + CharacterScheduleEntry *newEntry = Resources::getReference(). + charSchedules().getEntry(entryId, entry.parent()); + setSupportData(newEntry); +} + +void CurrentActionEntry::saveToStream(WriteStream *stream) { + debugC(ERROR_DETAILED, kLureDebugAnimations, "Saving hotspot action entry dyn=%d id=%d", + hasSupportData(), hasSupportData() ? supportData().id() : 0); + stream->writeByte((uint8) _action); + stream->writeUint16LE(_roomNumber); + stream->writeByte(hasSupportData()); + if (hasSupportData()) { + // Handle the support data + stream->writeByte(_dynamicSupportData); + if (_dynamicSupportData) { + // Write out the dynamic data + stream->writeByte(supportData().action()); + stream->writeSint16LE(supportData().numParams()); + for (int index = 0; index < supportData().numParams(); ++index) + stream->writeUint16LE(supportData().param(index)); + } else { + // Write out the Id for the static entry + stream->writeUint16LE(supportData().id()); + } + } + debugC(ERROR_DETAILED, kLureDebugAnimations, "Finished saving hotspot action entry"); +} + +CurrentActionEntry *CurrentActionEntry::loadFromStream(ReadStream *stream) { + Resources &res = Resources::getReference(); + uint8 actionNum = stream->readByte(); + if (actionNum == 0xff) return NULL; + CurrentActionEntry *result; + + uint16 roomNumber = stream->readUint16LE(); + bool hasSupportData = stream->readByte() != 0; + + if (!hasSupportData) { + // An entry that doesn't have support data + result = new CurrentActionEntry( + (CurrentAction) actionNum, roomNumber); + } else { + // Handle support data for the entry + bool dynamicData = stream->readByte() != 0; + if (dynamicData) { + // Load action entry that has dynamic data + result = new CurrentActionEntry( + (CurrentAction) actionNum, roomNumber); + result->_supportData = new CharacterScheduleEntry(); + Action action = (Action) stream->readByte(); + int numParams = stream->readSint16LE(); + uint16 *paramList = new uint16[numParams]; + for (int index = 0; index < numParams; ++index) + paramList[index] = stream->readUint16LE(); + + result->_supportData->setDetails2(action, numParams, paramList); + delete paramList; + } else { + // Load action entry with an NPC schedule entry + uint16 entryId = stream->readUint16LE(); + CharacterScheduleEntry *entry = res.charSchedules().getEntry(entryId); + result = new CurrentActionEntry((CurrentAction) actionNum, roomNumber); + result->setSupportData(entry); + } + } + + return result; +} + +void CurrentActionStack::list(char *buffer) { + ManagedList<CurrentActionEntry *>::iterator i; + + if (buffer) { + sprintf(buffer, "CurrentActionStack::list num_actions=%d\n", size()); + buffer += strlen(buffer); + } + else + printf("CurrentActionStack::list num_actions=%d\n", size()); + + for (i = _actions.begin(); i != _actions.end(); ++i) { + CurrentActionEntry *entry = *i; + if (buffer) { + sprintf(buffer, "style=%d room#=%d", entry->action(), entry->roomNumber()); + buffer += strlen(buffer); + } + else + printf("style=%d room#=%d", entry->action(), entry->roomNumber()); + + if (entry->hasSupportData()) { + CharacterScheduleEntry &rec = entry->supportData(); + + if (buffer) { + sprintf(buffer, ", action=%d params=", rec.action()); + buffer += strlen(buffer); + } + else + printf(", action=%d params=", rec.action()); + + if (rec.numParams() == 0) + if (buffer) { + strcat(buffer, "none"); + buffer += strlen(buffer); + } + else + printf("none"); + else { + for (int ctr = 0; ctr < rec.numParams(); ++ctr) { + if (ctr != 0) { + if (buffer) { + strcpy(buffer, ", "); + buffer += strlen(buffer); + } + else + printf(", "); + } + + if (buffer) { + sprintf(buffer, "%d", rec.param(ctr)); + buffer += strlen(buffer); + } else + printf("%d", rec.param(ctr)); + } + } + } + if (buffer) { + sprintf(buffer, "\n"); + buffer += strlen(buffer); + } + else + printf("\n"); + } +} + +void CurrentActionStack::saveToStream(WriteStream *stream) { + ManagedList<CurrentActionEntry *>::iterator i; + + debugC(ERROR_DETAILED, kLureDebugAnimations, "Saving hotspot action stack"); + char buffer[MAX_DESC_SIZE]; + list(buffer); + debugC(ERROR_DETAILED, kLureDebugAnimations, "%s", buffer); + + for (i = _actions.begin(); i != _actions.end(); ++i) { + CurrentActionEntry *rec = *i; + rec->saveToStream(stream); + } + stream->writeByte(0xff); // End of list marker + debugC(ERROR_DETAILED, kLureDebugAnimations, "Finished saving hotspot action stack"); +} + +void CurrentActionStack::loadFromStream(ReadStream *stream) { + CurrentActionEntry *rec; + + _actions.clear(); + while ((rec = CurrentActionEntry::loadFromStream(stream)) != NULL) + _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)); + } +} + } // end of namespace Lure diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h index b53b254ad4..bf518bf307 100644 --- a/engines/lure/res_struct.h +++ b/engines/lure/res_struct.h @@ -439,8 +439,120 @@ enum BlockedState {BS_NONE, BS_INITIAL, BS_FINAL}; enum VariantBool {VB_INITIAL, VB_FALSE, VB_TRUE}; +enum CurrentAction {NO_ACTION, START_WALKING, DISPATCH_ACTION, EXEC_HOTSPOT_SCRIPT, + PROCESSING_PATH, WALKING}; + +class CharacterScheduleSet; + +class CharacterScheduleEntry { +private: + CharacterScheduleSet *_parent; + Action _action; + uint16 _params[MAX_TELL_COMMANDS * 3]; + int _numParams; +public: + CharacterScheduleEntry() { _action = NONE; _parent = NULL; } + CharacterScheduleEntry(Action theAction, ...); + CharacterScheduleEntry(CharacterScheduleSet *parentSet, + CharacterScheduleResource *&rec); + CharacterScheduleEntry(CharacterScheduleEntry *src); + + Action action() { return _action; } + int numParams() { return _numParams; } + uint16 param(int index); + void setDetails(Action theAction, ...); + void setDetails2(Action theAction, int numParamEntries, uint16 *paramList); + CharacterScheduleEntry *next(); + CharacterScheduleSet *parent() { return _parent; } + uint16 id(); +}; + +class CurrentActionEntry { +private: + CurrentAction _action; + CharacterScheduleEntry *_supportData; + uint16 _roomNumber; + bool _dynamicSupportData; +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; + } + + CurrentAction action() { return _action; } + CharacterScheduleEntry &supportData() { + if (!_supportData) error("Access made to non-defined action support record"); + return *_supportData; + } + bool hasSupportData() { return _supportData != NULL; } + uint16 roomNumber() { return _roomNumber; } + void setAction(CurrentAction newAction) { _action = newAction; } + void setRoomNumber(uint16 roomNum) { _roomNumber = roomNum; } + void setSupportData(CharacterScheduleEntry *newRec) { + assert((newRec == NULL) || (newRec->parent() != NULL)); + _supportData = newRec; + } + void setSupportData(uint16 entryId); + + void saveToStream(WriteStream *stream); + static CurrentActionEntry *loadFromStream(ReadStream *stream); +}; + +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(); } + + bool isEmpty() { return _actions.begin() == _actions.end(); } + void clear() { _actions.clear(); } + CurrentActionEntry &top() { return **_actions.begin(); } + CurrentAction action() { return isEmpty() ? NO_ACTION : top().action(); } + void pop() { _actions.erase(_actions.begin()); } + int size() { return _actions.size(); } + void list(char *buffer); + void list() { list(NULL); } + + 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); + void loadFromStream(ReadStream *stream); + void copyFrom(CurrentActionStack &stack); +}; + class HotspotData { public: + CurrentActionStack npcSchedule; HotspotData(HotspotResource *rec); uint16 hotspotId; @@ -472,7 +584,6 @@ public: uint16 tickProcId; uint16 tickTimeout; uint16 tickScriptOffset; - uint16 npcSchedule; CharacterMode characterMode; uint16 delayCtr; uint8 flags2; @@ -658,31 +769,6 @@ public: extern const int actionNumParams[NPC_JUMP_ADDRESS+1]; -class CharacterScheduleSet; - -class CharacterScheduleEntry { -private: - CharacterScheduleSet *_parent; - Action _action; - uint16 _params[MAX_TELL_COMMANDS * 3]; - int _numParams; -public: - CharacterScheduleEntry() { _action = NONE; _parent = NULL; } - CharacterScheduleEntry(Action theAction, ...); - CharacterScheduleEntry(CharacterScheduleSet *parentSet, - CharacterScheduleResource *&rec); - CharacterScheduleEntry(CharacterScheduleEntry *src); - - Action action() { return _action; } - int numParams() { return _numParams; } - uint16 param(int index); - void setDetails(Action theAction, ...); - void setDetails2(Action theAction, int numParamEntries, uint16 *paramList); - CharacterScheduleEntry *next(); - CharacterScheduleSet *parent() { return _parent; } - uint16 id(); -}; - class CharacterScheduleSet: public ManagedList<CharacterScheduleEntry *> { private: uint16 _id; |