mirror of
https://github.com/libretro/scummvm.git
synced 2025-05-13 17:46:22 +00:00
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:
parent
946d0582dc
commit
1192f0dfca
@ -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();
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 ¤tActions() { return _currentActions; }
|
CurrentActionStack ¤tActions() { 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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user