aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2008-01-24 08:14:48 +0000
committerPaul Gilbert2008-01-24 08:14:48 +0000
commit2195528ca0cdf8b83af38d94562b488f4f230b32 (patch)
treed96604c1e0e6ac25fd5f28ee2f0b46eef45cbb67
parent5ca95f9d65d0269eb2a20cb076243c3c2fef15fa (diff)
downloadscummvm-rg350-2195528ca0cdf8b83af38d94562b488f4f230b32.tar.gz
scummvm-rg350-2195528ca0cdf8b83af38d94562b488f4f230b32.tar.bz2
scummvm-rg350-2195528ca0cdf8b83af38d94562b488f4f230b32.zip
Got rid of the experimental NPC Schedule store in favour of moving the NPC schedules from the active hotspot class back into the hotspot data class, similiar to how the original game implements them
svn-id: r30629
-rw-r--r--engines/lure/debugger.cpp1
-rw-r--r--engines/lure/hotspots.cpp377
-rw-r--r--engines/lure/hotspots.h109
-rw-r--r--engines/lure/res.cpp85
-rw-r--r--engines/lure/res.h2
-rw-r--r--engines/lure/res_struct.cpp224
-rw-r--r--engines/lure/res_struct.h138
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 &currentActions() { return _currentActions; }
+ CurrentActionStack &currentActions() {
+ 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;