From 547716a0dfd671461a5df85535be40f650c3aa17 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 24 Oct 2007 10:09:06 +0000 Subject: Added a talkerId field to hotspots to better handle characters being talked to svn-id: r29254 --- engines/lure/hotspots.cpp | 59 +++++++++++++++++++++++++++------------------ engines/lure/res_struct.cpp | 6 ++--- engines/lure/res_struct.h | 17 +++---------- engines/lure/room.cpp | 17 +++++++++++-- engines/lure/room.h | 1 + 5 files changed, 59 insertions(+), 41 deletions(-) diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp index 550d57d9f0..5d36c2438b 100644 --- a/engines/lure/hotspots.cpp +++ b/engines/lure/hotspots.cpp @@ -749,8 +749,8 @@ void Hotspot::converse(uint16 destCharacterId, uint16 messageId, bool standStill HotspotData *hotspot = Resources::getReference().getHotspot(destCharacterId); _data->talkCountdown += hotspot->talkCountdown; - _data->talkDestCharacterId = destCharacterId; - _data->talkGate = 0; + hotspot->talkerId = _hotspotId ; + hotspot->talkGate = 0; } if (standStill) { @@ -811,6 +811,7 @@ void Hotspot::handleTalkDialog() { assert(_data); Resources &res = Resources::getReference(); ValueTableData &fields = res.fieldList(); + Game &game = Game::getReference(); Room &room = Room::getReference(); // Return if no talk dialog is necessary @@ -840,24 +841,37 @@ void Hotspot::handleTalkDialog() { charHotspot->faceHotspot(resource()); } } - - } else if ((fields.flags() & GAMEFLAG_FAST_TEXTSPEED) != 0) { +/* + } else if (game.fastTextFlag()) { // Fast text speed --_data->talkCountdown; - } else if ((fields.flags() & (GAMEFLAG_8 | GAMEFLAG_4)) != 0) { - fields.flags() |= GAMEFLAG_4; + } else if (fields.textCtr2() != 0) { + fields.textCtr2() = 1; --_data->talkCountdown; } else { --_data->talkCountdown; - fields.flags() -= GAMEFLAG_4; - } + --fields.textCtr2(); + }*/ - if (_data->talkCountdown == 0) { - // Talking is finish - stop talking and free voice animation - debugC(ERROR_DETAILED, kLureDebugAnimations, "Talk dialog close"); - room.setTalkDialog(0, 0, 0, 0); - _data->talkDestCharacterId = 0; - _data->talkGate = 0; + } else if ((room.talkDialog() != NULL) && (room.talkDialog()->isBuilding())) { + return; + + } else if (_data->talkCountdown > 0) { + --_data->talkCountdown; + + if (_data->talkCountdown == 0) { + // Talking is finish - stop talking and free voice animation + debugC(ERROR_DETAILED, kLureDebugAnimations, "Talk dialog close"); + room.setTalkDialog(0, 0, 0, 0); + + if (_data->talkDestCharacterId != 0) { + HotspotData *destChar = res.getHotspot(_data->talkDestCharacterId); + destChar->talkerId = 0; + } + + _data->talkerId = 0; + _data->talkGate = 0; + } } debugC(ERROR_DETAILED, kLureDebugAnimations, "Talk handler method end"); @@ -2314,16 +2328,15 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) { // Handle any active talk dialog h.handleTalkDialog(); - // Handle any active hotspot the character is using (for example, if the player is - // talking to a character, this stops them from moving for the duration) - if (h.resource()->talkDestCharacterId != 0) { - debugC(ERROR_DETAILED, kLureDebugAnimations, "Use Hotspot Id = %xh, talk_gate = %d", + // If someone is talking to the character, this stops them from moving for the duration) + if (h.resource()->talkerId != 0) { + debugC(ERROR_DETAILED, kLureDebugAnimations, "Talker Id = %xh, talk_gate = %d", h.resource()->talkDestCharacterId, h.talkGate()); if (h.talkGate() == GENERAL_MAGIC_ID) { fields.setField(ACTIVE_HOTSPOT_ID, h.talkGate()); - fields.setField(USE_HOTSPOT_ID, h.resource()->talkDestCharacterId); + fields.setField(USE_HOTSPOT_ID, h.resource()->talkerId); Script::execute(h.talkScript()); - h.resource()->talkDestCharacterId = 0; + h.resource()->talkerId = 0; } else { h.updateMovement(); return; @@ -3268,7 +3281,7 @@ void HotspotTickHandlers::talkAnimHandler(Hotspot &h) { // Make sure the dest character holds still while an option is selected HotspotData *destHotspot = res.getHotspot(talkDestCharacter); - destHotspot->talkDestCharacterId = h.hotspotId(); + destHotspot->talkerId = h.hotspotId(); } else { res.setTalkState(TALK_RESPOND); res.setTalkSelection(1); @@ -3486,8 +3499,8 @@ void HotspotTickHandlers::barmanAnimHandler(Hotspot &h) { h.setFrameCtr(barEntry.currentCustomer->serveFlags); barEntry.currentCustomer->serveFlags &= 0xf8; - } else if (h.resource()->talkDestCharacterId == 0) { - // Player is not currently talking + } else if (h.resource()->talkerId == 0) { + // Barman is not currently being talked to // Clear entry from list barEntry.currentCustomer->hotspotId = 0; barEntry.currentCustomer->serveFlags = 0; diff --git a/engines/lure/res_struct.cpp b/engines/lure/res_struct.cpp index b338817b93..d16ff22caa 100644 --- a/engines/lure/res_struct.cpp +++ b/engines/lure/res_struct.cpp @@ -421,6 +421,7 @@ HotspotData::HotspotData(HotspotResource *rec) { blockedFlag = false; coveredFlag = VB_INITIAL; talkMessageId = 0; + talkerId = 0; talkDestCharacterId = 0; talkCountdown = 0; useHotspotId = 0; @@ -462,6 +463,7 @@ void HotspotData::saveToStream(WriteStream *stream) { stream->writeByte((byte)blockedFlag); stream->writeByte((byte)coveredFlag); stream->writeUint16LE(talkMessageId); + stream->writeUint16LE(talkerId); stream->writeUint16LE(talkDestCharacterId); stream->writeUint16LE(talkCountdown); stream->writeUint16LE(pauseCtr); @@ -503,6 +505,7 @@ void HotspotData::loadFromStream(ReadStream *stream) { blockedFlag = stream->readByte() != 0; coveredFlag = (VariantBool)stream->readByte(); talkMessageId = stream->readUint16LE(); + talkerId = stream->readUint16LE(); talkDestCharacterId = stream->readUint16LE(); talkCountdown = stream->readUint16LE(); pauseCtr = stream->readUint16LE(); @@ -1203,7 +1206,6 @@ void ValueTableData::reset() { _playerNewPos.roomNumber = 0; _playerNewPos.position.x = 0; _playerNewPos.position.y = 0; - _flags = GAMEFLAG_4 | GAMEFLAG_1; _hdrFlagMask = 1; for (uint16 index = 0; index < NUM_VALUE_FIELDS; ++index) @@ -1245,7 +1247,6 @@ void ValueTableData::saveToStream(Common::WriteStream *stream) { stream->writeSint16LE(_playerNewPos.position.x); stream->writeSint16LE(_playerNewPos.position.y); stream->writeUint16LE(_playerNewPos.roomNumber); - stream->writeByte(_flags); stream->writeByte(_hdrFlagMask); // Write out the special fields @@ -1259,7 +1260,6 @@ void ValueTableData::loadFromStream(Common::ReadStream *stream) { _playerNewPos.position.x = stream->readSint16LE(); _playerNewPos.position.y = stream->readSint16LE(); _playerNewPos.roomNumber = stream->readUint16LE(); - _flags = stream->readByte(); _hdrFlagMask = stream->readByte(); // Read in the field list diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h index 33ec6a776f..40a801bc8d 100644 --- a/engines/lure/res_struct.h +++ b/engines/lure/res_struct.h @@ -472,6 +472,7 @@ public: bool blockedFlag; VariantBool coveredFlag; uint16 talkMessageId; + uint16 talkerId; uint16 talkDestCharacterId; uint16 talkCountdown; uint16 pauseCtr; @@ -826,17 +827,6 @@ enum FieldName { AREA_FLAG = 82 }; -enum GameFlags { - GAMEFLAG_1 = 1, - GAMEFLAG_2 = 2, - GAMEFLAG_4 = 4, - GAMEFLAG_8 = 8, - GAMEFLAG_10 = 0x10, - GAMEFLAG_20 = 0x20, - GAMEFLAG_40 = 0x40, - GAMEFLAG_FAST_TEXTSPEED = 0x80 -}; - struct PlayerNewPosition { Point position; uint16 roomNumber; @@ -846,7 +836,7 @@ class ValueTableData { private: uint16 _numGroats; PlayerNewPosition _playerNewPos; - uint8 _flags; + uint8 _textCtr1, _textCtr2; // originally 2 2-bit counters uint8 _hdrFlagMask; uint16 _fieldList[NUM_VALUE_FIELDS]; @@ -862,7 +852,8 @@ public: int size() { return NUM_VALUE_FIELDS; } uint16 &numGroats() { return _numGroats; } - uint8 &flags() { return _flags; } + uint8 &textCtr1() { return _textCtr1; } + uint8 &textCtr2() { return _textCtr2; } uint8 &hdrFlagMask() { return _hdrFlagMask; } PlayerNewPosition &playerNewPos() { return _playerNewPos; } diff --git a/engines/lure/room.cpp b/engines/lure/room.cpp index 7c77ecbce7..0dbca44d83 100644 --- a/engines/lure/room.cpp +++ b/engines/lure/room.cpp @@ -425,7 +425,7 @@ void Room::update() { // Make sure the character is still active and in the viewing room Hotspot *talkCharacter = res.getActiveHotspot(res.getTalkingCharacter()); if ((talkCharacter != NULL) && (talkCharacter->roomNumber() == _roomNumber)) - _talkDialog->surface().copyTo(&s, _talkDialogX, _talkDialogY); + _talkDialog->copyTo(&s, _talkDialogX, _talkDialogY); } // Handle showing the status line @@ -601,6 +601,7 @@ void Room::checkCursor() { } void Room::setTalkDialog(uint16 srcCharacterId, uint16 destCharacterId, uint16 usedId, uint16 stringId) { + Resources &res = Resources::getReference(); debugC(ERROR_DETAILED, kLureDebugAnimations, "Room::setTalkDialog - char=%xh string=%d", srcCharacterId, stringId); @@ -609,7 +610,16 @@ void Room::setTalkDialog(uint16 srcCharacterId, uint16 destCharacterId, uint16 u _talkDialog = NULL; } - Resources &res = Resources::getReference(); + if (res.getTalkingCharacter() != 0) { + // Signal to any talked to character that they're no longer being talked to + HotspotData *talkingChar = res.getHotspot(res.getTalkingCharacter()); + if ((talkingChar->talkDestCharacterId != 0) && + (talkingChar->talkDestCharacterId != NOONE_ID)) { + HotspotData *destChar = res.getHotspot(talkingChar->talkDestCharacterId); + destChar->talkerId = 0; + } + } + res.setTalkingCharacter(srcCharacterId); if (srcCharacterId == 0) @@ -635,6 +645,9 @@ void Room::setTalkDialog(uint16 srcCharacterId, uint16 destCharacterId, uint16 u bool Room::checkInTalkDialog() { // Make sure there is a talk dialog active if (!_talkDialog) return false; + + // Don't allow dialog close if it's still in progress + if (_talkDialog->isBuilding()) return false; // Check boundaries Mouse &mouse = Mouse::getReference(); diff --git a/engines/lure/room.h b/engines/lure/room.h index 8cda59415e..2c3fbf83cf 100644 --- a/engines/lure/room.h +++ b/engines/lure/room.h @@ -108,6 +108,7 @@ public: CursorState cursorState() { return _cursorState; } void setShowInfo(bool value) { _showInfo = value; } void setTalkDialog(uint16 srcCharacterId, uint16 destCharacterId, uint16 usedId, uint16 stringId); + TalkDialog *talkDialog() { return _talkDialog; } void setCursorState(CursorState state) { _cursorState = state; } bool isDialogActive() { return _talkDialog != NULL; } bool checkInTalkDialog(); -- cgit v1.2.3