aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;