Enhanced hotspot action so that the player will properly walk to a hotspot before performing an action

svn-id: r22209
This commit is contained in:
Paul Gilbert 2006-04-29 11:22:05 +00:00
parent 946d0582dc
commit 1192f0dfca
4 changed files with 527 additions and 189 deletions

View File

@ -281,12 +281,16 @@ void Game::handleClick() {
fields.setField(NEW_ROOM_NUMBER, oldRoomNumber); fields.setField(NEW_ROOM_NUMBER, oldRoomNumber);
fields.setField(OLD_ROOM_NUMBER, 0); fields.setField(OLD_ROOM_NUMBER, 0);
} }
} else if (res.getTalkState() != TALK_NONE) { } else if ((room.cursorState() == CS_TALKING) ||
(res.getTalkState() != TALK_NONE)) {
// Currently talking, so let it's tick proc handle it // Currently talking, so let it's tick proc handle it
} else if (mouse.y() < MENUBAR_Y_SIZE) { } else if (mouse.y() < MENUBAR_Y_SIZE) {
uint8 response = Menu::getReference().execute(); uint8 response = Menu::getReference().execute();
if (response != MENUITEM_NONE) if (response != MENUITEM_NONE)
handleMenuResponse(response); handleMenuResponse(response);
} else if ((room.cursorState() == CS_SEQUENCE) ||
(room.cursorState() == CS_UNKNOWN)) {
// No action necessary
} else { } else {
if (mouse.lButton()) if (mouse.lButton())
handleLeftClick(); handleLeftClick();
@ -303,7 +307,7 @@ void Game::handleRightClickMenu() {
HotspotData *hotspot; HotspotData *hotspot;
Action action; Action action;
uint32 actions; uint32 actions;
uint16 itemId; uint16 itemId = 0xffff;
if (room.hotspotId() != 0) { if (room.hotspotId() != 0) {
// Get hotspot actions // Get hotspot actions
@ -353,23 +357,9 @@ void Game::handleRightClickMenu() {
} }
} }
// Set fields used by the script interpreter
fields.setField(CHARACTER_HOTSPOT_ID, PLAYER_ID);
if (hotspot) {
fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
if ((action != USE) && (action != GIVE)) {
fields.setField(USE_HOTSPOT_ID, 0xffff);
}
}
if (action != NONE) { if (action != NONE) {
res.setCurrentAction(action); player->stopWalking();
room.update(); doAction(action, (hotspot != NULL) ? hotspot->hotspotId : NULL, itemId);
Screen::getReference().update();
player->doAction(action, hotspot);
if (action != TALK_TO)
res.setCurrentAction(NONE);
} }
} }
@ -377,22 +367,17 @@ void Game::handleLeftClick() {
Room &room = Room::getReference(); Room &room = Room::getReference();
Mouse &mouse = Mouse::getReference(); Mouse &mouse = Mouse::getReference();
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
ValueTableData &fields = res.fieldList();
Hotspot *player = res.getActiveHotspot(PLAYER_ID); Hotspot *player = res.getActiveHotspot(PLAYER_ID);
room.setCursorState(CS_NONE);
player->stopWalking();
player->setDestHotspot(0);
player->setActionCtr(0);
if ((room.destRoomNumber() == 0) && (room.hotspotId() != 0)) { if ((room.destRoomNumber() == 0) && (room.hotspotId() != 0)) {
// Handle look at hotspot // Handle look at hotspot
HotspotData *hs = res.getHotspot(room.hotspotId()); doAction(LOOK_AT, room.hotspotId(), 0xffff);
fields.setField(CHARACTER_HOTSPOT_ID, PLAYER_ID);
fields.setField(ACTIVE_HOTSPOT_ID, hs->hotspotId);
fields.setField(USE_HOTSPOT_ID, 0xffff);
res.setCurrentAction(LOOK_AT);
room.update();
Screen::getReference().update();
player->doAction(LOOK_AT, hs);
res.setCurrentAction(NONE);
} else if (room.destRoomNumber() != 0) { } else if (room.destRoomNumber() != 0) {
// Walk to another room // Walk to another room
RoomExitCoordinateData &exitData = RoomExitCoordinateData &exitData =
@ -406,6 +391,21 @@ void Game::handleLeftClick() {
} }
} }
void Game::doAction(Action action, uint16 hotspotId, uint16 usedId) {
Resources &res = Resources::getReference();
Room &room = Room::getReference();
ValueTableData &fields = res.fieldList();
Hotspot *player = res.getActiveHotspot(PLAYER_ID);
fields.setField(CHARACTER_HOTSPOT_ID, PLAYER_ID);
fields.setField(ACTIVE_HOTSPOT_ID, hotspotId);
fields.setField(USE_HOTSPOT_ID, usedId);
res.setCurrentAction(action);
room.setCursorState(CS_ACTION);
player->setCurrentAction(DISPATCH_ACTION, action, hotspotId, usedId);
}
void Game::doShowCredits() { void Game::doShowCredits() {
Events &events = Events::getReference(); Events &events = Events::getReference();
Mouse &mouse = Mouse::getReference(); Mouse &mouse = Mouse::getReference();

View File

@ -43,6 +43,7 @@ private:
void handleClick(); void handleClick();
void handleRightClickMenu(); void handleRightClickMenu();
void handleLeftClick(); void handleLeftClick();
void doAction(Action action, uint16 hotspotId, uint16 usedId);
void playerChangeRoom(); void playerChangeRoom();
public: public:

View File

@ -68,8 +68,8 @@ Hotspot::Hotspot(HotspotData *res): _pathFinder(this) {
_tickHandler = HotspotTickHandlers::getHandler(_data->tickProcOffset); _tickHandler = HotspotTickHandlers::getHandler(_data->tickProcOffset);
_frameCtr = 0; _frameCtr = 0;
_skipFlag = false; _skipFlag = false;
_pathfindCovered = false;
_charRectY = 0; _charRectY = 0;
_actionCtr = 0;
} }
// Special constructor used to create a voice hotspot // Special constructor used to create a voice hotspot
@ -300,10 +300,17 @@ void Hotspot::walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot) {
_destX = endPosX; _destX = endPosX;
_destY = endPosY; _destY = endPosY;
_destHotspotId = destHotspot; _destHotspotId = destHotspot;
_currentActions.clear();
setCurrentAction(START_WALKING); setCurrentAction(START_WALKING);
} }
void Hotspot::stopWalking() {
// TODO: voiceCtr = 0
_actionCtr = 0;
_currentActions.clear();
Room::getReference().setCursorState(CS_NONE);
Resources::getReference().setCurrentAction(NONE);
}
void Hotspot::setDirection(Direction dir) { void Hotspot::setDirection(Direction dir) {
_direction = dir; _direction = dir;
@ -334,7 +341,8 @@ void Hotspot::setDirection(Direction dir) {
void Hotspot::faceHotspot(HotspotData *hotspot) { void Hotspot::faceHotspot(HotspotData *hotspot) {
if (hotspot->hotspotId >= START_NONVISUAL_HOTSPOT_ID) { if (hotspot->hotspotId >= START_NONVISUAL_HOTSPOT_ID) {
// Non visual hotspot // Non visual hotspot
// TODO: setDirection(hotspot->nonVisualDirection());
} else { } else {
// Visual hotspot // Visual hotspot
int xp = x() - hotspot->startX; int xp = x() - hotspot->startX;
@ -344,23 +352,25 @@ void Hotspot::faceHotspot(HotspotData *hotspot) {
if (yp < 0) setDirection(DOWN); if (yp < 0) setDirection(DOWN);
else setDirection(UP); else setDirection(UP);
} else { } else {
if (xp < 0) setDirection(LEFT); if (xp < 0) setDirection(RIGHT);
else setDirection(RIGHT); else setDirection(LEFT);
} }
} }
if (hotspotId() == PLAYER_ID) {
Room::getReference().update();
Screen::getReference().update();
}
} }
// Sets or clears the hotspot as occupying an area in it's room's pathfinding data // Sets or clears the hotspot as occupying an area in it's room's pathfinding data
void Hotspot::setOccupied(bool occupiedFlag) { void Hotspot::setOccupied(bool occupiedFlag) {
if (occupiedFlag == _pathfindCovered) return; int xp = x() >> 3;
_pathfindCovered = occupiedFlag;
int yp = (y() - 8 + heightCopy() - 4) >> 3; int yp = (y() - 8 + heightCopy() - 4) >> 3;
int widthVal = MAX((widthCopy() >> 3), 1); int widthVal = MAX((widthCopy() >> 3), 1);
// Handle cropping for screen left // Handle cropping for screen left
int xp = (x() >> 3) - 16;
if (xp < 0) { if (xp < 0) {
xp = -xp; xp = -xp;
widthVal -= xp; widthVal -= xp;
@ -369,10 +379,9 @@ void Hotspot::setOccupied(bool occupiedFlag) {
} }
// Handle cropping for screen right // Handle cropping for screen right
int x2 = xp + widthVal; int x2 = xp + widthVal - ROOM_PATHS_WIDTH - 1;
if (x2 > ROOM_PATHS_WIDTH) { if (x2 >= 0) {
++x2; widthVal -= (x2 + 1);
widthVal -= x2;
if (widthVal <= 0) return; if (widthVal <= 0) return;
} }
@ -449,7 +458,7 @@ HotspotPrecheckResult Hotspot::actionPrecheck(HotspotData *hotspot) {
(hotspot->hotspotId == 0x429)) { (hotspot->hotspotId == 0x429)) {
// TODO: figure out specific handling code // TODO: figure out specific handling code
actionPrecheck3(hotspot); actionPrecheck3(hotspot);
return PC_0; return PC_EXECUTE;
} else { } else {
return actionPrecheck2(hotspot); return actionPrecheck2(hotspot);
} }
@ -460,24 +469,34 @@ HotspotPrecheckResult Hotspot::actionPrecheck2(HotspotData *hotspot) {
if (hotspot->roomNumber != roomNumber()) { if (hotspot->roomNumber != roomNumber()) {
// Hotspot isn't in same room as character // Hotspot isn't in same room as character
if (frameNumber() != 0) { if (_actionCtr == 0)
Dialog::showMessage(0, hotspotId()); Dialog::showMessage(0, hotspotId());
setFrameNumber(0); _actionCtr = 0;
} return PC_NOT_IN_ROOM;
return PC_1; } else if (_actionCtr != 0) {
} else if (frameNumber() != 0) { // loc_883
// TODO: loc_883 ++_actionCtr;
setFrameNumber(frameNumber() + 1);
if (frameNumber() >= 6) { if (_actionCtr >= 6) {
warning("actionCtr exceeded");
_actionCtr = 0;
Dialog::showMessage(0xD, hotspotId()); Dialog::showMessage(0xD, hotspotId());
return PC_4; return PC_EXCESS;
} }
if ((hotspot->hotspotId < 0x408)) { if (hotspot->hotspotId < FIRST_NONCHARACTER_ID) {
// TODO: Does other checks on HS[44] -> loc_886 // TODO: Does other checks on HS[44] -> loc_886
setFrameNumber(0); _actionCtr = 0;
Dialog::showMessage(0xE, hotspotId()); Dialog::showMessage(0xE, hotspotId());
return PC_2; return PC_UNKNOWN;
}
} else {
_actionCtr = 1;
if (hotspot->hotspotId < FIRST_NONCHARACTER_ID) {
// TODO: Extra Checks
Dialog::showMessage(5, hotspotId());
return PC_INITIAL;
} }
} }
@ -485,60 +504,104 @@ HotspotPrecheckResult Hotspot::actionPrecheck2(HotspotData *hotspot) {
return PC_INITIAL; return PC_INITIAL;
} else { } else {
actionPrecheck3(hotspot); actionPrecheck3(hotspot);
return PC_0; return PC_EXECUTE;
} }
} }
void Hotspot::actionPrecheck3(HotspotData *hotspot) { void Hotspot::actionPrecheck3(HotspotData *hotspot) {
setFrameNumber(0); _actionCtr = 0;
if (hotspot->hotspotId < 0x408) { if (hotspot->hotspotId < FIRST_NONCHARACTER_ID) {
// TODO: HS[44]=8, HS[42]=1E, HS[50]=ID // TODO: HS[44]=8, HS[42]=1E, HS[50]=ID
} }
} }
// Checks to see whether a character needs to walk to the given hotspot
bool Hotspot::characterWalkingCheck(HotspotData *hotspot) { bool Hotspot::characterWalkingCheck(HotspotData *hotspot) {
Resources &res = Resources::getReference();
HotspotProximityList &list = res.proximityList();
HotspotProximityList::iterator i;
int16 xp, yp; int16 xp, yp;
// Get default position if ((hotspot->walkX == 0) && (hotspot->walkY == 0)) {
xp = hotspot->startX; // The hotspot doesn't have any walk co-ordinates
yp = hotspot->startY + hotspot->heightCopy - 4; xp = hotspot->startX;
yp = hotspot->startY + hotspot->heightCopy - 4;
} else {
xp = hotspot->walkX;
yp = hotspot->walkY & 0x7fff;
if ((hotspot->walkY & 0x8000) != 0) {
// Special handling for walking
// if (((xp >> 3) != (x() >> 3)) ||
// ((((y() + heightCopy()) >> 3) - 1) != (yp >> 3))) {
if ((abs(xp - x()) > 8) ||
(abs(yp - (y() + heightCopy())) > 8)) {
walkTo(xp, yp);
return true;
} else {
return false;
}
}
}
// Scan through the list for a proximity record // Default walking handling
for (i = list.begin(); i != list.end(); ++i) { // TODO: ANIM[27h] = 1 if hotspot has walk co-ordinates
HotspotProximityData *rec = *i; if ((abs(x() - xp) >= 8) ||
if (rec->hotspotId != hotspot->hotspotId) continue; (abs(y() + heightCopy() - yp - 1) >= 19)) {
walkTo(xp, yp);
return true;
}
xp = (int16) rec->x; return false;
yp = (int16) (rec->y & 0x7fff); }
// If the high bit of the Y position is clear, use standard handling bool Hotspot::doorCloseCheck(uint16 doorId) {
// with the co-ordinates provided by the record Resources &res = Resources::getReference();
if ((rec->y & 0x8000) == 0) Hotspot *doorHotspot = res.getActiveHotspot(doorId);
break; if (!doorHotspot) {
warning("Hotspot %xh is not currently active", doorId);
// Special handling for if hi-bit of Y is set return true;
if (((x() >> 3) != (xp >> 3)) || }
((((y() + heightCopy()) >> 3) - 1) != (yp >> 3))) {
walkTo(xp, yp); Rect bounds(doorHotspot->x(), doorHotspot->y() + doorHotspot->heightCopy()
return true; - doorHotspot->yCorrection() - doorHotspot->charRectY(),
} else { doorHotspot->x() + doorHotspot->widthCopy(),
doorHotspot->y() + doorHotspot->heightCopy() + doorHotspot->charRectY());
// Loop through active hotspots
HotspotList::iterator i;
HotspotList &lst = res.activeHotspots();
for (i = lst.begin(); i != lst.end(); ++i) {
Hotspot *hsCurrent = *i;
// Skip entry if it's the door or the character
if ((hsCurrent->hotspotId() == hotspotId()) ||
(hsCurrent->hotspotId() == doorHotspot->hotspotId()))
continue;
// Skip entry if it doesn't meet certain criteria
if ((hsCurrent->layer() == 0) ||
(hsCurrent->roomNumber() != doorHotspot->roomNumber()) ||
(hsCurrent->hotspotId() < PLAYER_ID) ||
((hsCurrent->hotspotId() >= 0x408) && (hsCurrent->hotspotId() < 0x2710)))
continue;
// Also skip entry if special Id
if ((hsCurrent->hotspotId() == 0xfffe) || (hsCurrent->hotspotId() == 0xffff))
continue;
// Check the dimensions of the animation
if ((hsCurrent->x() < bounds.right) &&
((hsCurrent->x() + hsCurrent->widthCopy()) > bounds.left) &&
((hsCurrent->y() + hsCurrent->heightCopy() + hsCurrent->charRectY()) >= bounds.top) &&
((hsCurrent->y() + hsCurrent->heightCopy() - hsCurrent->charRectY()
- hsCurrent->yCorrection()) > bounds.bottom)) {
// Return false - the door can't be closed
return false; return false;
} }
} }
// Default handling // No blocking characters, so return true that the door can be closed
if ((abs(x() - xp) < 8) && (abs(y() + heightCopy() - 1 - yp) < 19))
return false;
walkTo(xp, yp);
return true; return true;
} }
/*-------------------------------------------------------------------------*/
void Hotspot::doAction(Action action, HotspotData *hotspot) { void Hotspot::doAction(Action action, HotspotData *hotspot) {
switch (action) { switch (action) {
case GET: case GET:
@ -556,10 +619,10 @@ void Hotspot::doAction(Action action, HotspotData *hotspot) {
doClose(hotspot); doClose(hotspot);
break; break;
case LOCK: case LOCK:
doSimple(hotspot, LOCK); doLockUnlock(hotspot);
break; break;
case UNLOCK: case UNLOCK:
doSimple(hotspot, UNLOCK); doLockUnlock(hotspot);
break; break;
case USE: case USE:
doUse(hotspot); doUse(hotspot);
@ -580,13 +643,13 @@ void Hotspot::doAction(Action action, HotspotData *hotspot) {
doLookAt(hotspot); doLookAt(hotspot);
break; break;
case LOOK_THROUGH: case LOOK_THROUGH:
doSimple(hotspot, LOOK_THROUGH); doLookThrough(hotspot);
break; break;
case ASK: case ASK:
doAsk(hotspot); doAsk(hotspot);
break; break;
case DRINK: case DRINK:
doDrink(); doDrink(hotspot);
break; break;
case STATUS: case STATUS:
doStatus(); doStatus();
@ -595,7 +658,7 @@ void Hotspot::doAction(Action action, HotspotData *hotspot) {
doBribe(hotspot); doBribe(hotspot);
break; break;
case EXAMINE: case EXAMINE:
doExamine(); doExamine(hotspot);
break; break;
default: default:
doSimple(hotspot, action); doSimple(hotspot, action);
@ -605,16 +668,16 @@ void Hotspot::doAction(Action action, HotspotData *hotspot) {
void Hotspot::doGet(HotspotData *hotspot) { void Hotspot::doGet(HotspotData *hotspot) {
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
HotspotPrecheckResult result = actionPrecheck(hotspot); HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return; if (result == PC_INITIAL) return;
else if (result != PC_0) { else if (result !=PC_EXECUTE) {
stopWalking(); stopWalking();
return; return;
} }
stopWalking();
faceHotspot(hotspot); faceHotspot(hotspot);
stopWalking();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, GET); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, GET);
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
@ -645,14 +708,26 @@ void Hotspot::doGet(HotspotData *hotspot) {
void Hotspot::doOperate(HotspotData *hotspot, Action action) { void Hotspot::doOperate(HotspotData *hotspot, Action action) {
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
_actionCtr = 0;
faceHotspot(hotspot);
stopWalking();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, action); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, action);
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
Dialog::showMessage(sequenceOffset, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} else if (sequenceOffset != 0) { } else {
uint16 result = Script::execute(sequenceOffset); sequenceOffset = Script::execute(sequenceOffset);
if (result > 1) if (sequenceOffset > 1)
Dialog::showMessage(result, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} }
} }
@ -665,33 +740,47 @@ void Hotspot::doOpen(HotspotData *hotspot) {
if (!joinRec->blocked) { if (!joinRec->blocked) {
// Room exit is already open // Room exit is already open
Dialog::showMessage(4, hotspotId()); Dialog::showMessage(4, hotspotId());
// TODO: jmp loc_1102 stopWalking();
return; return;
} }
} }
// TODO: Call to sub_107 and checking the results, then sub_110 HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
faceHotspot(hotspot);
_actionCtr = 0;
stopWalking();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, OPEN); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, OPEN);
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
// Message to display // Message to display
Dialog::showMessage(sequenceOffset, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} else if (sequenceOffset != 0) { return;
// Otherwise handle script }
uint16 result = Script::execute(sequenceOffset);
if (result == 0) { if (sequenceOffset != 0) {
joinRec = res.getExitJoin(hotspot->hotspotId); sequenceOffset = Script::execute(sequenceOffset);
if (joinRec->blocked) {
joinRec->blocked = 0;
if (hotspotId() != PLAYER_ID) { if (sequenceOffset == 1) return;
// TODO: HS[44h]=3, HS[42h]W = 4 if (sequenceOffset != 0) {
} // TODO: HS[60h] check
} Dialog::showMessage(sequenceOffset, hotspotId());
} else if (result != 1) { return;
// TODO: Figure out: if Hotspot-rec[60h] != 0, then set = 4 }
Dialog::showMessage(result, hotspotId()); }
joinRec = res.getExitJoin(hotspot->hotspotId);
if (joinRec->blocked) {
joinRec->blocked = 0;
if (hotspotId() != PLAYER_ID) {
// TODO: HS[44h]=3, HS[42h]W = 4
} }
} }
} }
@ -705,12 +794,21 @@ void Hotspot::doClose(HotspotData *hotspot) {
if (joinRec->blocked) { if (joinRec->blocked) {
// Room exit is already closed/blocked // Room exit is already closed/blocked
Dialog::showMessage(3, hotspotId()); Dialog::showMessage(3, hotspotId());
// TODO: jmp sub_129 stopWalking();
return; return;
} }
} }
// TODO: Call to sub_107 and checking the results, then sub_110 HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
faceHotspot(hotspot);
_actionCtr = 0;
stopWalking();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, CLOSE); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, CLOSE);
@ -719,30 +817,55 @@ void Hotspot::doClose(HotspotData *hotspot) {
Dialog::showMessage(sequenceOffset, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} else if (sequenceOffset != 0) { } else if (sequenceOffset != 0) {
// Otherwise handle script // Otherwise handle script
uint16 result = Script::execute(sequenceOffset); sequenceOffset = Script::execute(sequenceOffset);
if (result != 0) { if (sequenceOffset != 0) {
Dialog::showMessage(result, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
return;
}
}
joinRec = res.getExitJoin(hotspot->hotspotId);
if (!joinRec->blocked) {
// Close the door
if (!doorCloseCheck(joinRec->hotspot1Id) ||
!doorCloseCheck(joinRec->hotspot2Id)) {
// A character is preventing the door from closing
Dialog::showMessage(2, hotspotId());
} else { } else {
joinRec = res.getExitJoin(hotspot->hotspotId); // Flag the door as closed
if (!joinRec->blocked) { joinRec->blocked = 1;
// Close the door
// TODO: Decode sub_183 - does check to see if door is 'jammed', but
// a cursory inspection seems to indicate that the routine is more
// concerned with checking if any character is blocking the door
// if (!sub183(joinRec->0Dh) || !sub183(joinRec->0Fh)) {
// Dialog::showMessage(2, hotspotId());
// } else {
joinRec->blocked = 1;
// }
}
} }
} }
} }
void Hotspot::doUse(HotspotData *hotspot) { void Hotspot::doUse(HotspotData *hotspot) {
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
// uint16 usedId = res.fieldList().getField(USE_HOTSPOT_ID); uint16 usedId = _currentActions.top().usedId();
HotspotData *usedHotspot = res.getHotspot(usedId);
ValueTableData &fields = res.fieldList();
fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
fields.setField(USE_HOTSPOT_ID, usedHotspot->hotspotId);
if (usedHotspot->roomNumber != hotspotId()) {
// Item to be used is not in character's inventory - say "What???"
stopWalking();
Dialog::showMessage(0xF, hotspotId());
return;
}
HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
faceHotspot(hotspot);
stopWalking();
// TODO: If character=3E9h, HS[-1]=28h, HS[1Fh]=50h
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, USE); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, USE);
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
@ -750,59 +873,97 @@ void Hotspot::doUse(HotspotData *hotspot) {
} else if (sequenceOffset == 0) { } else if (sequenceOffset == 0) {
Dialog::showMessage(17, hotspotId()); Dialog::showMessage(17, hotspotId());
} else { } else {
uint16 result = Script::execute(sequenceOffset); sequenceOffset = Script::execute(sequenceOffset);
if (result != 0) if (sequenceOffset != 0)
Dialog::showMessage(result, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} }
} }
void Hotspot::doGive(HotspotData *hotspot) { void Hotspot::doGive(HotspotData *hotspot) {
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
uint16 usedId = res.fieldList().getField(USE_HOTSPOT_ID); uint16 usedId = _currentActions.top().usedId();
HotspotData *usedHotspot = res.getHotspot(usedId);
ValueTableData &fields = res.fieldList();
fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
fields.setField(USE_HOTSPOT_ID, usedId);
if (usedHotspot->roomNumber != hotspotId()) {
// Item to be used is not in character's inventory - say "What???"
stopWalking();
Dialog::showMessage(0xF, hotspotId());
return;
}
HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
faceHotspot(hotspot);
stopWalking();
if ((hotspotId() != 0x412) || (usedId != 0x2710))
Dialog::showMessage(7, hotspotId());
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, GIVE); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, GIVE);
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
Dialog::showMessage(sequenceOffset, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} else { } else if (sequenceOffset != 0) {
uint16 result = Script::execute(sequenceOffset); sequenceOffset = Script::execute(sequenceOffset);
if (result == 0x3E7) { if (sequenceOffset == NOONE_ID) {
// TODO // TODO
} else if (result == 0) { } else if (sequenceOffset == 0) {
// Move item into character's inventory // Move item into character's inventory
HotspotData *usedItem = res.getHotspot(usedId); HotspotData *usedItem = res.getHotspot(usedId);
usedItem->roomNumber = hotspotId(); usedItem->roomNumber = hotspotId();
} else if (result > 1) { } else if (sequenceOffset > 1) {
// TODO Dialog::showMessage(result, hotspotId());
} }
} }
} }
void Hotspot::doTalkTo(HotspotData *hotspot) { void Hotspot::doTalkTo(HotspotData *hotspot) {
// TODO: still some work at start Resources &res = Resources::getReference();
if ((hotspot->hotspotId != 0x3EA) && ((hotspot->roomNumber != 28) || uint16 usedId = _currentActions.top().usedId();
ValueTableData &fields = res.fieldList();
fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
fields.setField(USE_HOTSPOT_ID, usedId);
if ((hotspot->hotspotId != SKORL_ID) && ((hotspot->roomNumber != 28) ||
(hotspot->hotspotId != 0x3EB))) { (hotspot->hotspotId != 0x3EB))) {
// sub_107 call and after check
HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
} }
// Validate character is in player's room - since currently you can activate faceHotspot(hotspot);
// hotspots when you're not in the room stopWalking();
if (hotspot->roomNumber != hotspot->roomNumber) return;
Resources &res = Resources::getReference();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, TALK_TO); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, TALK_TO);
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
Dialog::showMessage(sequenceOffset, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} else if (sequenceOffset == 0) { return;
startTalk(hotspot); }
} else {
if (sequenceOffset != 0) {
uint16 result = Script::execute(sequenceOffset); uint16 result = Script::execute(sequenceOffset);
if (result == 0) { if (result != 0) {
// Start talking with character stopWalking();
startTalk(hotspot); return;
} }
} }
// Start talking with character
startTalk(hotspot);
} }
void Hotspot::doTell(HotspotData *hotspot) { void Hotspot::doTell(HotspotData *hotspot) {
@ -810,13 +971,74 @@ void Hotspot::doTell(HotspotData *hotspot) {
} }
void Hotspot::doLook() { void Hotspot::doLook() {
stopWalking();
Dialog::show(Room::getReference().descId()); Dialog::show(Room::getReference().descId());
} }
uint16 hotspotLookAtList[] = {0x411, 0x412, 0x41F, 0x420, 0x421, 0x422, 0x426,
0x427, 0x428, 0x429, 0x436, 0x437, 0};
void Hotspot::doLookAt(HotspotData *hotspot) { void Hotspot::doLookAt(HotspotData *hotspot) {
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, LOOK_AT); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, LOOK_AT);
if (hotspot->hotspotId >= FIRST_NONCHARACTER_ID) {
// Check if the hotspot appears in the list of hotspots that don't
// need to be walked to before being looked at
uint16 *tempId = &hotspotLookAtList[0];
while ((*tempId != 0) && (*tempId != hotspot->hotspotId)) ++tempId;
if (!*tempId) {
// Hotspot wasn't in the list
HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
}
}
faceHotspot(hotspot);
_actionCtr = 0;
stopWalking();
if (sequenceOffset >= 0x8000) {
Dialog::showMessage(sequenceOffset, hotspotId());
} else {
if (sequenceOffset != 0)
sequenceOffset = Script::execute(sequenceOffset);
if (sequenceOffset == 0) {
uint16 descId = (hotspot->descId2 != 0) ? hotspot->descId2 : hotspot->descId;
Dialog::show(descId);
}
}
}
void Hotspot::doLookThrough(HotspotData *hotspot) {
Resources &res = Resources::getReference();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, LOOK_THROUGH);
if (hotspot->hotspotId >= FIRST_NONCHARACTER_ID) {
// Check if the hotspot appears in the list of hotspots that don't
// need to be walked to before being looked at
uint16 *tempId = &hotspotLookAtList[0];
while ((*tempId != 0) && (*tempId != hotspot->hotspotId)) ++tempId;
if (!*tempId) {
// Hotspot wasn't in the list
HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
}
}
faceHotspot(hotspot);
_actionCtr = 0;
stopWalking();
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
Dialog::showMessage(sequenceOffset, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} else { } else {
@ -834,10 +1056,19 @@ void Hotspot::doAsk(HotspotData *hotspot) {
// TODO // TODO
} }
void Hotspot::doDrink() { void Hotspot::doDrink(HotspotData *hotspot) {
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
uint16 usedId = res.fieldList().getField(USE_HOTSPOT_ID); ValueTableData &fields = res.fieldList();
HotspotData *hotspot = res.getHotspot(usedId); fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId);
// Make sure item is in character's inventory
if (hotspot->hotspotId != hotspotId()) {
Dialog::showMessage(0xF, hotspotId());
return;
}
stopWalking();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, DRINK); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, DRINK);
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
@ -864,6 +1095,10 @@ void Hotspot::doStatus() {
StringData &strings = StringData::getReference(); StringData &strings = StringData::getReference();
Resources &resources = Resources::getReference(); Resources &resources = Resources::getReference();
Room &room = Room::getReference(); Room &room = Room::getReference();
warning("status0 %d %d", room.cursorState(), resources.getCurrentAction());
room.update();
stopWalking();
strings.getString(room.roomNumber(), buffer, NULL, NULL); strings.getString(room.roomNumber(), buffer, NULL, NULL);
strcat(buffer, "\n\nYou are carrying "); strcat(buffer, "\n\nYou are carrying ");
@ -880,7 +1115,7 @@ void Hotspot::doStatus() {
strings.getString(rec->nameId, buffer + strlen(buffer), NULL, NULL); strings.getString(rec->nameId, buffer + strlen(buffer), NULL, NULL);
} }
} }
warning("status1 %d", room.cursorState());
// If there were no items, add in the word 'nothing' // If there were no items, add in the word 'nothing'
if (numItems == 0) strcat(buffer, "nothing."); if (numItems == 0) strcat(buffer, "nothing.");
@ -895,25 +1130,67 @@ void Hotspot::doStatus() {
Screen &screen = Screen::getReference(); Screen &screen = Screen::getReference();
Mouse &mouse = Mouse::getReference(); Mouse &mouse = Mouse::getReference();
mouse.cursorOff(); mouse.cursorOff();
warning("status2 %d", room.cursorState());
Surface *s = Surface::newDialog(INFO_DIALOG_WIDTH, buffer); Surface *s = Surface::newDialog(INFO_DIALOG_WIDTH, buffer);
s->copyToScreen(INFO_DIALOG_X, (FULL_SCREEN_HEIGHT-s->height())/2); s->copyToScreen(INFO_DIALOG_X, (FULL_SCREEN_HEIGHT-s->height())/2);
warning("status3");
Events::getReference().waitForPress(); Events::getReference().waitForPress();
warning("status4");
screen.update(); screen.update();
mouse.cursorOn(); mouse.cursorOn();
} }
uint16 bribe_hotspot_list[] = {0x421, 0x879, 0x3E9, 0x8C7, 0x429, 0x8D1,
0x422, 0x8D4, 0x420, 0x8D6, 0x42B, 0x956, 0x3F2, 0xBE6, 0};
void Hotspot::doBribe(HotspotData *hotspot) { void Hotspot::doBribe(HotspotData *hotspot) {
Dialog::show("Yet to do"); Resources &res = Resources::getReference();
ValueTableData &fields = res.fieldList();
fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId);
HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
uint16 *tempId = &bribe_hotspot_list[0];
uint16 sequenceOffset = 0x14B; // Default sequence offset
while (*tempId != 0) {
if (*tempId++ == hotspotId()) {
sequenceOffset = *tempId;
if ((sequenceOffset & 0x8000) != 0)
sequenceOffset = Script::execute(sequenceOffset & 0x7fff);
break;
}
++tempId; // Move over entry's sequence offset
}
// TODO: call to talk_setup
faceHotspot(hotspot);
_actionCtr = 0;
stopWalking();
sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, BRIBE);
if (sequenceOffset != 0) {
sequenceOffset = Script::execute(sequenceOffset);
if (sequenceOffset != 0) return;
}
// TODO: handle character message display
} }
void Hotspot::doExamine() { void Hotspot::doExamine(HotspotData *hotspot) {
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
uint16 usedId = res.fieldList().getField(USE_HOTSPOT_ID); ValueTableData &fields = res.fieldList();
HotspotData *hotspot = res.getHotspot(usedId); fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId);
stopWalking();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, EXAMINE); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, EXAMINE);
if (sequenceOffset >= 0x8000) { if (sequenceOffset >= 0x8000) {
Dialog::showMessage(sequenceOffset, hotspotId()); Dialog::showMessage(sequenceOffset, hotspotId());
} else { } else {
@ -926,6 +1203,33 @@ void Hotspot::doExamine() {
} }
} }
void Hotspot::doLockUnlock(HotspotData *hotspot) {
Action action = _currentActions.top().hotspotAction();
Resources &res = Resources::getReference();
ValueTableData &fields = res.fieldList();
fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId);
HotspotPrecheckResult result = actionPrecheck(hotspot);
if (result == PC_INITIAL) return;
else if (result != PC_EXECUTE) {
stopWalking();
return;
}
faceHotspot(hotspot);
stopWalking();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, action);
if (sequenceOffset >= 0x8000) {
Dialog::showMessage(sequenceOffset, hotspotId());
} else {
if (sequenceOffset != 0)
Script::execute(sequenceOffset);
}
}
void Hotspot::doSimple(HotspotData *hotspot, Action action) { void Hotspot::doSimple(HotspotData *hotspot, Action action) {
Resources &res = Resources::getReference(); Resources &res = Resources::getReference();
uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, action); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, action);
@ -1016,18 +1320,21 @@ void HotspotTickHandlers::roomExitAnimHandler(Hotspot &h) {
} }
if ((rec->blocked != 0) && (*currentFrame != *destFrame)) { if ((rec->blocked != 0) && (*currentFrame != *destFrame)) {
// sub_178 // Closing the door
h.setOccupied(true);
++*currentFrame; ++*currentFrame;
if (*currentFrame != *destFrame) { if (*currentFrame == *destFrame) {
// cx=1 => sub_184 // TODO: play closed door sound
} }
} else if ((rec->blocked == 0) && (*currentFrame != 0)) { } else if ((rec->blocked == 0) && (*currentFrame != 0)) {
// sub_179 // Opening the door
if (*currentFrame == *destFrame) { h.setOccupied(false);
// sub_184 and other stuff TODO
}
--*currentFrame; --*currentFrame;
if (*currentFrame == *destFrame) {
//TODO: Check against script val 88 and play sound
}
} }
h.setFrameNumber(*currentFrame); h.setFrameNumber(*currentFrame);
@ -1073,9 +1380,7 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) {
h.setDestHotspot(0); h.setDestHotspot(0);
hsAction = actions.top().hotspotAction(); hsAction = actions.top().hotspotAction();
hotspotId = actions.top().hotspotId(); hotspotId = actions.top().hotspotId();
actions.pop(); hotspot = (hotspotId == 0) ? NULL : res.getHotspot(hotspotId);
hotspot = res.getHotspot(hotspotId);
h.doAction(hsAction, hotspot); h.doAction(hsAction, hotspot);
break; break;
@ -1089,7 +1394,7 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) {
case START_WALKING: case START_WALKING:
// Start the player walking to the given destination // Start the player walking to the given destination
h.setOccupied(false); // clear pathfinding area h.setOccupied(false);
// Reset the path finder / walking sequence // Reset the path finder / walking sequence
pathFinder.reset(paths); pathFinder.reset(paths);
@ -1131,7 +1436,7 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) {
if (h.walkingStep()) { if (h.walkingStep()) {
// Walking done // Walking done
actions.pop(); h.currentActions().pop();
} }
// Check for whether need to change room // Check for whether need to change room
@ -1741,7 +2046,7 @@ int Support::findIntersectingCharacters(Hotspot &h, uint16 *charList) {
// Check for basic reasons to skip checking the animation // Check for basic reasons to skip checking the animation
if ((h.hotspotId() == hotspot.hotspotId()) || (hotspot.layer() == 0) || if ((h.hotspotId() == hotspot.hotspotId()) || (hotspot.layer() == 0) ||
(h.roomNumber() != hotspot.roomNumber()) || (h.hotspotId() >= 0x408) || (h.roomNumber() != hotspot.roomNumber()) || (h.hotspotId() >= FIRST_NONCHARACTER_ID) ||
h.skipFlag()) continue; h.skipFlag()) continue;
// TODO: See why si+ANIM_HOTSPOT_OFFSET compared aganst di+ANIM_VOICE_CTR // TODO: See why si+ANIM_HOTSPOT_OFFSET compared aganst di+ANIM_VOICE_CTR

View File

@ -71,6 +71,7 @@ private:
CurrentAction _action; CurrentAction _action;
Action _hotspotAction; Action _hotspotAction;
uint16 _hotspotId; uint16 _hotspotId;
uint16 _usedId;
public: public:
CurrentActionEntry(CurrentAction newAction) { _action = newAction; } CurrentActionEntry(CurrentAction newAction) { _action = newAction; }
CurrentActionEntry(CurrentAction newAction, Action hsAction, uint16 id) { CurrentActionEntry(CurrentAction newAction, Action hsAction, uint16 id) {
@ -78,10 +79,17 @@ public:
_hotspotAction = hsAction; _hotspotAction = hsAction;
_hotspotId = id; _hotspotId = id;
} }
CurrentActionEntry(CurrentAction newAction, Action hsAction, uint16 id, uint16 uId) {
_action = newAction;
_hotspotAction = hsAction;
_hotspotId = id;
_usedId = uId;
}
CurrentAction action() { return _action; } CurrentAction action() { return _action; }
Action hotspotAction() { return _hotspotAction; } Action hotspotAction() { return _hotspotAction; }
uint16 hotspotId() { return _hotspotId; } uint16 hotspotId() { return _hotspotId; }
uint16 usedId() { return _usedId; }
}; };
class CurrentActionStack { class CurrentActionStack {
@ -95,9 +103,21 @@ public:
CurrentActionEntry &top() { return **_actions.begin(); } CurrentActionEntry &top() { return **_actions.begin(); }
CurrentAction action() { return isEmpty() ? NO_ACTION : top().action(); } CurrentAction action() { return isEmpty() ? NO_ACTION : top().action(); }
void pop() { _actions.erase(_actions.begin()); } void pop() { _actions.erase(_actions.begin()); }
void add(CurrentAction newAction) { void addBack(CurrentAction newAction) {
_actions.push_back(new CurrentActionEntry(newAction)); _actions.push_back(new CurrentActionEntry(newAction));
} }
void addBack(CurrentAction newAction, Action hsAction, uint16 id) {
_actions.push_back(new CurrentActionEntry(newAction, hsAction, id));
}
void addFront(CurrentAction newAction) {
_actions.push_front(new CurrentActionEntry(newAction));
}
void addFront(CurrentAction newAction, Action hsAction, uint16 id) {
_actions.push_front(new CurrentActionEntry(newAction, hsAction, id));
}
void addFront(CurrentAction newAction, Action hsAction, uint16 id, uint16 usedId) {
_actions.push_front(new CurrentActionEntry(newAction, hsAction, id, usedId));
}
}; };
class WalkingActionEntry { class WalkingActionEntry {
@ -156,7 +176,7 @@ public:
int &stepCtr() { return _stepCtr; } int &stepCtr() { return _stepCtr; }
}; };
enum HotspotPrecheckResult {PC_0, PC_1, PC_2, PC_INITIAL, PC_4}; enum HotspotPrecheckResult {PC_EXECUTE, PC_NOT_IN_ROOM, PC_UNKNOWN, PC_INITIAL, PC_EXCESS};
class Hotspot { class Hotspot {
private: private:
@ -183,12 +203,12 @@ private:
bool _persistant; bool _persistant;
HotspotOverrideData *_override; HotspotOverrideData *_override;
bool _skipFlag; bool _skipFlag;
bool _pathfindCovered;
CurrentActionStack _currentActions; CurrentActionStack _currentActions;
PathFinder _pathFinder; PathFinder _pathFinder;
uint16 _frameCtr; uint16 _frameCtr;
uint8 _actionCtr;
int16 _destX, _destY; int16 _destX, _destY;
uint16 _destHotspotId; uint16 _destHotspotId;
@ -200,6 +220,7 @@ private:
HotspotPrecheckResult actionPrecheck2(HotspotData *hotspot); HotspotPrecheckResult actionPrecheck2(HotspotData *hotspot);
void actionPrecheck3(HotspotData *hotspot); void actionPrecheck3(HotspotData *hotspot);
bool characterWalkingCheck(HotspotData *hotspot); bool characterWalkingCheck(HotspotData *hotspot);
bool doorCloseCheck(uint16 doorId);
// Action set // Action set
void doGet(HotspotData *hotspot); void doGet(HotspotData *hotspot);
@ -213,11 +234,12 @@ private:
void doTell(HotspotData *hotspot); void doTell(HotspotData *hotspot);
void doLook(); void doLook();
void doLookAt(HotspotData *hotspot); void doLookAt(HotspotData *hotspot);
void doLookThrough(HotspotData *hotspot);
void doAsk(HotspotData *hotspot); void doAsk(HotspotData *hotspot);
void doDrink(); void doDrink(HotspotData *hotspot);
void doStatus(); void doStatus();
void doBribe(HotspotData *hotspot); void doBribe(HotspotData *hotspot);
void doExamine(); void doExamine(HotspotData *hotspot);
void doSimple(HotspotData *hotspot, Action action); void doSimple(HotspotData *hotspot, Action action);
public: public:
Hotspot(HotspotData *res); Hotspot(HotspotData *res);
@ -283,7 +305,7 @@ public:
// Walking // Walking
void walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot = 0); void walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot = 0);
void stopWalking() { _currentActions.clear(); } void stopWalking();
void setDirection(Direction dir); void setDirection(Direction dir);
void faceHotspot(HotspotData *hotspot); void faceHotspot(HotspotData *hotspot);
void setOccupied(bool occupiedFlag); void setOccupied(bool occupiedFlag);
@ -291,12 +313,22 @@ public:
// Actions // Actions
void doAction(Action action, HotspotData *hotspot); void doAction(Action action, HotspotData *hotspot);
void setCurrentAction(CurrentAction currAction) { _currentActions.add(currAction); } void setCurrentAction(CurrentAction currAction) {
_currentActions.addFront(currAction);
}
void setCurrentAction(CurrentAction currAction, Action hsAction, uint16 id) {
_currentActions.addFront(currAction, hsAction, id);
}
void setCurrentAction(CurrentAction currAction, Action hsAction, uint16 id, uint16 usedId) {
_currentActions.addFront(currAction, hsAction, id, usedId);
}
CurrentActionStack &currentActions() { return _currentActions; } CurrentActionStack &currentActions() { return _currentActions; }
PathFinder &pathFinder() { return _pathFinder; } PathFinder &pathFinder() { return _pathFinder; }
uint16 frameCtr() { return _frameCtr; } uint16 frameCtr() { return _frameCtr; }
void setFrameCtr(uint16 value) { _frameCtr = value; } void setFrameCtr(uint16 value) { _frameCtr = value; }
void decrFrameCtr() { if (_frameCtr > 0) --_frameCtr; } void decrFrameCtr() { if (_frameCtr > 0) --_frameCtr; }
uint8 actionCtr() { return _actionCtr; }
void setActionCtr(uint8 v) { _actionCtr = v; }
}; };
typedef ManagedList<Hotspot *> HotspotList; typedef ManagedList<Hotspot *> HotspotList;