Initial commit
This commit is contained in:
749
engines/titanic/npcs/barbot.cpp
Normal file
749
engines/titanic/npcs/barbot.cpp
Normal file
@@ -0,0 +1,749 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/barbot.h"
|
||||
#include "titanic/support/files_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
int CBarbot::_timesCalled;
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBarbot, CTrueTalkNPC)
|
||||
ON_MESSAGE(ActMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(TurnOff)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(TrueTalkSelfQueueAnimSetMsg)
|
||||
ON_MESSAGE(TrueTalkQueueUpAnimSetMsg)
|
||||
ON_MESSAGE(TrueTalkGetStateValueMsg)
|
||||
ON_MESSAGE(TrueTalkTriggerActionMsg)
|
||||
ON_MESSAGE(FrameMsg)
|
||||
ON_MESSAGE(LoadSuccessMsg)
|
||||
ON_MESSAGE(MovieFrameMsg)
|
||||
ON_MESSAGE(EnterRoomMsg)
|
||||
ON_MESSAGE(TimerMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CBarbot::FrameRanges::FrameRanges() : Common::Array<FrameRange>() {
|
||||
resize(60);
|
||||
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource("FRAMES/BARBOT");
|
||||
for (int idx = 0; idx < 60; ++idx) {
|
||||
(*this)[idx]._startFrame = stream->readUint32LE();
|
||||
(*this)[idx]._endFrame = stream->readUint32LE();
|
||||
}
|
||||
|
||||
delete stream;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
CBarbot::CBarbot() : CTrueTalkNPC() {
|
||||
_field108 = 0;
|
||||
_field10C = 0;
|
||||
_field110 = 0;
|
||||
_addedLemon = false;
|
||||
_addedTV = false;
|
||||
_addedPuret = false;
|
||||
_field120 = 0;
|
||||
_field124 = 0;
|
||||
_visCenterOnCounter = false;
|
||||
_addedVodka = false;
|
||||
_gottenDrunk = false;
|
||||
_field134 = 0;
|
||||
_field138 = 0;
|
||||
_field13C = -1;
|
||||
_volume = 30;
|
||||
_frameNum = -1;
|
||||
_field148 = -1;
|
||||
_field14C = 0;
|
||||
_field150 = 0;
|
||||
_field154 = 0;
|
||||
_glassContent = GG_DEFAULT;
|
||||
_drunkFlag = false;
|
||||
_field160 = 0;
|
||||
}
|
||||
|
||||
void CBarbot::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_field108, indent);
|
||||
file->writeNumberLine(_field10C, indent);
|
||||
file->writeNumberLine(_field110, indent);
|
||||
file->writeNumberLine(_addedLemon, indent);
|
||||
file->writeNumberLine(_addedTV, indent);
|
||||
file->writeNumberLine(_addedPuret, indent);
|
||||
file->writeNumberLine(_field120, indent);
|
||||
file->writeNumberLine(_field124, indent);
|
||||
file->writeNumberLine(_visCenterOnCounter, indent);
|
||||
|
||||
file->writeNumberLine(_timesCalled, indent);
|
||||
file->writeNumberLine(_addedVodka, indent);
|
||||
file->writeNumberLine(_gottenDrunk, indent);
|
||||
file->writeNumberLine(_field134, indent);
|
||||
file->writeNumberLine(_field138, indent);
|
||||
file->writeNumberLine(_field13C, indent);
|
||||
file->writeNumberLine(_volume, indent);
|
||||
file->writeNumberLine(_frameNum, indent);
|
||||
file->writeNumberLine(_field148, indent);
|
||||
file->writeNumberLine(_field14C, indent);
|
||||
file->writeNumberLine(_field150, indent);
|
||||
file->writeNumberLine(_field154, indent);
|
||||
file->writeNumberLine(_glassContent, indent);
|
||||
file->writeNumberLine(_drunkFlag, indent);
|
||||
file->writeNumberLine(_field160, indent);
|
||||
|
||||
CTrueTalkNPC::save(file, indent);
|
||||
}
|
||||
|
||||
void CBarbot::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_field108 = file->readNumber();
|
||||
_field10C = file->readNumber();
|
||||
_field110 = file->readNumber();
|
||||
_addedLemon = file->readNumber();
|
||||
_addedTV = file->readNumber();
|
||||
_addedPuret = file->readNumber();
|
||||
_field120 = file->readNumber();
|
||||
_field124 = file->readNumber();
|
||||
_visCenterOnCounter = file->readNumber();
|
||||
|
||||
_timesCalled = file->readNumber();
|
||||
_addedVodka = file->readNumber();
|
||||
_gottenDrunk = file->readNumber();
|
||||
_field134 = file->readNumber();
|
||||
_field138 = file->readNumber();
|
||||
_field13C = file->readNumber();
|
||||
_volume = file->readNumber();
|
||||
_frameNum = file->readNumber();
|
||||
_field148 = file->readNumber();
|
||||
_field14C = file->readNumber();
|
||||
_field150 = file->readNumber();
|
||||
_field154 = file->readNumber();
|
||||
_glassContent = (GlassGiven)file->readNumber();
|
||||
_drunkFlag = file->readNumber();
|
||||
_field160 = file->readNumber();
|
||||
|
||||
CTrueTalkNPC::load(file);
|
||||
}
|
||||
|
||||
bool CBarbot::ActMsg(CActMsg *msg) {
|
||||
if (msg->_action == "Vodka") {
|
||||
if (!_addedVodka) {
|
||||
playRange(_frames[47], MOVIE_NOTIFY_OBJECT);
|
||||
playRange(_frames[46], MOVIE_NOTIFY_OBJECT);
|
||||
playRange(_frames[40]);
|
||||
playRange(_frames[7]);
|
||||
playRange(_frames[13]);
|
||||
playRange(_frames[8]);
|
||||
playRange(_frames[40]);
|
||||
playRange(_frames[7]);
|
||||
playRange(_frames[13]);
|
||||
playRange(_frames[8]);
|
||||
playRange(_frames[7]);
|
||||
playRange(_frames[40]);
|
||||
playRange(_frames[13]);
|
||||
playRange(_frames[40]);
|
||||
playRange(_frames[7]);
|
||||
playRange(_frames[8]);
|
||||
playRange(_frames[13]);
|
||||
playRange(_frames[40], MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
_frameNum = _frames[40]._endFrame;
|
||||
}
|
||||
} else if (msg->_action == "GiveBackVisCentre") {
|
||||
if (_field134) {
|
||||
playRange(_frames[27]);
|
||||
_frameNum = _frames[27]._endFrame;
|
||||
}
|
||||
} else if (msg->_action == "Bird") {
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 2;
|
||||
statusMsg.execute("PickUpGlass");
|
||||
_glassContent = GG_BIRD;
|
||||
|
||||
playRange(_frames[32], MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent();
|
||||
playRange(_frames[30], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[30]._endFrame;
|
||||
|
||||
if (areIngredientsMissing()) {
|
||||
playRange(_frames[42], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[42]._endFrame;
|
||||
}
|
||||
|
||||
CActMsg actMsg("InTitilator");
|
||||
actMsg.execute("BeerGlass");
|
||||
} else if (msg->_action == "None") {
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 2;
|
||||
statusMsg.execute("PickUpGlass");
|
||||
_glassContent = GG_EMPTY;
|
||||
|
||||
playRange(_frames[55], MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent();
|
||||
playRange(_frames[54], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[54]._endFrame;
|
||||
} else if (msg->_action == "Mustard" || msg->_action == "Tomato") {
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 2;
|
||||
statusMsg.execute("PickUpGlass");
|
||||
_glassContent = GG_CONDIMENT;
|
||||
|
||||
playRange(_frames[55], MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent();
|
||||
playRange(_frames[54], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[54]._endFrame;
|
||||
|
||||
CActMsg actMsg("InTitilator");
|
||||
actMsg.execute("BeerGlass");
|
||||
} else if (msg->_action == "Fruit") {
|
||||
if (!_addedLemon) {
|
||||
CActMsg visibleMsg;
|
||||
visibleMsg.execute("LemonOnBar");
|
||||
startTalking(this, 250576);
|
||||
_addedLemon = true;
|
||||
|
||||
playRange(_frames[36], MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent();
|
||||
_frameNum = _frames[36]._endFrame;
|
||||
|
||||
if (areIngredientsMissing()) {
|
||||
playRange(_frames[43], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[43]._endFrame;
|
||||
}
|
||||
|
||||
CRemoveFromGameMsg removeMsg;
|
||||
removeMsg.execute("Lemon");
|
||||
}
|
||||
} else if (msg->_action == "CrushedTV") {
|
||||
if (!_addedTV) {
|
||||
CVisibleMsg visibleMsg;
|
||||
visibleMsg.execute("TVOnBar");
|
||||
startTalking(this, 250584);
|
||||
_field160 = 1;
|
||||
_addedTV = true;
|
||||
|
||||
playSound(TRANSLATE("c#5.wav", "c#65.wav"), _volume);
|
||||
playRange(_frames[35], MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent();
|
||||
playRange(_frames[34]);
|
||||
playRange(_frames[33], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[33]._endFrame;
|
||||
|
||||
if (areIngredientsMissing()) {
|
||||
playRange(_frames[41], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[41]._endFrame;
|
||||
}
|
||||
|
||||
CRemoveFromGameMsg removeMsg;
|
||||
removeMsg.execute("CrushedTV");
|
||||
}
|
||||
} else if (msg->_action == "PlayerTakesGlass") {
|
||||
playRange(_frames[53]);
|
||||
_field124 = 0;
|
||||
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 0;
|
||||
statusMsg.execute("PickUpGlass");
|
||||
} else if (msg->_action == "PlayerTakesVisCentre") {
|
||||
_visCenterOnCounter = false;
|
||||
loadFrame(0);
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 0;
|
||||
statusMsg.execute("PickUpVisCentre");
|
||||
} else if (msg->_action == "BellRing1") {
|
||||
startTalking(this, 251105);
|
||||
} else if (msg->_action == "BellRing2") {
|
||||
startTalking(this, 251107);
|
||||
} else if (msg->_action == "BellRing3") {
|
||||
startTalking(this, 250285);
|
||||
} else if (msg->_action == "GoRingBell") {
|
||||
startTalking(this, 250285);
|
||||
} else if (msg->_action == "ClickOnVision") {
|
||||
startTalking(this, 251858);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
// I think this is a remnant of early debugging code
|
||||
if (getName() != "Barbot")
|
||||
playMovie(MOVIE_REPEAT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::EnterRoomMsg(CEnterRoomMsg *msg) {
|
||||
// I think this is a remnant of early debugging code
|
||||
if (getName() != "Barbot")
|
||||
addTimer(g_vm->getRandomNumber(20000));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::TurnOn(CTurnOn *msg) {
|
||||
if (!_fieldC4) {
|
||||
_field13C = -1;
|
||||
setVisible(true);
|
||||
|
||||
CGameObject *glass = findInRoom("BeerGlass");
|
||||
if (!_gottenDrunk) {
|
||||
CVisibleMsg visibleMsg(false);
|
||||
visibleMsg.execute("BarShelfVisCentre");
|
||||
}
|
||||
|
||||
if (glass && !_addedPuret) {
|
||||
playRange(_frames[38], MOVIE_NOTIFY_OBJECT);
|
||||
playRange(_frames[58], MOVIE_NOTIFY_OBJECT);
|
||||
playRange(_frames[57], MOVIE_NOTIFY_OBJECT);
|
||||
playRange(_frames[56], MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
_frameNum = _frames[56]._endFrame;
|
||||
} else {
|
||||
playRange(_frames[38]);
|
||||
playRange(_frames[23], MOVIE_NOTIFY_OBJECT);
|
||||
playRange(_frames[21], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[21]._endFrame;
|
||||
|
||||
switch (g_vm->getRandomNumber(2)) {
|
||||
case 0:
|
||||
playRange(_frames[10], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[10]._endFrame;
|
||||
break;
|
||||
case 1:
|
||||
playRange(_frames[12], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[12]._endFrame;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_field124 = 0;
|
||||
}
|
||||
|
||||
_fieldC4 = 1;
|
||||
++_timesCalled;
|
||||
petSetArea(PET_CONVERSATION);
|
||||
setTalking(this, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::TurnOff(CTurnOff *msg) {
|
||||
if (_fieldC4) {
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 0;
|
||||
statusMsg.execute("PickUpGlass");
|
||||
statusMsg.execute("PickUpVisCentre");
|
||||
|
||||
if (_field124) {
|
||||
playRange(_frames[17], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[17]._endFrame;
|
||||
_field124 = 0;
|
||||
}
|
||||
|
||||
if (_visCenterOnCounter) {
|
||||
// Barbot will put away the vision center
|
||||
playRange(_frames[28], MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
_frameNum = _frames[28]._endFrame;
|
||||
_visCenterOnCounter = false;
|
||||
_field134 = 1;
|
||||
}
|
||||
|
||||
playRange(_frames[29], MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
movieEvent(_frames[29]._startFrame);
|
||||
_frameNum = _frames[29]._endFrame;
|
||||
_fieldC4 = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
CTurnOff offMsg;
|
||||
offMsg.execute(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
if (msg->_endFrame == _frameNum) {
|
||||
_frameNum = -1;
|
||||
_field14C = getTicksCount();
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _field148) {
|
||||
_field148 = -1;
|
||||
_field150 = getTicksCount();
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _field13C) {
|
||||
if (_field124)
|
||||
playMovie(_frames[53]._startFrame, _frames[53]._startFrame, 0);
|
||||
else if (_visCenterOnCounter)
|
||||
playMovie(_frames[27]._endFrame, _frames[27]._endFrame, 0);
|
||||
|
||||
_field13C = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[58]._endFrame || msg->_endFrame == _frames[21]._endFrame) {
|
||||
if (!_gottenDrunk) {
|
||||
CVisibleMsg visibleMsg(true);
|
||||
visibleMsg.execute("BarShelfVisCentre");
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[57]._endFrame) {
|
||||
startTalking(this, 250575);
|
||||
playSound(TRANSLATE("c#10.wav", "c#70.wav"), _volume);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[55]._endFrame) {
|
||||
playSound(TRANSLATE("c#10.wav", "c#70.wav"), _volume);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[56]._endFrame
|
||||
|| msg->_endFrame == _frames[54]._endFrame) {
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 1;
|
||||
statusMsg.execute("PickUpGlass");
|
||||
CMoveToStartPosMsg moveMsg;
|
||||
moveMsg.execute("BeerGlass");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[30]._endFrame) {
|
||||
_field124 = 0;
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 0;
|
||||
statusMsg.execute("PickUpGlass");
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[45]._endFrame) {
|
||||
if (!_gottenDrunk) {
|
||||
CVisibleMsg visibleMsg(false);
|
||||
visibleMsg.execute("BarShelfVisCentre");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[44]._endFrame) {
|
||||
_visCenterOnCounter = true;
|
||||
_gottenDrunk = true;
|
||||
startTalking(this, 250586);
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 1;
|
||||
statusMsg.execute("PickUpVisCentre");
|
||||
CPuzzleSolvedMsg solvedMsg;
|
||||
solvedMsg.execute("VisionCentre");
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[46]._endFrame) {
|
||||
if (!_gottenDrunk && !areIngredientsMissing())
|
||||
startTalking(this, 250571);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[43]._endFrame
|
||||
|| msg->_endFrame == _frames[42]._endFrame
|
||||
|| msg->_endFrame == _frames[41]._endFrame) {
|
||||
if (_field124)
|
||||
playMovie(_frames[53]._startFrame, _frames[53]._startFrame, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _frames[38]._endFrame || msg->_endFrame == _frames[23]._endFrame) {
|
||||
playSound(TRANSLATE("c#3.wav", "c#63.wav"), _volume);
|
||||
} else if (msg->_endFrame == _frames[36]._endFrame) {
|
||||
playSound(TRANSLATE("c#6.wav", "c#66.wav"), _volume);
|
||||
} else if (msg->_endFrame == _frames[35]._endFrame) {
|
||||
playSound(TRANSLATE("c#8.wav", "c#68.wav"), _volume);
|
||||
} else if (msg->_endFrame == _frames[33]._endFrame) {
|
||||
playSound(TRANSLATE("c#4.wav", "c#64.wav"), _volume);
|
||||
} else if (msg->_endFrame == _frames[32]._endFrame) {
|
||||
startTalking(this, 145);
|
||||
playSound(TRANSLATE("c#9.wav", "c#69.wav"), _volume);
|
||||
} else if (msg->_endFrame == _frames[47]._endFrame) {
|
||||
playSound(TRANSLATE("c#9.wav", "c#69.wav"), _volume);
|
||||
_addedVodka = true;
|
||||
_drunkFlag = true;
|
||||
} else if (msg->_endFrame == _frames[30]._endFrame) {
|
||||
playSound(TRANSLATE("c#4.wav", "c#64.wav"), 60);
|
||||
} else if (msg->_endFrame == _frames[29]._endFrame) {
|
||||
if (!_fieldC4) {
|
||||
performAction(true, nullptr);
|
||||
setVisible(false);
|
||||
CActMsg actMsg("ResetCount");
|
||||
actMsg.execute("BarBell");
|
||||
}
|
||||
} else if (msg->_endFrame == _frames[27]._endFrame) {
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 1;
|
||||
statusMsg.execute("PickUpVisCentre");
|
||||
_visCenterOnCounter = true;
|
||||
_field134 = 0;
|
||||
startTalking(this, 250586);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::TrueTalkSelfQueueAnimSetMsg(CTrueTalkSelfQueueAnimSetMsg *msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::TrueTalkQueueUpAnimSetMsg(CTrueTalkQueueUpAnimSetMsg *msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg) {
|
||||
switch (msg->_stateNum) {
|
||||
case 2:
|
||||
if (!_gottenDrunk) {
|
||||
if (_drunkFlag) {
|
||||
msg->_stateVal = _field134 | 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
msg->_stateVal = _field134;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
msg->_stateVal = 0;
|
||||
if (_addedLemon)
|
||||
msg->_stateVal = 1;
|
||||
if (_addedVodka)
|
||||
msg->_stateVal |= 2;
|
||||
if (_addedPuret)
|
||||
msg->_stateVal |= 4;
|
||||
if (_addedTV)
|
||||
msg->_stateVal |= 8;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
msg->_stateVal = _drunkFlag ? 1 : 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) {
|
||||
switch (msg->_action) {
|
||||
case 6:
|
||||
if (_field134) {
|
||||
playRange(_frames[27], MOVIE_NOTIFY_OBJECT);
|
||||
_frameNum = _frames[27]._endFrame;
|
||||
} else if (!_gottenDrunk && _drunkFlag) {
|
||||
playRange(_frames[45], MOVIE_NOTIFY_OBJECT);
|
||||
playRange(_frames[44], MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
_frameNum = _frames[44]._endFrame;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: {
|
||||
// "add vodka"
|
||||
CActMsg actMsg("Vodka");
|
||||
actMsg.execute(this);
|
||||
break;
|
||||
}
|
||||
|
||||
case 30:
|
||||
// "starling puret"
|
||||
_addedPuret = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::FrameMsg(CFrameMsg *msg) {
|
||||
if (!_fieldC4 || _frameNum != -1 || _field148 != -1
|
||||
|| (msg->_ticks - _field14C) <= 5000
|
||||
|| (msg->_ticks - _field150) <= 1000)
|
||||
return true;
|
||||
|
||||
if (!_drunkFlag) {
|
||||
if (++_field154 > 2) {
|
||||
playRange(_frames[0]);
|
||||
playRange(_frames[1], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[1]._endFrame;
|
||||
_field154 = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (g_vm->getRandomNumber(5)) {
|
||||
case 0:
|
||||
playRange(_frames[4], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[4]._endFrame;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
playRange(_frames[10], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[10]._endFrame;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
playRange(_frames[7], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[7]._endFrame;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
playRange(_frames[0]);
|
||||
playRange(_frames[1], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[1]._endFrame;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
playRange(_frames[3], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[3]._endFrame;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (!_field160 && !_visCenterOnCounter) {
|
||||
playRange(_frames[15], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[15]._endFrame;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
static const int CASES[23] = {
|
||||
0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7
|
||||
};
|
||||
switch (CASES[g_vm->getRandomNumber(22)]) {
|
||||
case 0:
|
||||
playRange(_frames[13], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[13]._endFrame;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
playRange(_frames[4], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[4]._endFrame;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
playRange(_frames[8], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[8]._endFrame;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
playRange(_frames[7], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[7]._endFrame;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
playRange(_frames[10], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[10]._endFrame;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
playRange(_frames[2], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[2]._endFrame;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
playRange(_frames[6], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[6]._endFrame;
|
||||
break;
|
||||
|
||||
default:
|
||||
playRange(_frames[3], MOVIE_NOTIFY_OBJECT);
|
||||
_field148 = _frames[3]._endFrame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::LoadSuccessMsg(CLoadSuccessMsg *msg) {
|
||||
_field14C = _field150 = getTicksCount();
|
||||
_frameNum = -1;
|
||||
_field148 = -1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::MovieFrameMsg(CMovieFrameMsg *msg) {
|
||||
if (msg->_frameNumber == _frames[29]._startFrame) {
|
||||
playSound(TRANSLATE("c#2.wav", "c#62.wav"), _volume);
|
||||
|
||||
} else if (msg->_frameNumber == _frames[55]._startFrame
|
||||
|| msg->_frameNumber == _frames[32]._startFrame) {
|
||||
// Finished giving the Barbot a glass
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = 0;
|
||||
statusMsg.execute("PickUpGlass");
|
||||
|
||||
if (_glassContent == GG_EMPTY) {
|
||||
// I'd rather see that full of Starling Puret
|
||||
startTalking(this, 250574);
|
||||
} else if (_glassContent > GG_EMPTY) {
|
||||
// What's this?
|
||||
startTalking(this, 250580);
|
||||
petSetArea(PET_CONVERSATION);
|
||||
}
|
||||
|
||||
_glassContent = GG_DEFAULT;
|
||||
|
||||
} else if (msg->_frameNumber == _frames[36]._startFrame) {
|
||||
CVisibleMsg visibleMsg(false);
|
||||
visibleMsg.execute("LemonOnBar");
|
||||
|
||||
} else if (msg->_frameNumber == _frames[35]._startFrame) {
|
||||
CVisibleMsg visibleMsg(false);
|
||||
visibleMsg.execute("TVOnBar");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBarbot::TimerMsg(CTimerMsg *msg) {
|
||||
if (!_fieldC4 && compareRoomNameTo("Bar")) {
|
||||
CParrotSpeakMsg speakMsg("Barbot", "AskForDrink");
|
||||
speakMsg.execute("PerchedParrot");
|
||||
addTimer(10000 + getRandomNumber(20000));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBarbot::playRange(const FrameRange &range, uint flags) {
|
||||
playMovie(range._startFrame, range._endFrame, flags);
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
116
engines/titanic/npcs/barbot.h
Normal file
116
engines/titanic/npcs/barbot.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_BARBOT_H
|
||||
#define TITANIC_BARBOT_H
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum GlassGiven { GG_DEFAULT = -1, GG_EMPTY = 0, GG_CONDIMENT = 1, GG_BIRD = 3 };
|
||||
|
||||
class CBarbot : public CTrueTalkNPC {
|
||||
struct FrameRange {
|
||||
int _startFrame;
|
||||
int _endFrame;
|
||||
FrameRange() : _startFrame(0), _endFrame(0) {}
|
||||
};
|
||||
class FrameRanges : public Common::Array<FrameRange> {
|
||||
public:
|
||||
FrameRanges();
|
||||
};
|
||||
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool ActMsg(CActMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool TurnOff(CTurnOff *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool TrueTalkSelfQueueAnimSetMsg(CTrueTalkSelfQueueAnimSetMsg *msg);
|
||||
bool TrueTalkQueueUpAnimSetMsg(CTrueTalkQueueUpAnimSetMsg *msg);
|
||||
bool TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg);
|
||||
bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg);
|
||||
bool FrameMsg(CFrameMsg *msg);
|
||||
bool LoadSuccessMsg(CLoadSuccessMsg *msg);
|
||||
bool MovieFrameMsg(CMovieFrameMsg *msg);
|
||||
bool EnterRoomMsg(CEnterRoomMsg *msg);
|
||||
bool TimerMsg(CTimerMsg *msg);
|
||||
private:
|
||||
static int _timesCalled;
|
||||
private:
|
||||
FrameRanges _frames;
|
||||
int _field108;
|
||||
int _field10C;
|
||||
int _field110;
|
||||
bool _addedLemon;
|
||||
bool _addedTV;
|
||||
bool _addedPuret;
|
||||
int _field120;
|
||||
int _field124;
|
||||
bool _visCenterOnCounter;
|
||||
bool _addedVodka;
|
||||
bool _gottenDrunk;
|
||||
int _field134;
|
||||
int _field138;
|
||||
int _field13C;
|
||||
int _volume;
|
||||
int _frameNum;
|
||||
int _field148;
|
||||
int _field14C;
|
||||
int _field150;
|
||||
int _field154;
|
||||
GlassGiven _glassContent;
|
||||
bool _drunkFlag;
|
||||
int _field160;
|
||||
private:
|
||||
/**
|
||||
* Plays a given range of movie frames
|
||||
*/
|
||||
void playRange(const FrameRange &range, uint flags = 0);
|
||||
|
||||
/**
|
||||
* Returns true if one of the ingredients (with the exception of Vodka)
|
||||
* is missing from the concoction
|
||||
*/
|
||||
bool areIngredientsMissing() const {
|
||||
return !_addedPuret || !_addedLemon || !_addedVodka;
|
||||
}
|
||||
public:
|
||||
CLASSDEF;
|
||||
CBarbot();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_BARBOT_H */
|
||||
301
engines/titanic/npcs/bellbot.cpp
Normal file
301
engines/titanic/npcs/bellbot.cpp
Normal file
@@ -0,0 +1,301 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/bellbot.h"
|
||||
#include "titanic/carry/carry.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
#include "titanic/game_manager.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBellBot, CTrueTalkNPC)
|
||||
ON_MESSAGE(OnSummonBotMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(Use)
|
||||
ON_MESSAGE(DismissBotMsg)
|
||||
ON_MESSAGE(TrueTalkTriggerActionMsg)
|
||||
ON_MESSAGE(MovieFrameMsg)
|
||||
ON_MESSAGE(PutBotBackInHisBoxMsg)
|
||||
ON_MESSAGE(NPCPlayIdleAnimationMsg)
|
||||
ON_MESSAGE(NPCPlayTalkingAnimationMsg)
|
||||
ON_MESSAGE(TimerMsg)
|
||||
ON_MESSAGE(TrueTalkGetStateValueMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechEndedMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CBellBot::CBellBot() : CTrueTalkNPC(), _field108(0) {
|
||||
}
|
||||
|
||||
void CBellBot::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_field108, indent);
|
||||
|
||||
CTrueTalkNPC::save(file, indent);
|
||||
}
|
||||
|
||||
void CBellBot::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_field108 = file->readNumber();
|
||||
|
||||
CTrueTalkNPC::load(file);
|
||||
}
|
||||
|
||||
bool CBellBot::OnSummonBotMsg(COnSummonBotMsg *msg) {
|
||||
if (msg->_value == 1) {
|
||||
_npcFlags |= NPCFLAG_MOVE_LOOP;
|
||||
} else {
|
||||
struct RoomWave {
|
||||
const char *_room;
|
||||
const char *_enSound;
|
||||
const char *_deSound;
|
||||
};
|
||||
static const RoomWave ROOM_WAVES[8] = {
|
||||
{ "EmbLobby", "z#193.wav", "z#723.wav" },
|
||||
{ "PromenadeDeck", "z#191.wav", "z#721.wav" },
|
||||
{ "Arboretum", "z#195.wav", "z#725.wav" },
|
||||
{ "Frozen Arboretum", "z#195.wav", "z#725.wav" },
|
||||
{ "Bar", "z#194.wav", "z#724.wav" },
|
||||
{ "MusicRoom", "z#192.wav", "z#722.wav" },
|
||||
{ "MusicRoomLobby", "z#192.wav", "z#722.wav" },
|
||||
{ "1stClassRestaurant", "z#190.wav", "z#720.wav" }
|
||||
};
|
||||
|
||||
int idx;
|
||||
for (idx = 0; idx < 8; ++idx) {
|
||||
if (compareRoomNameTo(ROOM_WAVES[idx]._room)) {
|
||||
playSound(TRANSLATE(ROOM_WAVES[idx]._enSound, ROOM_WAVES[idx]._deSound));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx == 8)
|
||||
playSound(TRANSLATE("z#147.wav", "z#703.wav"));
|
||||
|
||||
sleep(2000);
|
||||
_npcFlags &= ~NPCFLAG_MOVE_LOOP;
|
||||
}
|
||||
|
||||
getGameManager()->_gameState.setMode(GSMODE_CUTSCENE);
|
||||
playClip("Walk On", MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
movieEvent();
|
||||
_npcFlags |= NPCFLAG_MOVING;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
// WORKAROUND: Calling bot in front of doors and then going through them
|
||||
// can leave it in the view. Detect this and properly remove him when
|
||||
// the player returns to that view
|
||||
if (!hasActiveMovie() && msg->_newView == getParent()
|
||||
&& getPetControl()->canSummonBot("BellBot"))
|
||||
petMoveToHiddenRoom();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
if (_npcFlags & NPCFLAG_MOVING) {
|
||||
performAction(true);
|
||||
_npcFlags &= ~NPCFLAG_START_IDLING;
|
||||
CDismissBotMsg dismissMsg;
|
||||
dismissMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
if (!(_npcFlags & NPCFLAG_MOVING)) {
|
||||
CTrueTalkNPC::MovieEndMsg(msg);
|
||||
} else if (clipExistsByEnd("Walk On", msg->_endFrame)) {
|
||||
getGameManager()->_gameState.setMode(GSMODE_INTERACTIVE);
|
||||
setPosition(Point(80, 10));
|
||||
loadFrame(543);
|
||||
_npcFlags |= NPCFLAG_START_IDLING;
|
||||
if (_npcFlags & NPCFLAG_MOVE_LOOP) {
|
||||
startTalking(this, 157);
|
||||
_npcFlags &= ~NPCFLAG_MOVE_LOOP;
|
||||
}
|
||||
|
||||
setTalking(this, true);
|
||||
petSetArea(PET_CONVERSATION);
|
||||
} else if (clipExistsByEnd("Walk Off", msg->_endFrame)) {
|
||||
CPutBotBackInHisBoxMsg boxMsg;
|
||||
boxMsg.execute(this);
|
||||
|
||||
if (_npcFlags & NPCFLAG_MOVE_START)
|
||||
startAnimTimer("SummonDoorbot", 1500);
|
||||
} else {
|
||||
CTrueTalkNPC::MovieEndMsg(msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::Use(CUse *msg) {
|
||||
CCarry *item = dynamic_cast<CCarry *>(msg->_item);
|
||||
assert(item);
|
||||
item->_npcUse = "Bellbot";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::DismissBotMsg(CDismissBotMsg *msg) {
|
||||
if (_npcFlags & NPCFLAG_MOVING) {
|
||||
playClip("Walk Off", MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
movieEvent();
|
||||
if (_npcFlags & NPCFLAG_START_IDLING) {
|
||||
_npcFlags &= ~NPCFLAG_START_IDLING;
|
||||
performAction(true);
|
||||
} else {
|
||||
performAction(false);
|
||||
}
|
||||
|
||||
CActMsg actMsg("BellbotDismissed");
|
||||
actMsg.execute("BotIdleSummons");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) {
|
||||
switch (msg->_action) {
|
||||
case 1:
|
||||
case 28: {
|
||||
_npcFlags &= ~NPCFLAG_IDLING;
|
||||
CDismissBotMsg dismissMsg;
|
||||
dismissMsg.execute(this);
|
||||
break;
|
||||
}
|
||||
|
||||
case 5:
|
||||
_npcFlags &= ~NPCFLAG_MOVE_START;
|
||||
playClip("Walk Off", MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
movieEvent();
|
||||
break;
|
||||
|
||||
case 17: {
|
||||
CActMsg actMsg("ThrowTVDownWell");
|
||||
actMsg.execute("ThrowTVDownWellControl");
|
||||
break;
|
||||
}
|
||||
|
||||
case 29: {
|
||||
CActMsg actMsg("BellbotGetLight");
|
||||
actMsg.execute("BellbotGetLightCutScene");
|
||||
startTalking(this, 158);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::MovieFrameMsg(CMovieFrameMsg *msg) {
|
||||
if (clipExistsByStart("Walk Off", msg->_frameNumber)
|
||||
|| clipExistsByStart("Walk On", msg->_frameNumber)) {
|
||||
setPosition(Point(20, 10));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::PutBotBackInHisBoxMsg(CPutBotBackInHisBoxMsg *msg) {
|
||||
petMoveToHiddenRoom();
|
||||
_npcFlags &= ~NPCFLAG_START_IDLING;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) {
|
||||
static const char *const NAMES[] = {
|
||||
"Sway Side To Side", "Hit Head", "Hands On Hips", "Sway",
|
||||
"Hand Wave", "Slow Sway", "Lean Backwards",
|
||||
"Sway Side To Side 2", "Bob Up And Down", nullptr
|
||||
};
|
||||
|
||||
msg->_names = NAMES;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) {
|
||||
static const char *const NAMES[] = {
|
||||
"Hand On Hip Talking", "Hand On Hip Talking", "Hand On Hip Talking",
|
||||
"Sway Side To Side", "Lean Forward", "Hit Head", "Confidential Talking",
|
||||
"Hands On Hips", "Hands On Hips", "Hands On Hips", "Sway", "Laugh",
|
||||
"Hand Wave", "Slow Sway", "Lean Backwards", "Sway Side To Side 2",
|
||||
"Bob Up And Down", "Elbow In Hand", "Elbow In Hand", "Elbow In Hand",
|
||||
nullptr
|
||||
};
|
||||
|
||||
if (msg->_value2 == 2)
|
||||
playClip("Mother Frame");
|
||||
else
|
||||
msg->_names = NAMES;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::TimerMsg(CTimerMsg *msg) {
|
||||
if (msg->_action == "SummonDoorbot") {
|
||||
CRoomItem *room = getRoom();
|
||||
if (room) {
|
||||
CSummonBotMsg botMsg;
|
||||
botMsg._npcName = "Doorbot";
|
||||
botMsg._value = 2;
|
||||
botMsg.execute(room);
|
||||
}
|
||||
|
||||
_npcFlags &= ~NPCFLAG_MOVE_START;
|
||||
} else {
|
||||
CTrueTalkNPC::TimerMsg(msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
bool isYourStateroom = pet ? pet->isFirstClassSuite() : false;
|
||||
|
||||
if (msg->_stateNum == 7)
|
||||
msg->_stateVal = isYourStateroom ? 1 : 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBellBot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) {
|
||||
CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(msg);
|
||||
|
||||
if (msg->_dialogueId == TRANSLATE(20991, 20997)) {
|
||||
petDismissBot("DoorBot");
|
||||
getGameManager()->unlockInputHandler();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
64
engines/titanic/npcs/bellbot.h
Normal file
64
engines/titanic/npcs/bellbot.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_BELLBOT_H
|
||||
#define TITANIC_BELLBOT_H
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CBellBot : public CTrueTalkNPC {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool OnSummonBotMsg(COnSummonBotMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool Use(CUse *msg);
|
||||
bool DismissBotMsg(CDismissBotMsg *msg);
|
||||
bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg);
|
||||
bool MovieFrameMsg(CMovieFrameMsg *msg);
|
||||
bool PutBotBackInHisBoxMsg(CPutBotBackInHisBoxMsg *msg);
|
||||
bool NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg);
|
||||
bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg);
|
||||
bool TimerMsg(CTimerMsg *msg);
|
||||
bool TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg);
|
||||
bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg);
|
||||
private:
|
||||
int _field108;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CBellBot();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_BELLBOT_H */
|
||||
468
engines/titanic/npcs/bilge_succubus.cpp
Normal file
468
engines/titanic/npcs/bilge_succubus.cpp
Normal file
@@ -0,0 +1,468 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/bilge_succubus.h"
|
||||
#include "titanic/carry/chicken.h"
|
||||
#include "titanic/core/view_item.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBilgeSuccUBus, CSuccUBus)
|
||||
ON_MESSAGE(FrameMsg)
|
||||
ON_MESSAGE(PETReceiveMsg)
|
||||
ON_MESSAGE(PETDeliverMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(MouseButtonDownMsg)
|
||||
ON_MESSAGE(SubAcceptCCarryMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(TrueTalkGetStateValueMsg)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(TurnOff)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CBilgeSuccUBus::CBilgeSuccUBus() : CSuccUBus(),
|
||||
_sneezing2StartFrame(-1), _sneezing2EndFrame(-1),
|
||||
_sneezing1StartFrame(-1), _sneezing1EndFrame(-1) {
|
||||
}
|
||||
|
||||
void CBilgeSuccUBus::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_sneezing2StartFrame, indent);
|
||||
file->writeNumberLine(_sneezing2EndFrame, indent);
|
||||
file->writeNumberLine(_sneezing1StartFrame, indent);
|
||||
file->writeNumberLine(_sneezing1EndFrame, indent);
|
||||
|
||||
CSuccUBus::save(file, indent);
|
||||
}
|
||||
|
||||
void CBilgeSuccUBus::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_sneezing2StartFrame = file->readNumber();
|
||||
_sneezing2EndFrame = file->readNumber();
|
||||
_sneezing1StartFrame = file->readNumber();
|
||||
_sneezing1EndFrame = file->readNumber();
|
||||
|
||||
CSuccUBus::load(file);
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::FrameMsg(CFrameMsg *msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::PETReceiveMsg(CPETReceiveMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
|
||||
if (_motherBlocked) {
|
||||
// Mother hasn't yet been unblocked, so don't receive anything
|
||||
if (_receiveStartFrame >= 0)
|
||||
playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_WAIT_FOR_FINISH);
|
||||
if (_afterReceiveStartFrame >= 0)
|
||||
playMovie(_afterReceiveStartFrame, _afterReceiveEndFrame, MOVIE_WAIT_FOR_FINISH);
|
||||
|
||||
playSound(TRANSLATE("z#28.wav", "z#559.wav"), 70);
|
||||
} else if (!_isOn) {
|
||||
petDisplayMessage(2, SUCCUBUS_IS_IN_STANDBY);
|
||||
return false;
|
||||
} else if (!pet) {
|
||||
return false;
|
||||
} else {
|
||||
uint roomFlags = pet->getRoomFlags();
|
||||
CGameObject *mailObject = findMailByFlags(
|
||||
_fuseboxOn && compareRoomNameTo("Titania") ? RFC_TITANIA : _flagsComparison,
|
||||
roomFlags);
|
||||
|
||||
if (mailObject) {
|
||||
startTalking(this, 230004);
|
||||
_mailP = mailObject;
|
||||
if (_receiveStartFrame >= 0)
|
||||
playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
} else {
|
||||
petDisplayMessage(2, NOTHING_TO_DELIVER);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
if (!_isOn || !pet)
|
||||
return true;
|
||||
|
||||
uint petRoomFlags = pet->getRoomFlags();
|
||||
CGameObject *mailObject = findMail(petRoomFlags);
|
||||
|
||||
if (!mailObject) {
|
||||
petDisplayMessage(2, NOTHING_IN_SUCCUBUS_TRAY);
|
||||
return true;
|
||||
}
|
||||
|
||||
_sendLost = false;
|
||||
_mailP = mailObject;
|
||||
|
||||
uint roomFlags = _destRoomFlags;
|
||||
if (!pet->isSuccUBusDest(roomFlags) || getPassengerClass() > pet->getMailDestClass(roomFlags)) {
|
||||
roomFlags = pet->getSpecialRoomFlags("BilgeRoom");
|
||||
_sendLost = true;
|
||||
}
|
||||
|
||||
_isChicken = mailObject->getName() == "Chicken";
|
||||
_isFeathers = mailObject->getName() == "Feathers";
|
||||
_sendAction = SA_SENT;
|
||||
|
||||
if (_motherBlocked) {
|
||||
if (_isFeathers) {
|
||||
startTalking(this, 230022);
|
||||
_sendAction = SA_FEATHERS;
|
||||
|
||||
if (_sendStartFrame >= 0)
|
||||
playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
|
||||
if (_sneezing2StartFrame >= 0) {
|
||||
playMovie(_trayOutStartFrame, _trayOutEndFrame, MOVIE_WAIT_FOR_FINISH);
|
||||
playMovie(_sneezing1StartFrame, _sneezing1EndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
playMovie(_sneezing2StartFrame, _sneezing2EndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
lockMouse();
|
||||
}
|
||||
} else {
|
||||
startTalking(this, 230012);
|
||||
_sendAction = SA_EATEN;
|
||||
if (_sendStartFrame >= 0)
|
||||
playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
if (_receiveStartFrame >= 0)
|
||||
playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
if (_afterReceiveStartFrame >= 0)
|
||||
playMovie(_afterReceiveStartFrame, _afterReceiveEndFrame, MOVIE_WAIT_FOR_FINISH);
|
||||
}
|
||||
} else {
|
||||
if (_isFeathers) {
|
||||
startTalking(this, 230022);
|
||||
_sendAction = SA_BILGE_FEATHERS;
|
||||
|
||||
if (_sendStartFrame >= 0)
|
||||
playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
if (_receiveStartFrame >= 0)
|
||||
playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
if (_afterReceiveStartFrame >= 0)
|
||||
playMovie(_afterReceiveStartFrame, _afterReceiveEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
} else {
|
||||
sendMail(petRoomFlags, roomFlags);
|
||||
startTalking(this, 230012);
|
||||
if (_sendStartFrame >= 0) {
|
||||
_sendAction = SA_BILGE_SENT;
|
||||
playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
|
||||
if (msg->_endFrame == _trayOutEndFrame) {
|
||||
if (_offStartFrame >= 0)
|
||||
playSound(TRANSLATE("z#27.wav", "z#558.wav"));
|
||||
} else if (msg->_endFrame == _offEndFrame) {
|
||||
if (_endingStartFrame >= 0)
|
||||
playSound(TRANSLATE("z#30.wav", "z#561.wav"));
|
||||
} else {
|
||||
if (msg->_endFrame == _onEndFrame && pet) {
|
||||
if (_motherBlocked) {
|
||||
startTalking(this, getRandomNumber(1) ? 230062 : 230063);
|
||||
} else if (!findMail(pet->getRoomFlags())) {
|
||||
switch (getRandomNumber(4)) {
|
||||
case 0:
|
||||
startTalking(this, 230001);
|
||||
break;
|
||||
case 1:
|
||||
startTalking(this, 230002);
|
||||
break;
|
||||
case 2:
|
||||
startTalking(this, 230003);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (msg->_endFrame == _sendEndFrame) {
|
||||
switch (_sendAction) {
|
||||
case SA_EATEN:
|
||||
stopSound(_soundHandle, 1);
|
||||
_soundHandle = playSound(TRANSLATE("z#3.wav", "z#539.wav"), 1);
|
||||
break;
|
||||
case SA_BILGE_FEATHERS:
|
||||
stopSound(_soundHandle);
|
||||
_soundHandle = playSound(TRANSLATE("z#12.wav", "z#532.wav"));
|
||||
break;
|
||||
case SA_BILGE_SENT:
|
||||
if (_isChicken) {
|
||||
startTalking(this, 230018);
|
||||
_isChicken = false;
|
||||
} else {
|
||||
startTalking(this, 230013);
|
||||
}
|
||||
break;
|
||||
case SA_BILGE_EATEN:
|
||||
startTalking(this, 230017);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
|
||||
} else if (msg->_endFrame == _receiveEndFrame) {
|
||||
if (_mailP) {
|
||||
_mailP->petAddToInventory();
|
||||
CVisibleMsg visibleMsg(true);
|
||||
visibleMsg.execute(_mailP);
|
||||
|
||||
_mailP = nullptr;
|
||||
petSetArea(PET_INVENTORY);
|
||||
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
}
|
||||
|
||||
} else if (msg->_endFrame == _sneezing1EndFrame) {
|
||||
playSound(TRANSLATE("z#25.wav", "z#556.wav"), 70);
|
||||
playSound(TRANSLATE("z#24.wav", "z#555.wav"), 70);
|
||||
|
||||
} else if (msg->_endFrame == _sneezing2EndFrame) {
|
||||
changeView("BilgeRoomWith.Node 1.N", "");
|
||||
_motherBlocked = false;
|
||||
resetMail();
|
||||
|
||||
if (_mailP) {
|
||||
_mailP->petAddToInventory();
|
||||
CVisibleMsg visibleMsg(true);
|
||||
visibleMsg.execute(_mailP);
|
||||
|
||||
_mailP = nullptr;
|
||||
petSetArea(PET_INVENTORY);
|
||||
}
|
||||
|
||||
startTalking(this, 150);
|
||||
CBodyInBilgeRoomMsg bodyMsg;
|
||||
bodyMsg.execute("Service Elevator Entity");
|
||||
unlockMouse();
|
||||
_sendAction = SA_SENT;
|
||||
|
||||
} else {
|
||||
_sendAction = SA_SENT;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
|
||||
if (_isOn) {
|
||||
switch (getRandomNumber(4)) {
|
||||
case 0:
|
||||
case 4: {
|
||||
_isOn = false;
|
||||
CTurnOff offMsg;
|
||||
offMsg.execute(this);
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
startTalking(this, 230055);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
startTalking(this, 230067);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
startTalking(this, 230045);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
CTurnOn onMsg;
|
||||
onMsg.execute(this);
|
||||
_isOn = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
if (!msg->_item)
|
||||
return false;
|
||||
|
||||
CCarry *item = dynamic_cast<CCarry *>(msg->_item);
|
||||
if (!_isOn || !pet || !item) {
|
||||
item->petAddToInventory();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint petRoomFlags = pet->getRoomFlags();
|
||||
if (mailExists(petRoomFlags)) {
|
||||
petDisplayMessage(2, SUCCUBUS_SINGLE_DELIVERY);
|
||||
item->petAddToInventory();
|
||||
return true;
|
||||
}
|
||||
|
||||
petContainerRemove(item);
|
||||
pet->phonographAction("");
|
||||
item->setVisible(false);
|
||||
playSound(TRANSLATE("z#23.wav", "z#554.wav"));
|
||||
|
||||
CChicken *chicken = dynamic_cast<CChicken *>(item);
|
||||
bool chickenFlag = chicken ? chicken->_condiment == "None" : false;
|
||||
|
||||
if (chickenFlag) {
|
||||
if (_okStartFrame >= 0) {
|
||||
startTalking(this, 70219);
|
||||
playMovie(_okStartFrame, _okEndFrame, 0);
|
||||
}
|
||||
|
||||
if (_sendStartFrame >= 0) {
|
||||
_sendAction = SA_BILGE_EATEN;
|
||||
playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
}
|
||||
|
||||
CViewItem *view = parseView(item->_fullViewName);
|
||||
if (view) {
|
||||
item->setVisible(false);
|
||||
setPosition(item->_origPos);
|
||||
item->moveUnder(view);
|
||||
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
item->addMail(petRoomFlags);
|
||||
if (_okStartFrame >= 0)
|
||||
playMovie(_okStartFrame, _okEndFrame, 0);
|
||||
|
||||
petSetArea(PET_REMOTE);
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
petSetRemoteTarget();
|
||||
_mailP = nullptr;
|
||||
|
||||
if (_initialStartFrame >= 0)
|
||||
loadFrame(_initialStartFrame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
petDisplayMessage(2, BLANK);
|
||||
petClear();
|
||||
|
||||
if (_soundHandle != -1) {
|
||||
stopSound(_soundHandle);
|
||||
_soundHandle = -1;
|
||||
}
|
||||
|
||||
if (_isOn) {
|
||||
_isOn = false;
|
||||
if (_offStartFrame >= 0)
|
||||
playSound(TRANSLATE("z#27.wav", "z#558.wav"));
|
||||
}
|
||||
|
||||
performAction(true);
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg) {
|
||||
if (msg->_stateNum == 1)
|
||||
msg->_stateVal = _isOn;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::TurnOn(CTurnOn *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
|
||||
if (pet) {
|
||||
if (_onStartFrame >= 0) {
|
||||
playMovie(_onStartFrame, _onEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
playSound(TRANSLATE("z#26.wav", "z#557.wav"));
|
||||
}
|
||||
|
||||
if (mailExists(pet->getRoomFlags()) && _okStartFrame >= 0)
|
||||
playMovie(_okStartFrame, _okEndFrame, 0);
|
||||
|
||||
_isOn = true;
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
|
||||
setTalking(this, true);
|
||||
petSetArea(PET_REMOTE);
|
||||
petHighlightGlyph(16);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBilgeSuccUBus::TurnOff(CTurnOff *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
|
||||
if (pet && mailExists(pet->getRoomFlags()) && _trayOutStartFrame >= 0)
|
||||
playMovie(_trayOutStartFrame, _trayOutEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
else if (_trayOutEndFrame >= 0)
|
||||
playMovie(_trayOutEndFrame, _trayOutEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
|
||||
if (_soundHandle != -1) {
|
||||
stopSound(_soundHandle);
|
||||
_soundHandle = -1;
|
||||
}
|
||||
|
||||
if (_offStartFrame >= 0)
|
||||
playMovie(_offStartFrame, _offEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
|
||||
_isOn = false;
|
||||
performAction(true);
|
||||
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
64
engines/titanic/npcs/bilge_succubus.h
Normal file
64
engines/titanic/npcs/bilge_succubus.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_BILGE_SUCCUBUS_H
|
||||
#define TITANIC_BILGE_SUCCUBUS_H
|
||||
|
||||
#include "titanic/npcs/succubus.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CBilgeSuccUBus : public CSuccUBus {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool FrameMsg(CFrameMsg *msg);
|
||||
bool PETReceiveMsg(CPETReceiveMsg *msg);
|
||||
bool PETDeliverMsg(CPETDeliverMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
|
||||
bool SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg);
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool TurnOff(CTurnOff *msg);
|
||||
public:
|
||||
int _sneezing2StartFrame;
|
||||
int _sneezing2EndFrame;
|
||||
int _sneezing1StartFrame;
|
||||
int _sneezing1EndFrame;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CBilgeSuccUBus();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_BILGE_SUCCUBUS_H */
|
||||
80
engines/titanic/npcs/callbot.cpp
Normal file
80
engines/titanic/npcs/callbot.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/callbot.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
#include "titanic/game_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CCallBot, CGameObject)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CCallBot::CCallBot() : CGameObject(), _enabled(false) {
|
||||
}
|
||||
|
||||
void CCallBot::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeQuotedLine(_npcName, indent);
|
||||
file->writeNumberLine(_enabled, indent);
|
||||
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CCallBot::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_npcName = file->readString();
|
||||
_enabled = file->readNumber();
|
||||
|
||||
CGameObject::load(file);
|
||||
}
|
||||
|
||||
bool CCallBot::TurnOn(CTurnOn *msg) {
|
||||
_enabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCallBot::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
if (_enabled) {
|
||||
CRoomItem *room = getRoom();
|
||||
|
||||
if (room) {
|
||||
CGameState &gs = getGameManager()->_gameState;
|
||||
gs.setMode(GSMODE_CUTSCENE);
|
||||
|
||||
CSummonBotQueryMsg queryMsg;
|
||||
queryMsg._npcName = _npcName;
|
||||
if (queryMsg.execute(room))
|
||||
petOnSummonBot(_npcName, 0);
|
||||
|
||||
gs.setMode(GSMODE_INTERACTIVE);
|
||||
}
|
||||
|
||||
_enabled = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
53
engines/titanic/npcs/callbot.h
Normal file
53
engines/titanic/npcs/callbot.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_CALLBOT_H
|
||||
#define TITANIC_CALLBOT_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CCallBot : public CGameObject {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
protected:
|
||||
CString _npcName;
|
||||
bool _enabled;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CCallBot();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_CALLBOT_H */
|
||||
78
engines/titanic/npcs/character.cpp
Normal file
78
engines/titanic/npcs/character.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/character.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CCharacter, CGameObject)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(TurnOff)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CCharacter::CCharacter() : CGameObject(), _startFrame(0), _endFrame(0), _fieldC4(1) {
|
||||
}
|
||||
|
||||
void CCharacter::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_startFrame, indent);
|
||||
file->writeNumberLine(_endFrame, indent);
|
||||
file->writeNumberLine(_fieldC4, indent);
|
||||
file->writeQuotedLine(_charName, indent);
|
||||
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CCharacter::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_startFrame = file->readNumber();
|
||||
_endFrame = file->readNumber();
|
||||
_fieldC4 = file->readNumber();
|
||||
_charName = file->readString();
|
||||
|
||||
CGameObject::load(file);
|
||||
}
|
||||
|
||||
bool CCharacter::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
CTurnOff offMsg;
|
||||
offMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCharacter::TurnOn(CTurnOn *msg) {
|
||||
if (!_fieldC4)
|
||||
_fieldC4 = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCharacter::TurnOff(CTurnOff *msg) {
|
||||
CString charName = getName();
|
||||
if (charName == "Deskbot" || charName == "Barbot" || charName == "SuccUBus") {
|
||||
_fieldC4 = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
56
engines/titanic/npcs/character.h
Normal file
56
engines/titanic/npcs/character.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_CHARACTER_H
|
||||
#define TITANIC_CHARACTER_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CCharacter : public CGameObject {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool TurnOff(CTurnOff *msg);
|
||||
protected:
|
||||
int _startFrame;
|
||||
int _endFrame;
|
||||
int _fieldC4;
|
||||
CString _charName;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CCharacter();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_CHARACTER_H */
|
||||
363
engines/titanic/npcs/deskbot.cpp
Normal file
363
engines/titanic/npcs/deskbot.cpp
Normal file
@@ -0,0 +1,363 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/deskbot.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
#include "titanic/game_manager.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
static const char *const TALKING_NAMES[] = {
|
||||
"NeutralTalking", "HandFidget1", "HandFidget2", "LookingAround",
|
||||
"FriendlyTalking", "MoreRudeness", "HandUp", "TapFingers",
|
||||
"WaveOn", "WaveArmsAround", "HandsOverEdge",
|
||||
nullptr
|
||||
};
|
||||
|
||||
static const char *const IDLE_NAMES[] = {
|
||||
"WaveOn", "HandFidget1", "HandFidget2", "TapFingers", "HandsOverEdge",
|
||||
nullptr
|
||||
};
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDeskbot, CTrueTalkNPC)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(ActMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(TrueTalkTriggerActionMsg)
|
||||
ON_MESSAGE(NPCPlayTalkingAnimationMsg)
|
||||
ON_MESSAGE(NPCPlayIdleAnimationMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechStartedMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechEndedMsg)
|
||||
ON_MESSAGE(TurnOff)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
int CDeskbot::_v1;
|
||||
int CDeskbot::_v2;
|
||||
|
||||
CDeskbot::CDeskbot() : CTrueTalkNPC(), _deskbotActive(false),
|
||||
_classNum(NO_CLASS) {
|
||||
}
|
||||
|
||||
void CDeskbot::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_v1, indent);
|
||||
file->writeNumberLine(_v2, indent);
|
||||
file->writeNumberLine(_deskbotActive, indent);
|
||||
file->writeNumberLine(_classNum, indent);
|
||||
|
||||
CTrueTalkNPC::save(file, indent);
|
||||
}
|
||||
|
||||
void CDeskbot::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_v1 = file->readNumber();
|
||||
_v2 = file->readNumber();
|
||||
_deskbotActive = file->readNumber();
|
||||
_classNum = (PassengerClass)file->readNumber();
|
||||
|
||||
CTrueTalkNPC::load(file);
|
||||
}
|
||||
|
||||
bool CDeskbot::TurnOn(CTurnOn *msg) {
|
||||
if (!_deskbotActive) {
|
||||
setVisible(true);
|
||||
playClip("BellRinging");
|
||||
playClip("Opening", MOVIE_NOTIFY_OBJECT);
|
||||
|
||||
playSound(TRANSLATE("b#69.wav", "b#47.wav"));
|
||||
petSetArea(PET_CONVERSATION);
|
||||
|
||||
_npcFlags |= NPCFLAG_MOVE_START;
|
||||
_deskbotActive = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
setVisible(false);
|
||||
_deskbotActive = false;
|
||||
_fieldC4 = 0;
|
||||
loadFrame(625);
|
||||
|
||||
// WORKAROUND: If loading directly from the launcher when Marcinta
|
||||
// is active, reset the active NPC back to none at the same time
|
||||
CPetControl *pet = getPetControl();
|
||||
pet->resetActiveNPC();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::ActMsg(CActMsg *msg) {
|
||||
if (msg->_action == "2ndClassUpgrade" && getPassengerClass() > 2) {
|
||||
startTalking(this, 140, findView());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
bool flag = false;
|
||||
if (_npcFlags & NPCFLAG_MOVING) {
|
||||
if (_classNum) {
|
||||
petSetArea(PET_ROOMS);
|
||||
decTransitions();
|
||||
unlockMouse();
|
||||
playSound(TRANSLATE("z#47.wav", "z#578.wav"));
|
||||
_classNum = NO_CLASS;
|
||||
}
|
||||
|
||||
_npcFlags &= ~NPCFLAG_MOVING;
|
||||
}
|
||||
|
||||
if (_npcFlags & NPCFLAG_MOVE_LOOP) {
|
||||
_deskbotActive = false;
|
||||
_npcFlags &= ~(NPCFLAG_MOVE_LOOP | NPCFLAG_MOVE_START);
|
||||
|
||||
if (_npcFlags & NPCFLAG_MOVE_FINISH) {
|
||||
CTurnOn turnOn;
|
||||
turnOn.execute("EmbBellbotTrigger");
|
||||
unlockMouse();
|
||||
getGameManager()->lockInputHandler();
|
||||
changeView("EmbLobby.Node 4.N", "");
|
||||
} else if (_npcFlags & NPCFLAG_MOVE_LEFT) {
|
||||
CTurnOn turnOn;
|
||||
turnOn.execute("EmbDoorBotTrigger");
|
||||
unlockMouse();
|
||||
changeView("EmbLobby.Node 4.N", "");
|
||||
}
|
||||
|
||||
_npcFlags &= ~(NPCFLAG_MOVE_FINISH | NPCFLAG_MOVE_LEFT);
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if (_npcFlags & NPCFLAG_MOVE_START) {
|
||||
_npcFlags &= ~(NPCFLAG_MOVE_LOOP | NPCFLAG_MOVE_START);
|
||||
setTalking(this, true, findView());
|
||||
|
||||
_npcFlags |= NPCFLAG_START_IDLING;
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
CTrueTalkNPC::MovieEndMsg(msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
if (_deskbotActive) {
|
||||
CTurnOff turnOff;
|
||||
turnOff.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) {
|
||||
switch (msg->_action) {
|
||||
case 19:
|
||||
incTransitions();
|
||||
lockMouse();
|
||||
petSetArea(PET_CONVERSATION);
|
||||
playClip("ReprogramPETInHand", MOVIE_NOTIFY_OBJECT);
|
||||
_npcFlags |= NPCFLAG_MOVING;
|
||||
_classNum = (PassengerClass)msg->_param1;
|
||||
|
||||
switch (_classNum) {
|
||||
case FIRST_CLASS:
|
||||
petDisplayMessage(UPGRADED_TO_FIRST_CLASS);
|
||||
setPassengerClass(_classNum);
|
||||
petReassignRoom(_classNum);
|
||||
break;
|
||||
case SECOND_CLASS:
|
||||
petDisplayMessage(UPGRADED_TO_SECOND_CLASS);
|
||||
setPassengerClass(_classNum);
|
||||
petReassignRoom(_classNum);
|
||||
break;
|
||||
case THIRD_CLASS:
|
||||
setPassengerClass(THIRD_CLASS);
|
||||
petReassignRoom(_classNum);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 20:
|
||||
if (getPassengerClass() == 1) {
|
||||
CPetControl *petControl = getPetControl();
|
||||
if (petControl)
|
||||
petControl->changeLocationClass(UNCHECKED);
|
||||
}
|
||||
break;
|
||||
|
||||
case 21:
|
||||
if (getPassengerClass() == FIRST_CLASS) {
|
||||
CPetControl *petControl = getPetControl();
|
||||
if (petControl)
|
||||
petControl->changeLocationClass(THIRD_CLASS);
|
||||
}
|
||||
break;
|
||||
|
||||
case 22:
|
||||
if (getPassengerClass() == FIRST_CLASS) {
|
||||
CPetControl *petControl = getPetControl();
|
||||
if (petControl)
|
||||
petControl->changeLocationClass(SECOND_CLASS);
|
||||
}
|
||||
break;
|
||||
|
||||
case 23:
|
||||
if (getPassengerClass() == FIRST_CLASS) {
|
||||
CPetControl *petControl = getPetControl();
|
||||
if (petControl)
|
||||
petControl->changeLocationClass(FIRST_CLASS);
|
||||
}
|
||||
break;
|
||||
|
||||
case 26:
|
||||
{
|
||||
_npcFlags |= NPCFLAG_MOVE_FINISH;
|
||||
CTurnOff turnOff;
|
||||
turnOff.execute(this);
|
||||
lockMouse();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) {
|
||||
if (msg->_value2 != 2)
|
||||
msg->_names = TALKING_NAMES;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) {
|
||||
msg->_names = IDLE_NAMES;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg) {
|
||||
if (_npcFlags & NPCFLAG_MOVE_LOOP)
|
||||
return true;
|
||||
|
||||
CTrueTalkNPC::TrueTalkNotifySpeechStartedMsg(msg);
|
||||
|
||||
if (g_language == Common::DE_DEU) {
|
||||
switch (msg->_dialogueId) {
|
||||
case 41701:
|
||||
case 41703:
|
||||
case 41804:
|
||||
case 41805:
|
||||
case 41806:
|
||||
lockMouse();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (msg->_dialogueId) {
|
||||
case 41684:
|
||||
case 41686:
|
||||
case 41787:
|
||||
case 41788:
|
||||
case 41789:
|
||||
lockMouse();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) {
|
||||
if (_npcFlags & NPCFLAG_MOVE_LOOP)
|
||||
return true;
|
||||
|
||||
CTurnOff turnOff;
|
||||
CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(msg);
|
||||
|
||||
if (g_language == Common::DE_DEU) {
|
||||
switch (msg->_dialogueId) {
|
||||
case 41701:
|
||||
case 41804:
|
||||
case 41805:
|
||||
case 41806:
|
||||
_npcFlags |= NPCFLAG_MOVE_FINISH;
|
||||
turnOff.execute(this);
|
||||
break;
|
||||
|
||||
case 41703:
|
||||
_npcFlags |= NPCFLAG_MOVE_LEFT;
|
||||
turnOff.execute(this);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (msg->_dialogueId) {
|
||||
case 41684:
|
||||
case 41787:
|
||||
case 41788:
|
||||
case 41789:
|
||||
_npcFlags |= NPCFLAG_MOVE_FINISH;
|
||||
turnOff.execute(this);
|
||||
break;
|
||||
|
||||
case 41686:
|
||||
_npcFlags |= NPCFLAG_MOVE_LEFT;
|
||||
turnOff.execute(this);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDeskbot::TurnOff(CTurnOff *msg) {
|
||||
if (_deskbotActive) {
|
||||
stopMovie();
|
||||
performAction(1, findView());
|
||||
|
||||
_npcFlags = (_npcFlags & ~(NPCFLAG_SPEAKING | NPCFLAG_IDLING | NPCFLAG_START_IDLING)) | NPCFLAG_MOVE_LOOP;
|
||||
playClip("Closing", MOVIE_WAIT_FOR_FINISH | MOVIE_NOTIFY_OBJECT);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
65
engines/titanic/npcs/deskbot.h
Normal file
65
engines/titanic/npcs/deskbot.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_DESKBOT_H
|
||||
#define TITANIC_DESKBOT_H
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CDeskbot : public CTrueTalkNPC {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool ActMsg(CActMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg);
|
||||
bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg);
|
||||
bool NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg);
|
||||
bool TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg);
|
||||
bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg);
|
||||
bool TurnOff(CTurnOff *msg);
|
||||
private:
|
||||
static int _v1;
|
||||
static int _v2;
|
||||
public:
|
||||
bool _deskbotActive;
|
||||
PassengerClass _classNum;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CDeskbot();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_DESKBOT_H */
|
||||
609
engines/titanic/npcs/doorbot.cpp
Normal file
609
engines/titanic/npcs/doorbot.cpp
Normal file
@@ -0,0 +1,609 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/doorbot.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
#include "titanic/debugger.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDoorbot, CTrueTalkNPC)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(OnSummonBotMsg)
|
||||
ON_MESSAGE(TrueTalkTriggerActionMsg)
|
||||
ON_MESSAGE(DoorbotNeededInHomeMsg)
|
||||
ON_MESSAGE(DoorbotNeededInElevatorMsg)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(TimerMsg)
|
||||
ON_MESSAGE(NPCPlayTalkingAnimationMsg)
|
||||
ON_MESSAGE(NPCPlayIdleAnimationMsg)
|
||||
ON_MESSAGE(PutBotBackInHisBoxMsg)
|
||||
ON_MESSAGE(DismissBotMsg)
|
||||
ON_MESSAGE(MovieFrameMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechEndedMsg)
|
||||
ON_MESSAGE(TextInputMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(ActMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
int CDoorbot::_v1;
|
||||
int CDoorbot::_v2;
|
||||
|
||||
CDoorbot::CDoorbot() : CTrueTalkNPC() {
|
||||
_introMovieNum = 0;
|
||||
_timerId = 0;
|
||||
_field110 = 0;
|
||||
_field114 = 0;
|
||||
}
|
||||
|
||||
void CDoorbot::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_v1, indent);
|
||||
file->writeNumberLine(_v2, indent);
|
||||
|
||||
file->writeNumberLine(_introMovieNum, indent);
|
||||
file->writeNumberLine(_timerId, indent);
|
||||
file->writeNumberLine(_field110, indent);
|
||||
file->writeNumberLine(_field114, indent);
|
||||
|
||||
CTrueTalkNPC::save(file, indent);
|
||||
}
|
||||
|
||||
void CDoorbot::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_v1 = file->readNumber();
|
||||
_v2 = file->readNumber();
|
||||
|
||||
_introMovieNum = file->readNumber();
|
||||
_timerId = file->readNumber();
|
||||
_field110 = file->readNumber();
|
||||
_field114 = file->readNumber();
|
||||
|
||||
CTrueTalkNPC::load(file);
|
||||
}
|
||||
|
||||
bool CDoorbot::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
debugC(DEBUG_DETAILED, kDebugScripts, "CDoorbot MovieEndMsg flags=%x v=%d, start=%d, end=%d",
|
||||
_npcFlags, _introMovieNum, msg->_startFrame, msg->_endFrame);
|
||||
|
||||
if (_npcFlags & NPCFLAG_DOORBOT_INTRO) {
|
||||
switch (_introMovieNum) {
|
||||
case 3:
|
||||
startTalking(this, 221482);
|
||||
_introMovieNum = 4;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (clipExistsByEnd("Cloak On", msg->_endFrame)) {
|
||||
petShow();
|
||||
petDecAreaLocks();
|
||||
stateSetSoundMakerAllowed(true);
|
||||
changeView("ServiceElevator.Node 1.S");
|
||||
changeView("ServiceElevator.Node 1.N");
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
startTalking(this, 221467);
|
||||
_introMovieNum = 8;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
if (msg->_endFrame == 949)
|
||||
startTalking(this, 221468);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
changeView("ServiceElevator.Node 1.S");
|
||||
changeView("MoonEmbLobby.Node 1.NE");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CTrueTalkNPC::MovieEndMsg(msg);
|
||||
} else if (_npcFlags & NPCFLAG_MOVE_LEFT) {
|
||||
if (clipExistsByEnd("Cloak Off", msg->_endFrame)) {
|
||||
_npcFlags = (_npcFlags & ~NPCFLAG_DOORBOT_IN_HOME) | NPCFLAG_START_IDLING;
|
||||
setTalking(this, false);
|
||||
startTalking(this, 221474);
|
||||
_npcFlags |= NPCFLAG_DOORBOT_INTRO;
|
||||
_introMovieNum = 0;
|
||||
} else if (clipExistsByEnd("Cloak On", msg->_endFrame)) {
|
||||
petShow();
|
||||
stateSetSoundMakerAllowed(true);
|
||||
changeView("ServiceElevator.Node 1.S");
|
||||
} else {
|
||||
CTrueTalkNPC::MovieEndMsg(msg);
|
||||
}
|
||||
} else if (_npcFlags & NPCFLAG_MOVE_END) {
|
||||
if (clipExistsByEnd("Whizz On Left", msg->_endFrame)
|
||||
|| clipExistsByEnd("Whizz On Right", msg->_endFrame)) {
|
||||
setPosition(Point((600 - _bounds.width()) / 2 + 18, 42));
|
||||
loadFrame(0);
|
||||
setTalking(this, true);
|
||||
_npcFlags |= NPCFLAG_START_IDLING;
|
||||
petSetArea(PET_CONVERSATION);
|
||||
} else if (clipExistsByEnd("Whizz Off Left", msg->_endFrame)
|
||||
|| clipExistsByEnd("Whizz Off Right", msg->_endFrame)) {
|
||||
CPutBotBackInHisBoxMsg boxMsg;
|
||||
boxMsg.execute(this);
|
||||
if (_npcFlags & NPCFLAG_SUMMON_BELLBOT)
|
||||
startAnimTimer("SummonBellbot", 1500);
|
||||
} else {
|
||||
CTrueTalkNPC::MovieEndMsg(msg);
|
||||
}
|
||||
} else {
|
||||
CTrueTalkNPC::MovieEndMsg(msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::OnSummonBotMsg(COnSummonBotMsg *msg) {
|
||||
struct RoomWave {
|
||||
const char *_room;
|
||||
const char *_enSound;
|
||||
const char *_deSound;
|
||||
};
|
||||
const RoomWave ROOM_WAVES[8] = {
|
||||
{ "EmbLobby", "z#186.wav", "z#716.wav" },
|
||||
{ "PromenadeDeck", "z#184.wav", "z#714.wav" },
|
||||
{ "Arboretum", "z#188.wav", "z#718.wav" },
|
||||
{ "Frozen Arboretum", "z#188.wav", "z#718.wav" },
|
||||
{ "Bar", "z#187.wav", "z#717.wav" },
|
||||
{ "MusicRoom", "z#185.wav", "z#715.wav" },
|
||||
{ "MusicRoomLobby", "z#185.wav", "z#715.wav" },
|
||||
{ "1stClassRestaurant", "z#183.wav", "z#713.wav" },
|
||||
};
|
||||
|
||||
if (msg->_value != -1) {
|
||||
int idx;
|
||||
for (idx = 0; idx < 8; ++idx) {
|
||||
if (compareRoomNameTo(ROOM_WAVES[idx]._room)) {
|
||||
playSound(TRANSLATE(ROOM_WAVES[idx]._enSound, ROOM_WAVES[idx]._deSound));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx == 8)
|
||||
playSound(TRANSLATE("z#146.wav", "z#702.wav"));
|
||||
|
||||
sleep(2000);
|
||||
}
|
||||
|
||||
playClip(getRandomNumber(1) ? "Whizz On Left" : "Whizz On Right",
|
||||
MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
movieEvent();
|
||||
_npcFlags |= NPCFLAG_MOVE_END;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) {
|
||||
switch (msg->_action) {
|
||||
case 3:
|
||||
playClip("Cloak On", MOVIE_NOTIFY_OBJECT);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
_npcFlags = (_npcFlags & ~NPCFLAG_IDLING) | NPCFLAG_SUMMON_BELLBOT;
|
||||
playClip("Whizz Off Left", MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
break;
|
||||
|
||||
case 28: {
|
||||
_npcFlags &= ~(NPCFLAG_IDLING | NPCFLAG_START_IDLING);
|
||||
CDismissBotMsg dismissMsg;
|
||||
dismissMsg.execute(this);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::DoorbotNeededInHomeMsg(CDoorbotNeededInHomeMsg *msg) {
|
||||
moveToView();
|
||||
setPosition(Point(90, 42));
|
||||
_npcFlags = NPCFLAG_MOVE_LEFT;
|
||||
|
||||
stopMovie();
|
||||
playClip("Cloak Off", MOVIE_NOTIFY_OBJECT);
|
||||
|
||||
_npcFlags |= NPCFLAG_DOORBOT_IN_HOME;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::DoorbotNeededInElevatorMsg(CDoorbotNeededInElevatorMsg *msg) {
|
||||
moveToView("ServiceElevator.Node 1.N");
|
||||
setPosition(Point(100, 42));
|
||||
|
||||
if (_npcFlags & NPCFLAG_DOORBOT_INTRO) {
|
||||
_introMovieNum = 7;
|
||||
_npcFlags |= NPCFLAG_MOVE_RIGHT;
|
||||
loadFrame(797);
|
||||
} else {
|
||||
_npcFlags = 0;
|
||||
if (msg->_value)
|
||||
setTalking(this, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
if (!(_npcFlags & NPCFLAG_DOORBOT_INTRO) && (_npcFlags & NPCFLAG_MOVE_END)) {
|
||||
performAction(true);
|
||||
_npcFlags &= ~NPCFLAG_START_IDLING;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::TimerMsg(CTimerMsg *msg) {
|
||||
if (msg->_action == "NPCIdleAnim") {
|
||||
return CTrueTalkNPC::TimerMsg(msg);
|
||||
} else if (_npcFlags & NPCFLAG_DOORBOT_INTRO) {
|
||||
_timerId = 0;
|
||||
|
||||
switch (msg->_actionVal) {
|
||||
case 0:
|
||||
startTalking(this, 221475);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
startTalking(this, 221476);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
startTalking(this, 221477);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
playClip("DoubleTake Start");
|
||||
playClip("DoubleTake End");
|
||||
playClip("DoubleTake Start");
|
||||
playClip("DoubleTake End", MOVIE_NOTIFY_OBJECT);
|
||||
_introMovieNum = 3;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
startTalking(this, 221483);
|
||||
lockInputHandler();
|
||||
_field114 = true;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
lockInputHandler();
|
||||
mouseDisableControl();
|
||||
_field114 = true;
|
||||
startTalking(this, 221485);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// Start dragging photograph to PET
|
||||
CMouseButtonDownMsg::generate();
|
||||
mouseSetPosition(Point(200, 430), 2500);
|
||||
_timerId = addTimer(7, 2500, 0);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// Drop photograph in PET
|
||||
CMouseButtonUpMsg::generate();
|
||||
startTalking(this, 221486);
|
||||
mouseEnableControl();
|
||||
unlockInputHandler();
|
||||
_field114 = false;
|
||||
disableMouse();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (msg->_action == "SummonBellbot") {
|
||||
CRoomItem *room = getRoom();
|
||||
if (room) {
|
||||
CSummonBotMsg botMsg;
|
||||
botMsg._npcName = "Bellbot";
|
||||
botMsg.execute(room);
|
||||
}
|
||||
|
||||
_npcFlags &= ~NPCFLAG_SUMMON_BELLBOT;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) {
|
||||
static const char *const NAMES1[] = {
|
||||
"Mutter Aside", "Rub Chin", "Drunken Eye Roll", "Drunken Head Move",
|
||||
"Look down and mutter", "Look side to side", "Gesture forward and around",
|
||||
"Arms behind back", "Look down", "Rolling around", "Hold face",
|
||||
"Touch chin", "Cross hands in front", nullptr
|
||||
};
|
||||
static const char *const NAMES2[] = {
|
||||
"SE Talking 1", "SE Talking 2", "SE Talking 3", "SE Talking 4",
|
||||
nullptr
|
||||
};
|
||||
static const char *const NAMES3[] = {
|
||||
"SE Ask For Help", nullptr
|
||||
};
|
||||
|
||||
if (msg->_value2 != 2) {
|
||||
if (_npcFlags & NPCFLAG_MOVE_RIGHT) {
|
||||
switch (_introMovieNum) {
|
||||
case 8:
|
||||
case 10:
|
||||
msg->_names = NAMES2;
|
||||
break;
|
||||
case 9:
|
||||
msg->_names = NAMES3;
|
||||
_introMovieNum = 10;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (_npcFlags & (NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_END)) {
|
||||
msg->_names = NAMES1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) {
|
||||
static const char *const NAMES[] = {
|
||||
"Hand swivel", "Prompt Push", "Eye Roll", "Say something", nullptr
|
||||
};
|
||||
|
||||
if (!(_npcFlags & (NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT))
|
||||
&& (_npcFlags & NPCFLAG_MOVE_END))
|
||||
msg->_names = NAMES;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::PutBotBackInHisBoxMsg(CPutBotBackInHisBoxMsg *msg) {
|
||||
petMoveToHiddenRoom();
|
||||
_npcFlags &= ~(NPCFLAG_START_IDLING | NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT | NPCFLAG_DOORBOT_INTRO);
|
||||
if (msg->_value)
|
||||
performAction(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::DismissBotMsg(CDismissBotMsg *msg) {
|
||||
if (_npcFlags & NPCFLAG_MOVE_END) {
|
||||
playClip(getRandomNumber(1) ? "Whizz Off Left" : "Whizz Off Right",
|
||||
MOVIE_STOP_PREVIOUS | MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
movieEvent();
|
||||
|
||||
if (_npcFlags & NPCFLAG_START_IDLING) {
|
||||
_npcFlags &= ~NPCFLAG_START_IDLING;
|
||||
performAction(true);
|
||||
} else {
|
||||
performAction(false);
|
||||
}
|
||||
|
||||
CActMsg actMsg("DoorbotDismissed");
|
||||
actMsg.execute("BotIdleSummons");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::MovieFrameMsg(CMovieFrameMsg *msg) {
|
||||
if (clipExistsByStart("Whizz Off Left", msg->_frameNumber)
|
||||
|| clipExistsByStart("Whizz On Left", msg->_frameNumber)) {
|
||||
setPosition(Point(20, 42));
|
||||
} else if (clipExistsByStart("Whizz Off Right", msg->_frameNumber)
|
||||
|| clipExistsByStart("Whizz On Right", msg->_frameNumber)) {
|
||||
setPosition(Point(620 - _bounds.width(), 42));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) {
|
||||
CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(msg);
|
||||
|
||||
if (_npcFlags & NPCFLAG_DOORBOT_INTRO) {
|
||||
// Initial speech by Doorbot in
|
||||
switch (msg->_dialogueId - TRANSLATE(10552, 10563)) {
|
||||
case 0:
|
||||
playClip("SE Try Buttons", MOVIE_NOTIFY_OBJECT);
|
||||
_introMovieNum = 9;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
enableMouse();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
playClip("SE Move To Right", MOVIE_NOTIFY_OBJECT);
|
||||
_introMovieNum = 11;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = addTimer(0, 2500, 0);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
petShow();
|
||||
petSetArea(PET_CONVERSATION);
|
||||
petIncAreaLocks();
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = addTimer(1, 1000, 0);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
enableMouse();
|
||||
_introMovieNum = 1;
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = addTimer(2, 10000, 0);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
if (_introMovieNum == 1) {
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = addTimer(2, getRandomNumber(5000) + 5000, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
case 12:
|
||||
disableMouse();
|
||||
startTalking(this, 221480);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
startTalking(this, 221481);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = 0;
|
||||
if (_field110 == 2) {
|
||||
playClip("Cloak On", MOVIE_NOTIFY_OBJECT);
|
||||
_introMovieNum = 6;
|
||||
} else {
|
||||
_timerId = addTimer(3, 2000, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 15: {
|
||||
CActMsg actMsg("BecomeGettable");
|
||||
actMsg.execute("Photograph");
|
||||
enableMouse();
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = addTimer(4, 5000, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case 16:
|
||||
// Start moving cursor to photograph
|
||||
mouseDisableControl();
|
||||
mouseSetPosition(Point(600, 250), 2500);
|
||||
_timerId = addTimer(6, 2500, 0);
|
||||
break;
|
||||
|
||||
case 17:
|
||||
if (_field110 != 2) {
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = addTimer(5, 3000, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 18:
|
||||
mouseSetPosition(Point(200, 430), 2500);
|
||||
_timerId = addTimer(7, 3000, 0);
|
||||
break;
|
||||
|
||||
case 19:
|
||||
playClip("Cloak On", MOVIE_NOTIFY_OBJECT);
|
||||
_introMovieNum = 6;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::TextInputMsg(CTextInputMsg *msg) {
|
||||
if (!(_npcFlags & NPCFLAG_DOORBOT_INTRO))
|
||||
return CTrueTalkNPC::TextInputMsg(msg);
|
||||
|
||||
if (_introMovieNum == 1) {
|
||||
stopAnimTimer(_timerId);
|
||||
_introMovieNum = 2;
|
||||
_timerId = 0;
|
||||
|
||||
if (msg->_input == "yes" || msg->_input == "yeah"
|
||||
|| msg->_input == "yea" || msg->_input == "yup"
|
||||
|| msg->_input == "yep" || msg->_input == "sure"
|
||||
|| msg->_input == "alright" || msg->_input == "all right"
|
||||
|| msg->_input == "ok") {
|
||||
startTalking(this, 221479);
|
||||
} else {
|
||||
startTalking(this, 221478);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
if ((_npcFlags & NPCFLAG_DOORBOT_INTRO) && _introMovieNum == 7)
|
||||
playClip("SE Move And Turn", MOVIE_NOTIFY_OBJECT);
|
||||
else if (!compareRoomNameTo("ServiceElevator") && msg->_newView == getParent() && getPetControl()->canSummonBot("DoorBot")) {
|
||||
// WORKAROUND: Calling bot in front of doors and then going through them
|
||||
// can leave it in the view. Detect this and properly remove him when
|
||||
// the player returns to that view
|
||||
petMoveToHiddenRoom();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDoorbot::ActMsg(CActMsg *msg) {
|
||||
debugC(DEBUG_DETAILED, kDebugScripts, "CDoorbot ActMsg action=%s v108=%d v110=%d v114=%d",
|
||||
msg->_action.c_str(), _introMovieNum, _field110, _field114);
|
||||
|
||||
if (msg->_action == "DoorbotPlayerPressedTopButton") {
|
||||
disableMouse();
|
||||
startTalking(this, 221471);
|
||||
} else if (msg->_action == "DoorbotPlayerPressedMiddleButton") {
|
||||
startTalking(this, 221470);
|
||||
} else if (msg->_action == "DoorbotPlayerPressedBottomButton") {
|
||||
startTalking(this, 221469);
|
||||
} else if (msg->_action == "DoorbotReachedEmbLobby") {
|
||||
startTalking(this, 221472);
|
||||
} else if (msg->_action == "PlayerPicksUpPhoto") {
|
||||
_field110 = 1;
|
||||
if (!_field114 && _introMovieNum == 4) {
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = 0;
|
||||
_introMovieNum = 5;
|
||||
startTalking(this, 221484);
|
||||
}
|
||||
} else if (msg->_action == "PlayerPutsPhotoInPet") {
|
||||
_field110 = 2;
|
||||
if (!_field114 && _introMovieNum == 5) {
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = 0;
|
||||
startTalking(this, 221486);
|
||||
disableMouse();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
72
engines/titanic/npcs/doorbot.h
Normal file
72
engines/titanic/npcs/doorbot.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_DOORBOT_H
|
||||
#define TITANIC_DOORBOT_H
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CDoorbot : public CTrueTalkNPC {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool OnSummonBotMsg(COnSummonBotMsg *msg);
|
||||
bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg);
|
||||
bool DoorbotNeededInHomeMsg(CDoorbotNeededInHomeMsg *msg);
|
||||
bool DoorbotNeededInElevatorMsg(CDoorbotNeededInElevatorMsg *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool TimerMsg(CTimerMsg *msg);
|
||||
bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg);
|
||||
bool NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg);
|
||||
bool PutBotBackInHisBoxMsg(CPutBotBackInHisBoxMsg *msg);
|
||||
bool DismissBotMsg(CDismissBotMsg *msg);
|
||||
bool MovieFrameMsg(CMovieFrameMsg *msg);
|
||||
bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg);
|
||||
bool TextInputMsg(CTextInputMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool ActMsg(CActMsg *msg);
|
||||
private:
|
||||
static int _v1;
|
||||
static int _v2;
|
||||
private:
|
||||
int _introMovieNum;
|
||||
int _timerId;
|
||||
int _field110;
|
||||
int _field114;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CDoorbot();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_DOORBOT_H */
|
||||
185
engines/titanic/npcs/liftbot.cpp
Normal file
185
engines/titanic/npcs/liftbot.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/liftbot.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CLiftBot, CTrueTalkNPC)
|
||||
ON_MESSAGE(TextInputMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(EnterRoomMsg)
|
||||
ON_MESSAGE(TrueTalkTriggerActionMsg)
|
||||
ON_MESSAGE(LeaveRoomMsg)
|
||||
ON_MESSAGE(TurnOff)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(TrueTalkGetStateValueMsg)
|
||||
ON_MESSAGE(NPCPlayTalkingAnimationMsg)
|
||||
ON_MESSAGE(ActMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
bool CLiftBot::_flag;
|
||||
bool CLiftBot::_enabled;
|
||||
|
||||
CLiftBot::CLiftBot() : CTrueTalkNPC(), _field108(1) {
|
||||
}
|
||||
|
||||
void CLiftBot::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_flag, indent);
|
||||
file->writeNumberLine(_field108, indent);
|
||||
file->writeNumberLine(_enabled, indent);
|
||||
|
||||
CTrueTalkNPC::save(file, indent);
|
||||
}
|
||||
|
||||
void CLiftBot::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_flag = file->readNumber();
|
||||
_field108 = file->readNumber();
|
||||
_enabled = file->readNumber();
|
||||
|
||||
CTrueTalkNPC::load(file);
|
||||
}
|
||||
|
||||
bool CLiftBot::TextInputMsg(CTextInputMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
if (_enabled || pet->getRoomsElevatorNum() != 4) {
|
||||
if (getName() == "LiftBot") {
|
||||
CViewItem *view = findView();
|
||||
processInput(msg, view);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
if (!_enabled && pet->getRoomsElevatorNum() == 4) {
|
||||
loadFrame(700);
|
||||
} else if (!_flag && getName() == "LiftBot") {
|
||||
// First time meeting the LiftBot
|
||||
CViewItem *view = findView();
|
||||
setTalking(this, true, view);
|
||||
petSetArea(PET_CONVERSATION);
|
||||
_flag = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::EnterRoomMsg(CEnterRoomMsg *msg) {
|
||||
_flag = 0;
|
||||
changeView("Lift.Node 1.W", "");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) {
|
||||
if (msg->_action == 2 && msg->_param1 != _field108) {
|
||||
CStatusChangeMsg statusMsg(_field108, msg->_param1, false);
|
||||
statusMsg.execute("Well");
|
||||
|
||||
_field108 = msg->_param1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::LeaveRoomMsg(CLeaveRoomMsg *msg) {
|
||||
if (getName() == "LiftBot")
|
||||
performAction(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::TurnOff(CTurnOff *msg) {
|
||||
_enabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::TurnOn(CTurnOn *msg) {
|
||||
_enabled = true;
|
||||
if (!_flag) {
|
||||
if (isEquals("LiftBotTalking")) {
|
||||
setTalking(this, MOVIE_REPEAT, findView());
|
||||
petSetArea(PET_CONVERSATION);
|
||||
_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg) {
|
||||
if (msg->_stateNum == 4) {
|
||||
CPetControl *pet = getPetControl();
|
||||
if (pet)
|
||||
msg->_stateVal = pet->getAssignedFloorNum();
|
||||
} else if (msg->_stateNum == 5) {
|
||||
msg->_stateVal = _field108;
|
||||
} else if (msg->_stateNum == 6) {
|
||||
CPetControl *pet = getPetControl();
|
||||
if (pet)
|
||||
msg->_stateVal = pet->getRoomsElevatorNum();
|
||||
} else {
|
||||
msg->_stateVal = _field108;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) {
|
||||
static const char *const NAMES[] = {
|
||||
"Groaning", "Groaning 2", "Talking 1", "Talking 2", "Talking 3",
|
||||
"Happy Talking", "Complaining", "Aggressive", "Explaining",
|
||||
"Happy Talking 2", "Happy Talking 3", "Happy Talking 4",
|
||||
"Confidential", nullptr
|
||||
};
|
||||
|
||||
if (msg->_value2 == 2)
|
||||
playClip("At Rest");
|
||||
else
|
||||
msg->_names = NAMES;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLiftBot::ActMsg(CActMsg *msg) {
|
||||
if (msg->_action == "ActivateLift") {
|
||||
_enabled = true;
|
||||
CViewItem *view = findView();
|
||||
setTalking(this, true, view);
|
||||
startTalking(this, 155, view);
|
||||
} else if (msg->_action == "LiftArrive") {
|
||||
CViewItem *view = findView();
|
||||
startTalking(this, 156, view);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
65
engines/titanic/npcs/liftbot.h
Normal file
65
engines/titanic/npcs/liftbot.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_LIFTBOT_H
|
||||
#define TITANIC_LIFTBOT_H
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CLiftBot : public CTrueTalkNPC {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TextInputMsg(CTextInputMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool EnterRoomMsg(CEnterRoomMsg *msg);
|
||||
bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg);
|
||||
bool LeaveRoomMsg(CLeaveRoomMsg *msg);
|
||||
bool TurnOff(CTurnOff *msg);
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg);
|
||||
bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg);
|
||||
bool ActMsg(CActMsg *msg);
|
||||
private:
|
||||
static bool _flag;
|
||||
static bool _enabled;
|
||||
private:
|
||||
int _field108;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CLiftBot();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_LIFTBOT_H */
|
||||
228
engines/titanic/npcs/maitre_d.cpp
Normal file
228
engines/titanic/npcs/maitre_d.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/maitre_d.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
#include "titanic/sound/music_room.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CMaitreD, CTrueTalkNPC)
|
||||
ON_MESSAGE(RestaurantMusicChanged)
|
||||
ON_MESSAGE(TrueTalkTriggerActionMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(NPCPlayTalkingAnimationMsg)
|
||||
ON_MESSAGE(TimerMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechStartedMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechEndedMsg)
|
||||
ON_MESSAGE(LoadSuccessMsg)
|
||||
ON_MESSAGE(TextInputMsg)
|
||||
ON_MESSAGE(TriggerNPCEvent)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CMaitreD::CMaitreD() : CTrueTalkNPC(),
|
||||
_priorMusicName("z#40.wav"), _musicName("z#40.wav"), _unused5(0), _hasMusic(true),
|
||||
_musicSet(false), _fightFlag(false), _unused6(true), _savedFightFlag(false),
|
||||
_timerId(0), _defeated(false) {
|
||||
}
|
||||
|
||||
void CMaitreD::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_unused5, indent);
|
||||
file->writeQuotedLine(_priorMusicName, indent);
|
||||
file->writeNumberLine(_hasMusic, indent);
|
||||
file->writeNumberLine(_musicSet, indent);
|
||||
file->writeQuotedLine(_musicName, indent);
|
||||
file->writeNumberLine(_fightFlag, indent);
|
||||
file->writeNumberLine(_unused6, indent);
|
||||
|
||||
file->writeNumberLine(_defeated, indent);
|
||||
file->writeNumberLine(_savedFightFlag, indent);
|
||||
file->writeNumberLine(_timerId, indent);
|
||||
|
||||
CTrueTalkNPC::save(file, indent);
|
||||
}
|
||||
|
||||
void CMaitreD::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_unused5 = file->readNumber();
|
||||
_priorMusicName = file->readString();
|
||||
_hasMusic = file->readNumber();
|
||||
_musicSet = file->readNumber();
|
||||
_musicName = file->readString();
|
||||
_fightFlag = file->readNumber();
|
||||
_unused6 = file->readNumber();
|
||||
|
||||
_defeated = file->readNumber();
|
||||
_savedFightFlag = file->readNumber();
|
||||
_timerId = file->readNumber();
|
||||
|
||||
CTrueTalkNPC::load(file);
|
||||
|
||||
// WORKAROUND: The back view of the MaitreD from close to the table is dodgy
|
||||
// in the original. And unneeded anyway, since he's also part of the background
|
||||
if (_name == "MaitreLoop03")
|
||||
_visible = false;
|
||||
}
|
||||
|
||||
bool CMaitreD::RestaurantMusicChanged(CRestaurantMusicChanged *msg) {
|
||||
if (msg->_value.empty()) {
|
||||
_hasMusic = false;
|
||||
} else {
|
||||
_musicName = msg->_value;
|
||||
_hasMusic = _musicSet = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) {
|
||||
if (msg->_action == 8) {
|
||||
_fightFlag = true;
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = startAnimTimer("MD Fight", 3500, 0);
|
||||
} else if (msg->_action == 9) {
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = 0;
|
||||
} else if (msg->_action == 10) {
|
||||
_fightFlag = false;
|
||||
_defeated = true;
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = 0;
|
||||
|
||||
CMaitreDDefeatedMsg defeatedMsg;
|
||||
defeatedMsg.execute(findRoom());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
setTalking(this, true, findView());
|
||||
_fightFlag = _savedFightFlag;
|
||||
|
||||
if (_musicName != "STMusic" && (!_musicSet || _priorMusicName == _musicName))
|
||||
return true;
|
||||
|
||||
// WORKAROUND: It's possible in the original to not have a music handler set
|
||||
// if you start and stop the phonograph, then save and restore the game
|
||||
if (!CMusicRoom::_musicHandler)
|
||||
return true;
|
||||
|
||||
if (_musicName.contains("nasty ambient"))
|
||||
startTalking(this, 111, findView());
|
||||
else if (!CMusicRoom::_musicHandler->checkInstrument(SNAKE))
|
||||
startTalking(this, 114, findView());
|
||||
else if (!CMusicRoom::_musicHandler->checkInstrument(BASS))
|
||||
startTalking(this, 113, findView());
|
||||
else if (!CMusicRoom::_musicHandler->checkInstrument(PIANO))
|
||||
startTalking(this, 115, findView());
|
||||
else {
|
||||
startTalking(this, 110, findView());
|
||||
CMaitreDHappyMsg happyMsg;
|
||||
happyMsg.execute("MaitreD Left Arm");
|
||||
happyMsg.execute("MaitreD Right Arm");
|
||||
}
|
||||
|
||||
_priorMusicName = _musicName;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
_savedFightFlag = _fightFlag;
|
||||
performAction(true);
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = 0;
|
||||
|
||||
_fightFlag = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) {
|
||||
static const char *const NAMES[] = {
|
||||
"Talking0", "Talking1", "Talking2", "Talking3", "Talking4",
|
||||
"Talking5", "Talking6", "Talking7", nullptr
|
||||
};
|
||||
|
||||
if (msg->_value2 != 2) {
|
||||
msg->_names = NAMES;
|
||||
|
||||
CAnimateMaitreDMsg animMsg;
|
||||
if (_fightFlag)
|
||||
animMsg._value = 0;
|
||||
animMsg.execute(this, nullptr, MSGFLAG_SCAN);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::TimerMsg(CTimerMsg *msg) {
|
||||
if (msg->_action == "MD Fight") {
|
||||
if (_fightFlag && compareViewNameTo("1stClassRestaurant.MaitreD Node.N")) {
|
||||
startTalking(this, 131, findView());
|
||||
}
|
||||
} else {
|
||||
CTrueTalkNPC::TimerMsg(msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg) {
|
||||
if (_fightFlag) {
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = 0;
|
||||
}
|
||||
|
||||
CTrueTalkNPC::TrueTalkNotifySpeechStartedMsg(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) {
|
||||
if (_fightFlag) {
|
||||
stopAnimTimer(_timerId);
|
||||
_timerId = startAnimTimer("MD Fight", 3000 + getRandomNumber(3000));
|
||||
}
|
||||
|
||||
CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::LoadSuccessMsg(CLoadSuccessMsg *msg) {
|
||||
if (_fightFlag) {
|
||||
_timerId = startAnimTimer("MD Fight", 3000 + getRandomNumber(3000));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::TextInputMsg(CTextInputMsg *msg) {
|
||||
CTrueTalkNPC::processInput(msg, findView());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMaitreD::TriggerNPCEvent(CTriggerNPCEvent *msg) {
|
||||
startTalking(this, msg->_value, findView());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
70
engines/titanic/npcs/maitre_d.h
Normal file
70
engines/titanic/npcs/maitre_d.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_MAITRED_H
|
||||
#define TITANIC_MAITRED_H
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CMaitreD : public CTrueTalkNPC {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool RestaurantMusicChanged(CRestaurantMusicChanged *msg);
|
||||
bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg);
|
||||
bool TimerMsg(CTimerMsg *msg);
|
||||
bool TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg);
|
||||
bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg);
|
||||
bool LoadSuccessMsg(CLoadSuccessMsg *msg);
|
||||
bool TextInputMsg(CTextInputMsg *msg);
|
||||
bool TriggerNPCEvent(CTriggerNPCEvent *msg);
|
||||
private:
|
||||
int _unused5;
|
||||
CString _priorMusicName;
|
||||
bool _hasMusic;
|
||||
bool _musicSet;
|
||||
CString _musicName;
|
||||
bool _fightFlag;
|
||||
bool _unused6;
|
||||
bool _savedFightFlag;
|
||||
int _timerId;
|
||||
bool _defeated;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CMaitreD();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MAITRED_H */
|
||||
47
engines/titanic/npcs/mobile.cpp
Normal file
47
engines/titanic/npcs/mobile.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/mobile.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
EMPTY_MESSAGE_MAP(CMobile, CCharacter);
|
||||
|
||||
CMobile::CMobile() : CCharacter(), _fieldDC(0) {
|
||||
}
|
||||
|
||||
void CMobile::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writePoint(_pos1, indent);
|
||||
file->writeNumberLine(_fieldDC, indent);
|
||||
|
||||
CCharacter::save(file, indent);
|
||||
}
|
||||
|
||||
void CMobile::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_pos1 = file->readPoint();
|
||||
_fieldDC = file->readNumber();
|
||||
|
||||
CCharacter::load(file);
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
51
engines/titanic/npcs/mobile.h
Normal file
51
engines/titanic/npcs/mobile.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_MOBILE_H
|
||||
#define TITANIC_MOBILE_H
|
||||
|
||||
#include "titanic/npcs/character.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CMobile : public CCharacter {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
protected:
|
||||
Point _pos1;
|
||||
int _fieldDC;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CMobile();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MOBILE_H */
|
||||
759
engines/titanic/npcs/parrot.cpp
Normal file
759
engines/titanic/npcs/parrot.cpp
Normal file
@@ -0,0 +1,759 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/parrot.h"
|
||||
#include "titanic/core/project_item.h"
|
||||
#include "titanic/carry/carry.h"
|
||||
#include "titanic/carry/chicken.h"
|
||||
#include "titanic/game_manager.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CParrot, CTrueTalkNPC)
|
||||
ON_MESSAGE(ActMsg)
|
||||
ON_MESSAGE(MouseButtonDownMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(TrueTalkTriggerActionMsg)
|
||||
ON_MESSAGE(MouseDragStartMsg)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(ParrotSpeakMsg)
|
||||
ON_MESSAGE(NPCPlayTalkingAnimationMsg)
|
||||
ON_MESSAGE(NPCPlayIdleAnimationMsg)
|
||||
ON_MESSAGE(FrameMsg)
|
||||
ON_MESSAGE(MovieFrameMsg)
|
||||
ON_MESSAGE(PutParrotBackMsg)
|
||||
ON_MESSAGE(PreEnterViewMsg)
|
||||
ON_MESSAGE(PanningAwayFromParrotMsg)
|
||||
ON_MESSAGE(LeaveRoomMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechStartedMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechEndedMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
bool CParrot::_eatingChicken;
|
||||
bool CParrot::_takeOff;
|
||||
bool CParrot::_unused;
|
||||
ParrotState CParrot::_state;
|
||||
bool CParrot::_coreReplaced;
|
||||
|
||||
CParrot::CParrot() : CTrueTalkNPC() {
|
||||
_unused1 = 0;
|
||||
_carryParrot = "CarryParrot";
|
||||
_canDrag = true;
|
||||
_unused2 = 25;
|
||||
_lastSpeakTime = 0;
|
||||
_newXp = 73;
|
||||
_newXc = 58;
|
||||
_triedEatChicken = false;
|
||||
_eatOffsetX = 0;
|
||||
_panTarget = nullptr;
|
||||
|
||||
_assetName = "z454.dlg";
|
||||
_assetNumber = 0x13880;
|
||||
}
|
||||
|
||||
void CParrot::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_assetNumber, indent);
|
||||
|
||||
file->writeQuotedLine(_assetName, indent);
|
||||
file->writeNumberLine(_unused1, indent);
|
||||
file->writeNumberLine(_eatingChicken, indent);
|
||||
file->writeNumberLine(_takeOff, indent);
|
||||
file->writeNumberLine(_unused, indent);
|
||||
|
||||
file->writeQuotedLine(_carryParrot, indent);
|
||||
file->writeNumberLine(_canDrag, indent);
|
||||
file->writeNumberLine(_unused2, indent);
|
||||
file->writeNumberLine(_lastSpeakTime, indent);
|
||||
file->writeNumberLine(_newXp, indent);
|
||||
file->writeNumberLine(_newXc, indent);
|
||||
file->writeNumberLine(_triedEatChicken, indent);
|
||||
file->writeNumberLine(_eatOffsetX, indent);
|
||||
file->writeNumberLine(_state, indent);
|
||||
file->writeNumberLine(_coreReplaced, indent);
|
||||
|
||||
CTrueTalkNPC::save(file, indent);
|
||||
}
|
||||
|
||||
void CParrot::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_assetNumber = file->readNumber();
|
||||
|
||||
_assetName = file->readString();
|
||||
_unused1 = file->readNumber();
|
||||
_eatingChicken = file->readNumber();
|
||||
_takeOff = file->readNumber();
|
||||
_unused = file->readNumber();
|
||||
|
||||
_carryParrot = file->readString();
|
||||
_canDrag = file->readNumber();
|
||||
_unused2 = file->readNumber();
|
||||
_lastSpeakTime = file->readNumber();
|
||||
_newXp = file->readNumber();
|
||||
_newXc = file->readNumber();
|
||||
_triedEatChicken = file->readNumber();
|
||||
_eatOffsetX = file->readNumber();
|
||||
_state = (ParrotState)file->readNumber();
|
||||
_coreReplaced = file->readNumber();
|
||||
|
||||
CTrueTalkNPC::load(file);
|
||||
}
|
||||
|
||||
bool CParrot::ActMsg(CActMsg *msg) {
|
||||
if (msg->_action == "Chicken") {
|
||||
// Nothing to do
|
||||
} else if (msg->_action == "CarryParrotLeftView") {
|
||||
if (!_takeOff)
|
||||
setEatingChicken(false);
|
||||
} else if (msg->_action == "StartChickenDrag") {
|
||||
if (_state == PARROT_IN_CAGE) {
|
||||
stopMovie();
|
||||
startTalking(this, 280275, findView());
|
||||
_triedEatChicken = false;
|
||||
}
|
||||
} else if (msg->_action == "EnteringFromTOW" &&
|
||||
(_state == PARROT_IN_CAGE || _state == PARROT_ESCAPED)) {
|
||||
if (_takeOff) {
|
||||
_state = PARROT_ESCAPED;
|
||||
} else {
|
||||
setVisible(true);
|
||||
CTreeItem *cageBar = getRoot()->findByName("CageBar");
|
||||
detach();
|
||||
attach(cageBar);
|
||||
|
||||
_state = PARROT_IN_CAGE;
|
||||
CActMsg actMsg1("OpenNow");
|
||||
actMsg1.execute("ParrotCage");
|
||||
CActMsg actMsg2("GainParrot");
|
||||
actMsg2.execute("ParrotLobbyController");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
|
||||
if (!(_npcFlags & NPCFLAG_TAKE_OFF) && _speechCounter == 0) {
|
||||
CTrueTalkTriggerActionMsg triggerMsg(280250, 280250, 1);
|
||||
triggerMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
if ((_npcFlags & NPCFLAG_TAKE_OFF) && clipExistsByEnd("Take Off", msg->_endFrame)) {
|
||||
setVisible(false);
|
||||
moveUnder(findRoom());
|
||||
stopMovie();
|
||||
|
||||
CActMsg actMsg1("LoseParrot");
|
||||
actMsg1.execute("ParrotLobbyController");
|
||||
|
||||
if (_panTarget) {
|
||||
CActMsg actMsg2("PanAwayFromParrot");
|
||||
actMsg2.execute(_panTarget);
|
||||
_panTarget = nullptr;
|
||||
} else {
|
||||
CActMsg actMsg2("Shut");
|
||||
actMsg2.execute("ParrotCage");
|
||||
}
|
||||
|
||||
_npcFlags &= ~NPCFLAG_TAKE_OFF;
|
||||
_state = PARROT_ESCAPED;
|
||||
} else if (_npcFlags & NPCFLAG_MOVING) {
|
||||
if (_npcFlags & NPCFLAG_MOVE_START) {
|
||||
// Parrot is about to loop
|
||||
_npcFlags = (_npcFlags & ~NPCFLAG_MOVE_START) | NPCFLAG_MOVE_LOOP;
|
||||
if (_npcFlags & NPCFLAG_MOVE_LEFT) {
|
||||
playClip("Walk Left Loop", MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent(236);
|
||||
} else {
|
||||
playClip("Walk Right Loop", MOVIE_NOTIFY_OBJECT);
|
||||
}
|
||||
} else if (_npcFlags & NPCFLAG_MOVE_LOOP) {
|
||||
// In progress movement loop
|
||||
int xp = _bounds.left + _bounds.width() / 2;
|
||||
|
||||
if (_npcFlags & NPCFLAG_MOVE_LEFT) {
|
||||
if ((xp - _newXc) > 32) {
|
||||
setPosition(Point(_bounds.left - 40, _bounds.top));
|
||||
playClip("Walk Left Loop", MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent(236);
|
||||
} else {
|
||||
setPosition(Point(_bounds.left - 10, _bounds.top));
|
||||
playClip("Walk Left Outro", MOVIE_NOTIFY_OBJECT);
|
||||
_npcFlags = (_npcFlags & ~NPCFLAG_MOVE_LOOP) | NPCFLAG_MOVE_FINISH;
|
||||
}
|
||||
} else {
|
||||
if ((_newXc - xp) > 32) {
|
||||
playClip("Walk Right Loop", MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent(244);
|
||||
} else {
|
||||
playClip("Walk Right Outro", MOVIE_NOTIFY_OBJECT);
|
||||
_npcFlags = (_npcFlags & ~NPCFLAG_MOVE_LOOP) | NPCFLAG_MOVE_FINISH;
|
||||
}
|
||||
}
|
||||
} else if (_npcFlags & NPCFLAG_MOVE_FINISH) {
|
||||
// Finishing movement
|
||||
loadFrame(0);
|
||||
if (_npcFlags & NPCFLAG_MOVE_LEFT)
|
||||
setPosition(Point(_bounds.left - 30, _bounds.top));
|
||||
else
|
||||
setPosition(Point(_bounds.left + 14, _bounds.top));
|
||||
|
||||
_npcFlags &= ~(NPCFLAG_MOVING | NPCFLAG_MOVE_FINISH | NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT);
|
||||
CTrueTalkNPC::MovieEndMsg(msg);
|
||||
}
|
||||
} else if (_npcFlags & NPCFLAG_CHICKEN_OUTSIDE_CAGE) {
|
||||
Point pt = getMousePos();
|
||||
if (pt.x > 70 || pt.y < 90 || pt.y > 280) {
|
||||
stopMovie();
|
||||
loadFrame(0);
|
||||
_npcFlags &= ~NPCFLAG_CHICKEN_OUTSIDE_CAGE;
|
||||
}
|
||||
|
||||
if (clipExistsByEnd("Walk Left Loop", msg->_endFrame)) {
|
||||
playClip("Lean Over To Chicken", MOVIE_NOTIFY_OBJECT);
|
||||
setPosition(Point(_bounds.left - 55, _bounds.top));
|
||||
_eatOffsetX = (-100 - _bounds.left) / 5;
|
||||
movieEvent(261);
|
||||
movieEvent(262);
|
||||
movieEvent(265);
|
||||
movieEvent(268);
|
||||
movieEvent(271);
|
||||
return true;
|
||||
|
||||
} else if (clipExistsByEnd("Lean Over To Chicken", msg->_endFrame)) {
|
||||
// WORKAROUND: Do what the original obviously intended but got
|
||||
// wrong.. only flag chicken as eaten if it's still being dragged
|
||||
CTreeItem *dragItem = getGameManager()->_dragItem;
|
||||
CCarry *chicken = dynamic_cast<CCarry *>(dragItem);
|
||||
|
||||
if (chicken)
|
||||
playClip("Eat Chicken");
|
||||
playClip("Eat Chicken 2", MOVIE_NOTIFY_OBJECT);
|
||||
|
||||
if (chicken) {
|
||||
setEatingChicken(true);
|
||||
|
||||
CTrueTalkTriggerActionMsg actionMsg;
|
||||
actionMsg._action = 280266;
|
||||
actionMsg._param2 = 1;
|
||||
actionMsg.execute(this);
|
||||
|
||||
CActMsg actMsg("Eaten");
|
||||
actMsg.execute(chicken);
|
||||
}
|
||||
|
||||
_npcFlags &= ~NPCFLAG_CHICKEN_OUTSIDE_CAGE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (clipExistsByEnd("Eat Chicken 2", msg->_endFrame)) {
|
||||
// Parrot has finished eating Chicken
|
||||
setEatingChicken(false);
|
||||
|
||||
if (_takeOff) {
|
||||
// Perch has been taken, so take off
|
||||
loadMovie(TRANSLATE("z168.avi", "z191.avi"), false);
|
||||
playClip("Take Off", MOVIE_NOTIFY_OBJECT);
|
||||
setPosition(Point(20, 10));
|
||||
_npcFlags |= NPCFLAG_TAKE_OFF;
|
||||
} else {
|
||||
// Resetting back to standing
|
||||
_npcFlags &= ~(NPCFLAG_MOVING | NPCFLAG_MOVE_START | NPCFLAG_MOVE_LOOP
|
||||
| NPCFLAG_MOVE_FINISH | NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT);
|
||||
_npcFlags |= NPCFLAG_MOVE_END;
|
||||
stopMovie();
|
||||
loadFrame(0);
|
||||
setPosition(Point(-90, _bounds.top));
|
||||
}
|
||||
} else {
|
||||
return CTrueTalkNPC::MovieEndMsg(msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
static const char *const NAMES[] = {
|
||||
"Talking0", "Talking1", "Talking2", "Talking3", "Talking4",
|
||||
"Talking5", "Talking6", "Talking7", nullptr
|
||||
};
|
||||
|
||||
if (_state == PARROT_IN_CAGE) {
|
||||
setPosition(Point(_newXp, _bounds.top));
|
||||
_canDrag = true;
|
||||
_npcFlags &= ~(NPCFLAG_MOVING | NPCFLAG_MOVE_START | NPCFLAG_MOVE_LOOP
|
||||
| NPCFLAG_MOVE_FINISH | NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT | NPCFLAG_MOVE_END);
|
||||
loadFrame(0);
|
||||
setTalking(this, true, findView());
|
||||
|
||||
if (_speechCounter > 0) {
|
||||
playRandomClip(NAMES, MOVIE_NOTIFY_OBJECT);
|
||||
} else {
|
||||
startTalking(this, 280258, findView());
|
||||
}
|
||||
|
||||
petSetArea(PET_CONVERSATION);
|
||||
_triedEatChicken = false;
|
||||
_npcFlags |= NPCFLAG_START_IDLING;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) {
|
||||
if (_state != PARROT_MAILED) {
|
||||
CViewItem *view = msg->_param2 ? findView() : nullptr;
|
||||
startTalking(this, msg->_action, view);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::MouseDragStartMsg(CMouseDragStartMsg *msg) {
|
||||
if (_canDrag && _state == PARROT_IN_CAGE && checkPoint(msg->_mousePos, false, true)) {
|
||||
setVisible(false);
|
||||
CRoomItem *room = findRoom();
|
||||
|
||||
moveUnder(room);
|
||||
startTalking(this, 280129);
|
||||
performAction(true);
|
||||
|
||||
CCarry *item = dynamic_cast<CCarry *>(getRoot()->findByName(_carryParrot));
|
||||
if (item) {
|
||||
item->_canTake = true;
|
||||
CPassOnDragStartMsg passMsg;
|
||||
passMsg._mousePos = msg->_mousePos;
|
||||
passMsg.execute(item);
|
||||
msg->_dragItem = item;
|
||||
|
||||
CActMsg actMsg("LoseParrot");
|
||||
actMsg.execute("ParrotLobbyController");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CParrot::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
performAction(true);
|
||||
_npcFlags &= ~NPCFLAG_START_IDLING;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::ParrotSpeakMsg(CParrotSpeakMsg *msg) {
|
||||
static const char *const ROOM_NAMES[] = {
|
||||
"SGTState", "SGTLittleLift", "SecClassLittleLift", "SecClassState",
|
||||
"Lift", "ServiceElevator", "Dome", "Home", "MoonEmbLobby", nullptr
|
||||
};
|
||||
|
||||
if (!stateGetParrotMet() || _state == PARROT_MAILED || compareViewNameTo("Titania.Node 18.N"))
|
||||
return true;
|
||||
|
||||
// Check for rooms not to speak in
|
||||
for (const char *const *s = &ROOM_NAMES[0]; *s; ++s) {
|
||||
if (isEquals(*s))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't have the parrot speak too often
|
||||
if ((getTicksCount() - _lastSpeakTime) < 20000 || _speechCounter)
|
||||
return true;
|
||||
|
||||
playSound(TRANSLATE("z#475.wav", "z#212.wav"), 50);
|
||||
|
||||
if (msg->_target == "Bomb") {
|
||||
startTalking("PerchedParrot", 280236);
|
||||
} else if (msg->_target == "Announcements") {
|
||||
startTalking("PerchedParrot", 280263);
|
||||
} else if (msg->_target == "Television") {
|
||||
startTalking("PerchedParrot", 280264);
|
||||
} else if (msg->_target == "Barbot") {
|
||||
if (msg->_action == "AskForDrink")
|
||||
startTalking("PerchedParrot", 280262);
|
||||
} else if (msg->_target == "SuccUBus") {
|
||||
if (msg->_action == "TurnOn")
|
||||
startTalking("PerchedParrot", 80161);
|
||||
else if (msg->_action == "EnterView")
|
||||
startTalking("PerchedParrot", 80159);
|
||||
} else if (msg->_target == "Cellpoints") {
|
||||
if (getRandomNumber(2) == 0) {
|
||||
switch (getRandomNumber(2)) {
|
||||
case 0:
|
||||
startTalking("PerchedParrot", 80193);
|
||||
break;
|
||||
case 1:
|
||||
startTalking("PerchedParrot", 80197);
|
||||
break;
|
||||
case 2:
|
||||
startTalking("PerchedParrot", 80198);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (msg->_action == "DoorBot") {
|
||||
startTalking("PerchedParrot", 80195);
|
||||
} else if (msg->_action == "DeskBot") {
|
||||
startTalking("PerchedParrot", 80194);
|
||||
} else if (msg->_action == "BarBot") {
|
||||
startTalking("PerchedParrot", 80191);
|
||||
} else if (msg->_action == "BellBot") {
|
||||
startTalking("PerchedParrot", 80192);
|
||||
} else if (msg->_action == "LiftBot") {
|
||||
startTalking("PerchedParrot", 80196);
|
||||
}
|
||||
}
|
||||
|
||||
_lastSpeakTime = getTicksCount();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) {
|
||||
static const char *const NAMES[] = {
|
||||
"Talking0", "Talking1", "Talking2", "Talking3", "Talking4",
|
||||
"Talking5", "Talking6", "Talking7", nullptr
|
||||
};
|
||||
|
||||
if (!(_npcFlags & (NPCFLAG_MOVING | NPCFLAG_MOVE_START | NPCFLAG_MOVE_LOOP | NPCFLAG_MOVE_FINISH
|
||||
| NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT | NPCFLAG_MOVE_END))
|
||||
&& _visible && _state == PARROT_IN_CAGE) {
|
||||
if (compareViewNameTo("ParrotLobby.Node 1.N"))
|
||||
msg->_names = NAMES;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) {
|
||||
static const char *const NAMES[] = {
|
||||
"Idle0", "Idle1", "Peck At Feet", "Peck At Feet Left",
|
||||
"Peck At Feet Right", nullptr
|
||||
};
|
||||
|
||||
if (!(_npcFlags & (NPCFLAG_MOVING | NPCFLAG_MOVE_START | NPCFLAG_MOVE_LOOP | NPCFLAG_MOVE_FINISH
|
||||
| NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT | NPCFLAG_MOVE_END))
|
||||
&& _visible && _state == PARROT_IN_CAGE && compareViewNameTo("ParrotLobby.Node 1.N")) {
|
||||
CGameObject *dragItem = getDraggingObject();
|
||||
if (!dragItem || dragItem->getName() == "Chicken") {
|
||||
if (!_coreReplaced || getRandomNumber(3) != 0) {
|
||||
if (getRandomNumber(1)) {
|
||||
startTalking(this, 280267, findView());
|
||||
} else {
|
||||
msg->_names = NAMES;
|
||||
}
|
||||
} else {
|
||||
int id = -1;
|
||||
switch (getParrotResponse()) {
|
||||
case 0:
|
||||
id = 280107;
|
||||
break;
|
||||
case 1:
|
||||
id = 280106;
|
||||
break;
|
||||
case 2:
|
||||
id = 280115;
|
||||
break;
|
||||
case 3:
|
||||
id = 280114;
|
||||
break;
|
||||
case 4:
|
||||
id = 280113;
|
||||
break;
|
||||
case 5:
|
||||
id = 280112;
|
||||
break;
|
||||
case 6:
|
||||
id = 280111;
|
||||
break;
|
||||
case 7:
|
||||
id = 280110;
|
||||
break;
|
||||
case 8:
|
||||
id = 280109;
|
||||
break;
|
||||
case 9:
|
||||
id = 280108;
|
||||
break;
|
||||
case 10:
|
||||
id = 280105;
|
||||
break;
|
||||
case 11:
|
||||
id = 280000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (id != -1)
|
||||
startTalking(this, id, findView());
|
||||
|
||||
CActMsg actMsg("FlashCore");
|
||||
actMsg.execute("PerchCoreHolder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::FrameMsg(CFrameMsg *msg) {
|
||||
if (!compareViewNameTo("ParrotLobby.Node 1.N"))
|
||||
return false;
|
||||
if (_state != PARROT_IN_CAGE)
|
||||
return true;
|
||||
|
||||
Point pt = getMousePos();
|
||||
CGameObject *dragObject = getDraggingObject();
|
||||
int xp = _bounds.left + _bounds.width() / 2;
|
||||
bool chickenFlag = false;
|
||||
|
||||
if ((_npcFlags & NPCFLAG_MOVE_END) && !hasActiveMovie()) {
|
||||
_newXc = _newXp + _bounds.width() / 2;
|
||||
int xDiff = ABS(xp - _newXc);
|
||||
|
||||
if (xDiff < 64) {
|
||||
if (_panTarget) {
|
||||
CActMsg actMsg("PanAwayFromParrot");
|
||||
actMsg.execute(_panTarget);
|
||||
_panTarget = nullptr;
|
||||
}
|
||||
|
||||
_npcFlags &= ~(NPCFLAG_MOVING | NPCFLAG_MOVE_START | NPCFLAG_MOVE_LOOP
|
||||
| NPCFLAG_MOVE_FINISH | NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT | NPCFLAG_MOVE_END);
|
||||
return true;
|
||||
}
|
||||
|
||||
// WORKAROUND: Prevent panning away from stalling if Parrot was moving
|
||||
_npcFlags &= ~NPCFLAG_MOVING;
|
||||
} else {
|
||||
if (dragObject)
|
||||
chickenFlag = dragObject && dragObject->isEquals("Chicken");
|
||||
|
||||
if (_npcFlags & NPCFLAG_CHICKEN_OUTSIDE_CAGE) {
|
||||
if (!chickenFlag || pt.x > 70 || pt.y < 90 || pt.y > 280) {
|
||||
// A start of eating the chicken outside the cage has to be
|
||||
// aborted because the chicken has been moved out of range
|
||||
stopMovie();
|
||||
loadFrame(0);
|
||||
setPosition(Point(-90, _bounds.top));
|
||||
_npcFlags &= ~NPCFLAG_CHICKEN_OUTSIDE_CAGE;
|
||||
}
|
||||
} else {
|
||||
if (!chickenFlag)
|
||||
return false;
|
||||
}
|
||||
|
||||
_newXc = CLIP((int)pt.x, 230, 480);
|
||||
}
|
||||
|
||||
if ((_npcFlags & NPCFLAG_MOVING) || hasActiveMovie())
|
||||
return true;
|
||||
|
||||
if (ABS(_newXc - xp) > 64) {
|
||||
_npcFlags |= NPCFLAG_MOVING | NPCFLAG_MOVE_START;
|
||||
|
||||
if (_newXc >= xp) {
|
||||
// WORKAROUND: Original did not properly reset the eating chicken
|
||||
// flag when the player turns away from the cage
|
||||
setEatingChicken(false);
|
||||
|
||||
setPosition(Point(_bounds.left + 30, _bounds.top));
|
||||
_npcFlags |= NPCFLAG_MOVE_RIGHT;
|
||||
playClip("Walk Right Intro", MOVIE_NOTIFY_OBJECT);
|
||||
} else {
|
||||
_npcFlags |= NPCFLAG_MOVE_LEFT;
|
||||
playClip("Walk Left Intro", MOVIE_NOTIFY_OBJECT);
|
||||
}
|
||||
} else if (chickenFlag && pt.y >= 90 && pt.y <= 280 && !_triedEatChicken) {
|
||||
CParrotTriesChickenMsg triesMsg;
|
||||
triesMsg.execute(dragObject);
|
||||
|
||||
CTrueTalkTriggerActionMsg triggerMsg;
|
||||
int &action = triggerMsg._action;
|
||||
switch (triesMsg._condiment) {
|
||||
case 1:
|
||||
action = triesMsg._isHot ? 280034 : 280056;
|
||||
break;
|
||||
case 2:
|
||||
action = triesMsg._isHot ? 280033 : 280055;
|
||||
break;
|
||||
case 3:
|
||||
action = triesMsg._isHot ? 280032 : 280054;
|
||||
break;
|
||||
default:
|
||||
action = triesMsg._isHot ? 280266 : 280053;
|
||||
break;
|
||||
}
|
||||
|
||||
if (action == 280266) {
|
||||
if (pt.x < 75) {
|
||||
// Parrot needs to reach outside the cage
|
||||
_npcFlags |= NPCFLAG_CHICKEN_OUTSIDE_CAGE;
|
||||
playClip("Walk Left Intro", MOVIE_STOP_PREVIOUS);
|
||||
playClip("Walk Left Loop", MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent(236);
|
||||
chickenFlag = false;
|
||||
} else if ((pt.x - xp) > 15) {
|
||||
_npcFlags |= NPCFLAG_PECKING;
|
||||
playClip("Peck At Feet Right", MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent(170);
|
||||
} else if ((xp - pt.x) > 15) {
|
||||
_npcFlags |= NPCFLAG_PECKING;
|
||||
playClip("Peck At Feet Left", MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent(142);
|
||||
} else {
|
||||
_npcFlags |= NPCFLAG_PECKING;
|
||||
playClip("Peck At Feet", MOVIE_NOTIFY_OBJECT);
|
||||
movieEvent(157);
|
||||
}
|
||||
}
|
||||
|
||||
if (chickenFlag) {
|
||||
triggerMsg._param2 = 1;
|
||||
triggerMsg.execute(this);
|
||||
_triedEatChicken = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::MovieFrameMsg(CMovieFrameMsg *msg) {
|
||||
if (_npcFlags & NPCFLAG_PECKING) {
|
||||
// Whoopsy, the Parrot got your chicken
|
||||
CCarry *chicken = dynamic_cast<CCarry *>(findUnder(getRoot(), "Chicken"));
|
||||
if (chicken) {
|
||||
CActMsg actMsg("Eaten");
|
||||
actMsg.execute(chicken);
|
||||
}
|
||||
|
||||
_npcFlags &= ~NPCFLAG_PECKING;
|
||||
}
|
||||
|
||||
switch (msg->_frameNumber) {
|
||||
case 244:
|
||||
setPosition(Point(_bounds.left + 45, _bounds.top));
|
||||
break;
|
||||
case 261:
|
||||
case 262:
|
||||
case 265:
|
||||
case 268:
|
||||
case 271:
|
||||
setPosition(Point(_bounds.left + _eatOffsetX, _bounds.top));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::PutParrotBackMsg(CPutParrotBackMsg *msg) {
|
||||
const char *const NAMES[] = {
|
||||
"Talking0", "Talking1", "Talking2", "Talking3", "Talking4",
|
||||
"Talking5", "Talking6", "Talking7", nullptr
|
||||
};
|
||||
|
||||
int xp = CLIP(msg->_value, 230, 480);
|
||||
setVisible(true);
|
||||
moveToView();
|
||||
_state = PARROT_IN_CAGE;
|
||||
|
||||
setPosition(Point(xp - _bounds.width() / 2, _bounds.top));
|
||||
playRandomClip(NAMES, MOVIE_NOTIFY_OBJECT);
|
||||
|
||||
CActMsg actMsg("GainParrot");
|
||||
actMsg.execute("ParrotLobbyController");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::PreEnterViewMsg(CPreEnterViewMsg *msg) {
|
||||
if (_state == PARROT_IN_CAGE) {
|
||||
loadMovie(TRANSLATE("z167.avi", "z190.avi"), false);
|
||||
loadFrame(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::PanningAwayFromParrotMsg(CPanningAwayFromParrotMsg *msg) {
|
||||
if (_state != PARROT_IN_CAGE) {
|
||||
CActMsg actMsg("PanAwayFromParrot");
|
||||
actMsg.execute(msg->_target);
|
||||
_panTarget = nullptr;
|
||||
} else if (_takeOff) {
|
||||
_panTarget = msg->_target;
|
||||
loadMovie(TRANSLATE("z168.avi", "z191.avi"), false);
|
||||
stopMovie();
|
||||
playClip("Take Off", MOVIE_NOTIFY_OBJECT);
|
||||
_npcFlags |= NPCFLAG_TAKE_OFF;
|
||||
} else {
|
||||
_npcFlags |= NPCFLAG_MOVE_END;
|
||||
_panTarget = msg->_target;
|
||||
stopMovie();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::LeaveRoomMsg(CLeaveRoomMsg *msg) {
|
||||
if (_state == PARROT_IN_CAGE)
|
||||
startTalking(this, 280259);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrot::TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg) {
|
||||
// WORKAROUND: Fix parrot freezing up if you drag the chicken whilst
|
||||
// he's still returning to the center from a prior chicken drag
|
||||
if (_npcFlags & (NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT))
|
||||
_npcFlags &= ~(NPCFLAG_MOVING | NPCFLAG_MOVE_LEFT | NPCFLAG_MOVE_RIGHT);
|
||||
|
||||
return CTrueTalkNPC::TrueTalkNotifySpeechStartedMsg(msg);
|
||||
}
|
||||
|
||||
bool CParrot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) {
|
||||
if (msg->_dialogueId == 80022) {
|
||||
// WORKAROUND: End of parrot speech after having fixed Titania
|
||||
unlockMouse();
|
||||
changeView("Titania.Node 18.N", "");
|
||||
}
|
||||
|
||||
return CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(msg);
|
||||
}
|
||||
|
||||
void CParrot::setEatingChicken(bool eating) {
|
||||
_eatingChicken = eating;
|
||||
CStatusChangeMsg statusMsg;
|
||||
statusMsg._newStatus = eating ? 0 : 1;
|
||||
statusMsg.execute("PerchCoreHolder");
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
94
engines/titanic/npcs/parrot.h
Normal file
94
engines/titanic/npcs/parrot.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_PARROT_H
|
||||
#define TITANIC_PARROT_H
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
#include "titanic/moves/move_player_to.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum ParrotState {
|
||||
PARROT_IN_CAGE = 0, PARROT_1 = 1, PARROT_ESCAPED = 2,
|
||||
PARROT_MAILED = 3, PARROT_4 = 4
|
||||
};
|
||||
|
||||
class CParrot : public CTrueTalkNPC {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool ActMsg(CActMsg *msg);
|
||||
bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg);
|
||||
bool MouseDragStartMsg(CMouseDragStartMsg *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool ParrotSpeakMsg(CParrotSpeakMsg *msg);
|
||||
bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg);
|
||||
bool NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg);
|
||||
bool FrameMsg(CFrameMsg *msg);
|
||||
bool MovieFrameMsg(CMovieFrameMsg *msg);
|
||||
bool PutParrotBackMsg(CPutParrotBackMsg *msg);
|
||||
bool PreEnterViewMsg(CPreEnterViewMsg *msg);
|
||||
bool PanningAwayFromParrotMsg(CPanningAwayFromParrotMsg *msg);
|
||||
bool LeaveRoomMsg(CLeaveRoomMsg *msg);
|
||||
bool TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg);
|
||||
bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg);
|
||||
public:
|
||||
static bool _eatingChicken;
|
||||
static bool _takeOff;
|
||||
static bool _unused;
|
||||
static ParrotState _state;
|
||||
static bool _coreReplaced;
|
||||
private:
|
||||
int _unused1;
|
||||
CString _carryParrot;
|
||||
bool _canDrag;
|
||||
int _unused2;
|
||||
uint _lastSpeakTime;
|
||||
int _newXp;
|
||||
int _newXc;
|
||||
bool _triedEatChicken;
|
||||
int _eatOffsetX;
|
||||
CMovePlayerTo *_panTarget;
|
||||
private:
|
||||
/**
|
||||
* Called for the Parrot to start or finish eating
|
||||
*/
|
||||
void setEatingChicken(bool eating);
|
||||
public:
|
||||
CLASSDEF;
|
||||
CParrot();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_PARROT_H */
|
||||
152
engines/titanic/npcs/parrot_succubus.cpp
Normal file
152
engines/titanic/npcs/parrot_succubus.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/parrot_succubus.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
#include "titanic/carry/hose.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CParrotSuccUBus, CSuccUBus)
|
||||
ON_MESSAGE(HoseConnectedMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(MouseButtonDownMsg)
|
||||
ON_MESSAGE(LeaveNodeMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CParrotSuccUBus::CParrotSuccUBus() : CSuccUBus(), _hoseConnected(false),
|
||||
_pumpingSound(0), _hoseRemovalStartFrame(376), _hoseRemovalEndFrame(393) {
|
||||
}
|
||||
|
||||
void CParrotSuccUBus::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_hoseConnected, indent);
|
||||
file->writeQuotedLine(_pumpingTarget, indent);
|
||||
file->writeNumberLine(_pumpingSound, indent);
|
||||
|
||||
CSuccUBus::save(file, indent);
|
||||
}
|
||||
|
||||
void CParrotSuccUBus::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_hoseConnected = file->readNumber();
|
||||
_pumpingTarget = file->readString();
|
||||
_pumpingSound = file->readNumber();
|
||||
|
||||
CSuccUBus::load(file);
|
||||
}
|
||||
|
||||
bool CParrotSuccUBus::HoseConnectedMsg(CHoseConnectedMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
if (msg->_connected == _hoseConnected)
|
||||
return true;
|
||||
if (mailExists(pet->getRoomFlags()))
|
||||
return false;
|
||||
|
||||
_hoseConnected = msg->_connected;
|
||||
if (_hoseConnected) {
|
||||
CGameObject *item = msg->_object;
|
||||
_pumpingTarget = item->getName();
|
||||
CHoseConnectedMsg hoseMsg(1, this);
|
||||
hoseMsg.execute(msg->_object);
|
||||
item->petMoveToHiddenRoom();
|
||||
|
||||
CPumpingMsg pumpingMsg(1, this);
|
||||
pumpingMsg.execute(_pumpingTarget);
|
||||
_hoseConnected = true;
|
||||
|
||||
if (_isOn) {
|
||||
_isOn = false;
|
||||
} else {
|
||||
playMovie(_onStartFrame, _onEndFrame, 0);
|
||||
playSound(TRANSLATE("z#26.wav", "z#557.wav"));
|
||||
}
|
||||
|
||||
playMovie(_hoseStartFrame, _hoseEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
} else {
|
||||
stopMovie();
|
||||
stopSound(_pumpingSound);
|
||||
playMovie(_hoseRemovalStartFrame, _hoseRemovalEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
|
||||
CPumpingMsg pumpingMsg(0, this);
|
||||
pumpingMsg.execute(_pumpingTarget);
|
||||
|
||||
CGameObject *obj = getHiddenObject(_pumpingTarget);
|
||||
if (obj) {
|
||||
obj->petAddToInventory();
|
||||
obj->setVisible(true);
|
||||
}
|
||||
|
||||
_isOn = true;
|
||||
CTurnOff offMsg;
|
||||
offMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParrotSuccUBus::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
if (_hoseConnected) {
|
||||
playMovie(_pumpingStartFrame, _pumpingEndFrame, MOVIE_REPEAT);
|
||||
return true;
|
||||
} else {
|
||||
return CSuccUBus::EnterViewMsg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
bool CParrotSuccUBus::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
if (msg->_endFrame == _hoseEndFrame) {
|
||||
playMovie(_pumpingStartFrame, _pumpingEndFrame, MOVIE_REPEAT);
|
||||
_pumpingSound = playSound(TRANSLATE("z#472.wav", "z#209.wav"));
|
||||
return true;
|
||||
} else {
|
||||
return CSuccUBus::MovieEndMsg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
bool CParrotSuccUBus::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
|
||||
if (_hoseConnected) {
|
||||
CHoseConnectedMsg hoseMsg;
|
||||
hoseMsg._connected = false;
|
||||
hoseMsg.execute(this);
|
||||
return true;
|
||||
} else {
|
||||
return CSuccUBus::MouseButtonDownMsg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
bool CParrotSuccUBus::LeaveNodeMsg(CLeaveNodeMsg *msg) {
|
||||
if (_hoseConnected) {
|
||||
getHiddenObject(_pumpingTarget);
|
||||
if (CHose::_statics->_actionTarget.empty()) {
|
||||
playSound(TRANSLATE("z#51.wav", "z#582.wav"));
|
||||
CHoseConnectedMsg hoseMsg;
|
||||
hoseMsg._connected = false;
|
||||
hoseMsg.execute(this);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
59
engines/titanic/npcs/parrot_succubus.h
Normal file
59
engines/titanic/npcs/parrot_succubus.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_PARROT_SUCCUBUS_H
|
||||
#define TITANIC_PARROT_SUCCUBUS_H
|
||||
|
||||
#include "titanic/npcs/succubus.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CParrotSuccUBus : public CSuccUBus {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool HoseConnectedMsg(CHoseConnectedMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
|
||||
bool LeaveNodeMsg(CLeaveNodeMsg *msg);
|
||||
public:
|
||||
bool _hoseConnected;
|
||||
CString _pumpingTarget;
|
||||
int _pumpingSound;
|
||||
int _hoseRemovalStartFrame;
|
||||
int _hoseRemovalEndFrame;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CParrotSuccUBus();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_PARROT_SUCCUBUS_H */
|
||||
59
engines/titanic/npcs/robot_controller.cpp
Normal file
59
engines/titanic/npcs/robot_controller.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/robot_controller.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CRobotController, CGameObject)
|
||||
ON_MESSAGE(SummonBotMsg)
|
||||
ON_MESSAGE(SummonBotQueryMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CRobotController::CRobotController() : CGameObject(), _robotName("BellBot") {
|
||||
}
|
||||
|
||||
void CRobotController::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeQuotedLine(_robotName, indent);
|
||||
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CRobotController::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_robotName = file->readString();
|
||||
|
||||
CGameObject::load(file);
|
||||
}
|
||||
|
||||
bool CRobotController::SummonBotMsg(CSummonBotMsg *msg) {
|
||||
if (!petDismissBot(msg->_npcName))
|
||||
petOnSummonBot(msg->_npcName, msg->_value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRobotController::SummonBotQueryMsg(CSummonBotQueryMsg *msg) {
|
||||
return _robotName == msg->_npcName;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
52
engines/titanic/npcs/robot_controller.h
Normal file
52
engines/titanic/npcs/robot_controller.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_ROBOT_CONTROLLER_H
|
||||
#define TITANIC_ROBOT_CONTROLLER_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CRobotController : public CGameObject {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool SummonBotMsg(CSummonBotMsg *msg);
|
||||
bool SummonBotQueryMsg(CSummonBotQueryMsg *msg);
|
||||
protected:
|
||||
CString _robotName;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CRobotController();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_ROBOT_CONTROLLER_H */
|
||||
67
engines/titanic/npcs/starlings.cpp
Normal file
67
engines/titanic/npcs/starlings.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/starlings.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CStarlings, CCharacter)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(StatusChangeMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
bool CStarlings::_dead;
|
||||
|
||||
CStarlings::CStarlings() : CCharacter() {
|
||||
}
|
||||
|
||||
void CStarlings::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_dead, indent);
|
||||
|
||||
CCharacter::save(file, indent);
|
||||
}
|
||||
|
||||
void CStarlings::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_dead = file->readNumber();
|
||||
|
||||
CCharacter::load(file);
|
||||
}
|
||||
|
||||
bool CStarlings::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
if (_dead)
|
||||
// Tis but a flesh wound
|
||||
setVisible(false);
|
||||
else
|
||||
// Repeatedly play the starlings flying
|
||||
playMovie(MOVIE_REPEAT);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CStarlings::StatusChangeMsg(CStatusChangeMsg *msg) {
|
||||
// I'm not dead.. I'm getting better.
|
||||
_dead = msg->_newStatus == 1;
|
||||
setVisible(!_dead);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
53
engines/titanic/npcs/starlings.h
Normal file
53
engines/titanic/npcs/starlings.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_STARLINGS_H
|
||||
#define TITANIC_STARLINGS_H
|
||||
|
||||
#include "titanic/npcs/character.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CStarlings : public CCharacter {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool StatusChangeMsg(CStatusChangeMsg *msg);
|
||||
private:
|
||||
// This needs to be static to be shared across all starling instances
|
||||
static bool _dead;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CStarlings();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_STARLING_H */
|
||||
814
engines/titanic/npcs/succubus.cpp
Normal file
814
engines/titanic/npcs/succubus.cpp
Normal file
@@ -0,0 +1,814 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/succubus.h"
|
||||
#include "titanic/carry/carry.h"
|
||||
#include "titanic/carry/chicken.h"
|
||||
#include "titanic/core/view_item.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSuccUBus, CTrueTalkNPC)
|
||||
ON_MESSAGE(MouseButtonDownMsg)
|
||||
ON_MESSAGE(SubAcceptCCarryMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
ON_MESSAGE(PETDeliverMsg)
|
||||
ON_MESSAGE(PETReceiveMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(TrueTalkGetStateValueMsg)
|
||||
ON_MESSAGE(SignalObject)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(TurnOff)
|
||||
ON_MESSAGE(SUBTransition)
|
||||
ON_MESSAGE(SetChevRoomBits)
|
||||
ON_MESSAGE(ActMsg)
|
||||
ON_MESSAGE(MouseDragStartMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
bool CSuccUBus::_isOn; // SuccUBus turned on
|
||||
bool CSuccUBus::_motherBlocked; // Bilge SuccUBus is blocked
|
||||
bool CSuccUBus::_fuseboxOn; // SuccUBus dial in fusebox is on
|
||||
|
||||
CSuccUBus::CSuccUBus() : CTrueTalkNPC() {
|
||||
_initialStartFrame = -1;
|
||||
_initialEndFrame = -1;
|
||||
_endingStartFrame = -1;
|
||||
_endingEndFrame = -1;
|
||||
_sendStartFrame = 68;
|
||||
_sendEndFrame = 168;
|
||||
_receiveStartFrame = 168;
|
||||
_receiveEndFrame = 248;
|
||||
_onStartFrame = 0;
|
||||
_onEndFrame = 0x0E;
|
||||
_offStartFrame = 0x0E;
|
||||
_offEndFrame = 27;
|
||||
_okStartFrame = 40;
|
||||
_okEndFrame = 68;
|
||||
_flagsComparison = RFC_LOCATION;
|
||||
_mailP = nullptr;
|
||||
_afterReceiveStartFrame = 0;
|
||||
_afterReceiveEndFrame = 0;
|
||||
_trayOutStartFrame = 224;
|
||||
_trayOutEndFrame = 248;
|
||||
_sendAction = SA_SENT;
|
||||
_signalFlag = false;
|
||||
_signalTarget = "NULL";
|
||||
_startFrame1 = 28;
|
||||
_endFrame1 = 40;
|
||||
_rect1 = Rect(82, 284, 148, 339);
|
||||
_field184 = 15;
|
||||
_mailPresent = false;
|
||||
_rect2 = Rect(0, 0, 240, 340);
|
||||
_sendLost = false;
|
||||
_soundHandle = -1;
|
||||
_isChicken = false;
|
||||
_isFeathers = false;
|
||||
_priorRandomVal1 = 0;
|
||||
_priorRandomVal2 = 0;
|
||||
_emptyStartFrame = 303;
|
||||
_emptyEndFrame = 312;
|
||||
_smokeStartFrame = 313;
|
||||
_smokeEndFrame = 325;
|
||||
_hoseStartFrame = 326;
|
||||
_hoseEndFrame = 347;
|
||||
_pumpingStartFrame = 348;
|
||||
_pumpingEndFrame = 375;
|
||||
_destRoomFlags = 1;
|
||||
_inProgress = false;
|
||||
}
|
||||
|
||||
void CSuccUBus::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
|
||||
file->writeNumberLine(_isOn, indent);
|
||||
file->writeNumberLine(_initialStartFrame, indent);
|
||||
file->writeNumberLine(_initialEndFrame, indent);
|
||||
file->writeNumberLine(_endingStartFrame, indent);
|
||||
file->writeNumberLine(_endingEndFrame, indent);
|
||||
file->writeNumberLine(_sendStartFrame, indent);
|
||||
file->writeNumberLine(_sendEndFrame, indent);
|
||||
file->writeNumberLine(_receiveStartFrame, indent);
|
||||
file->writeNumberLine(_receiveEndFrame, indent);
|
||||
file->writeNumberLine(_onStartFrame, indent);
|
||||
file->writeNumberLine(_onEndFrame, indent);
|
||||
file->writeNumberLine(_offStartFrame, indent);
|
||||
file->writeNumberLine(_offEndFrame, indent);
|
||||
file->writeNumberLine(_okStartFrame, indent);
|
||||
file->writeNumberLine(_okEndFrame, indent);
|
||||
file->writeNumberLine(_flagsComparison, indent);
|
||||
|
||||
file->writeNumberLine(_motherBlocked, indent);
|
||||
file->writeNumberLine(_afterReceiveStartFrame, indent);
|
||||
file->writeNumberLine(_afterReceiveEndFrame, indent);
|
||||
file->writeNumberLine(_trayOutStartFrame, indent);
|
||||
file->writeNumberLine(_trayOutEndFrame, indent);
|
||||
file->writeNumberLine(_sendAction, indent);
|
||||
file->writeNumberLine(_signalFlag, indent);
|
||||
file->writeQuotedLine(_signalTarget, indent);
|
||||
file->writeNumberLine(_startFrame1, indent);
|
||||
file->writeNumberLine(_endFrame1, indent);
|
||||
file->writeNumberLine(_rect1.left, indent);
|
||||
file->writeNumberLine(_rect1.top, indent);
|
||||
file->writeNumberLine(_rect1.right, indent);
|
||||
file->writeNumberLine(_rect1.bottom, indent);
|
||||
file->writeNumberLine(_field184, indent);
|
||||
file->writeNumberLine(_mailPresent, indent);
|
||||
file->writeNumberLine(_rect2.left, indent);
|
||||
file->writeNumberLine(_rect2.top, indent);
|
||||
file->writeNumberLine(_rect2.right, indent);
|
||||
file->writeNumberLine(_rect2.bottom, indent);
|
||||
file->writeNumberLine(_sendLost, indent);
|
||||
file->writeNumberLine(_soundHandle, indent);
|
||||
file->writeNumberLine(_isChicken, indent);
|
||||
file->writeNumberLine(_isFeathers, indent);
|
||||
file->writeNumberLine(_priorRandomVal1, indent);
|
||||
file->writeNumberLine(_priorRandomVal2, indent);
|
||||
file->writeNumberLine(_emptyStartFrame, indent);
|
||||
file->writeNumberLine(_emptyEndFrame, indent);
|
||||
file->writeNumberLine(_smokeStartFrame, indent);
|
||||
file->writeNumberLine(_smokeEndFrame, indent);
|
||||
file->writeNumberLine(_hoseStartFrame, indent);
|
||||
file->writeNumberLine(_hoseEndFrame, indent);
|
||||
file->writeNumberLine(_pumpingStartFrame, indent);
|
||||
file->writeNumberLine(_pumpingEndFrame, indent);
|
||||
file->writeNumberLine(_destRoomFlags, indent);
|
||||
|
||||
file->writeNumberLine(_fuseboxOn, indent);
|
||||
file->writeNumberLine(_inProgress, indent);
|
||||
file->writeNumberLine(_field104, indent);
|
||||
|
||||
CTrueTalkNPC::save(file, indent);
|
||||
}
|
||||
|
||||
void CSuccUBus::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
|
||||
_isOn = file->readNumber();
|
||||
_initialStartFrame = file->readNumber();
|
||||
_initialEndFrame = file->readNumber();
|
||||
_endingStartFrame = file->readNumber();
|
||||
_endingEndFrame = file->readNumber();
|
||||
_sendStartFrame = file->readNumber();
|
||||
_sendEndFrame = file->readNumber();
|
||||
_receiveStartFrame = file->readNumber();
|
||||
_receiveEndFrame = file->readNumber();
|
||||
_onStartFrame = file->readNumber();
|
||||
_onEndFrame = file->readNumber();
|
||||
_offStartFrame = file->readNumber();
|
||||
_offEndFrame = file->readNumber();
|
||||
_okStartFrame = file->readNumber();
|
||||
_okEndFrame = file->readNumber();
|
||||
_flagsComparison = (RoomFlagsComparison)file->readNumber();
|
||||
|
||||
_motherBlocked = file->readNumber();
|
||||
_afterReceiveStartFrame = file->readNumber();
|
||||
_afterReceiveEndFrame = file->readNumber();
|
||||
_trayOutStartFrame = file->readNumber();
|
||||
_trayOutEndFrame = file->readNumber();
|
||||
_sendAction = (SuccUBusAction)file->readNumber();
|
||||
_signalFlag = file->readNumber();
|
||||
|
||||
_signalTarget = file->readString();
|
||||
_startFrame1 = file->readNumber();
|
||||
_endFrame1 = file->readNumber();
|
||||
_rect1.left = file->readNumber();
|
||||
_rect1.top = file->readNumber();
|
||||
_rect1.right = file->readNumber();
|
||||
_rect1.bottom = file->readNumber();
|
||||
_field184 = file->readNumber();
|
||||
_mailPresent = file->readNumber();
|
||||
_rect2.left = file->readNumber();
|
||||
_rect2.top = file->readNumber();
|
||||
_rect2.right = file->readNumber();
|
||||
_rect2.bottom = file->readNumber();
|
||||
_sendLost = file->readNumber();
|
||||
_soundHandle = file->readNumber();
|
||||
_isChicken = file->readNumber();
|
||||
_isFeathers = file->readNumber();
|
||||
_priorRandomVal1 = file->readNumber();
|
||||
_priorRandomVal2 = file->readNumber();
|
||||
_emptyStartFrame = file->readNumber();
|
||||
_emptyEndFrame = file->readNumber();
|
||||
_smokeStartFrame = file->readNumber();
|
||||
_smokeEndFrame = file->readNumber();
|
||||
_hoseStartFrame = file->readNumber();
|
||||
_hoseEndFrame = file->readNumber();
|
||||
_pumpingStartFrame = file->readNumber();
|
||||
_pumpingEndFrame = file->readNumber();
|
||||
_destRoomFlags = file->readNumber();
|
||||
|
||||
_fuseboxOn = file->readNumber();
|
||||
_inProgress = file->readNumber();
|
||||
_field104 = file->readNumber();
|
||||
|
||||
CTrueTalkNPC::load(file);
|
||||
}
|
||||
|
||||
bool CSuccUBus::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
|
||||
if (_inProgress)
|
||||
return true;
|
||||
|
||||
Rect tempRect = _rect1;
|
||||
tempRect.translate(_bounds.left, _bounds.top);
|
||||
|
||||
if (!_isOn) {
|
||||
CTurnOn onMsg;
|
||||
onMsg.execute(this);
|
||||
_isOn = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_mailPresent && tempRect.contains(msg->_mousePos))
|
||||
return true;
|
||||
|
||||
if (getRandomNumber(256) < 130) {
|
||||
_isOn = false;
|
||||
CTurnOff offMsg;
|
||||
offMsg.execute(this);
|
||||
} else {
|
||||
switch (getRandomNumber(2, &_priorRandomVal1)) {
|
||||
case 0:
|
||||
startTalking(this, 230055, findView());
|
||||
break;
|
||||
case 1:
|
||||
startTalking(this, 230067, findView());
|
||||
break;
|
||||
case 2:
|
||||
startTalking(this, 230045, findView());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg) {
|
||||
if (!msg->_item)
|
||||
return false;
|
||||
|
||||
CPetControl *pet = getPetControl();
|
||||
CCarry *item = dynamic_cast<CCarry *>(msg->_item);
|
||||
Rect tempRect = _rect2;
|
||||
tempRect.translate(_bounds.left, _bounds.top);
|
||||
uint roomFlags = pet ? pet->getRoomFlags() : 0;
|
||||
|
||||
if (!_isOn || !pet || !item || !tempRect.contains(item->getControid())) {
|
||||
item->petAddToInventory();
|
||||
} else if (mailExists(roomFlags)) {
|
||||
petDisplayMessage(SUCCUBUS_DESCRIPTION);
|
||||
item->petAddToInventory();
|
||||
} else {
|
||||
petContainerRemove(item);
|
||||
pet->phonographAction("");
|
||||
|
||||
CChicken *chicken = dynamic_cast<CChicken *>(item);
|
||||
bool chickenFlag = chicken ? chicken->_condiment == "None" : false;
|
||||
|
||||
item->setVisible(false);
|
||||
if (_startFrame1 >= 0) {
|
||||
playSound(TRANSLATE("z#23.wav", "z#554.wav"));
|
||||
playMovie(_startFrame1, _endFrame1, 0);
|
||||
}
|
||||
|
||||
if (!chickenFlag) {
|
||||
// Not chicken, or chicken with condiments
|
||||
_mailPresent = true;
|
||||
item->addMail(roomFlags);
|
||||
petSetArea(PET_REMOTE);
|
||||
petHighlightGlyph(16);
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
} else {
|
||||
// Chicken without condiments was passed to SuccUBus, so it'll
|
||||
// eat it immediately
|
||||
if (_okStartFrame >= 0) {
|
||||
startTalking(this, 70219, findView());
|
||||
playMovie(_okStartFrame, _okEndFrame, 0);
|
||||
}
|
||||
|
||||
if (_sendStartFrame >= 0) {
|
||||
playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
_sendAction = SA_EATEN;
|
||||
}
|
||||
|
||||
// WORKAROUND: The original had code below to return the chicken
|
||||
// to the dispensor after eaten, but since _fullViewName isn't
|
||||
// set, it didn't work. I've added code below in the else block
|
||||
// that replicates what happens when the parrot eats the chicken
|
||||
CViewItem *view = parseView(chicken->_fullViewName);
|
||||
if (view) {
|
||||
item->setPosition(item->_origPos);
|
||||
item->moveUnder(view);
|
||||
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
} else {
|
||||
CActMsg actMsg("Eaten");
|
||||
actMsg.execute(chicken);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
if (getRandomNumber(4) == 0 && compareRoomNameTo("PromenadeDeck")) {
|
||||
CParrotSpeakMsg speakMsg("SuccUBus", "EnterView");
|
||||
speakMsg.execute("PerchedParrot");
|
||||
}
|
||||
|
||||
petSetRemoteTarget();
|
||||
_mailP = nullptr;
|
||||
if (_initialStartFrame >= 0)
|
||||
loadFrame(_initialStartFrame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
petDisplayMessage(2, BLANK);
|
||||
if (_initialStartFrame >= 0)
|
||||
loadFrame(_initialStartFrame);
|
||||
else if (!_signalFlag && _onStartFrame >= 0)
|
||||
loadFrame(_onStartFrame);
|
||||
|
||||
petClear();
|
||||
if (_soundHandle != -1) {
|
||||
stopSound(_soundHandle, 1);
|
||||
_soundHandle = -1;
|
||||
}
|
||||
|
||||
if (_isOn) {
|
||||
_isOn = false;
|
||||
if (_offStartFrame >= 0)
|
||||
playSound(TRANSLATE("z#27.wav", "z#558.wav"), 100);
|
||||
|
||||
if (_signalFlag)
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
performAction(true, findView());
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) {
|
||||
if (_inProgress)
|
||||
return true;
|
||||
|
||||
if (!_isOn) {
|
||||
petDisplayMessage(2, SUCCUBUS_IS_IN_STANDBY);
|
||||
return true;
|
||||
}
|
||||
|
||||
CPetControl *pet = getPetControl();
|
||||
if (!pet)
|
||||
return true;
|
||||
|
||||
uint srcRoomFlags = pet->getRoomFlags();
|
||||
CGameObject *mailObject = findMail(srcRoomFlags);
|
||||
if (!mailObject) {
|
||||
// Nothing to send
|
||||
switch (getRandomNumber(2)) {
|
||||
case 0:
|
||||
startTalking(this, 70111, findView());
|
||||
break;
|
||||
case 1:
|
||||
startTalking(this, 70112, findView());
|
||||
break;
|
||||
case 2:
|
||||
startTalking(this, 70113, findView());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
petDisplayMessage(2, NOTHING_IN_SUCCUBUS_TRAY);
|
||||
} else {
|
||||
_sendLost = false;
|
||||
|
||||
CRoomFlags roomFlags = _destRoomFlags;
|
||||
if (!pet->isSuccUBusDest(roomFlags) || pet->getMailDestClass(roomFlags) < getPassengerClass()) {
|
||||
roomFlags = pet->getSpecialRoomFlags("BilgeRoom");
|
||||
_sendLost = true;
|
||||
}
|
||||
|
||||
_isFeathers = mailObject->getName() == "Feathers";
|
||||
_isChicken = mailObject->getName() == "Chicken";
|
||||
_sendAction = SA_SENT;
|
||||
_mailPresent = false;
|
||||
_inProgress = true;
|
||||
lockMouse();
|
||||
|
||||
if (_isFeathers) {
|
||||
// The feather has special handling to be rejected by the SuccUBus
|
||||
_sendLost = false;
|
||||
sendMail(srcRoomFlags, roomFlags);
|
||||
pet->phonographAction("");
|
||||
|
||||
if (_okStartFrame >= 0) {
|
||||
playMovie(_okStartFrame, _okEndFrame, 0);
|
||||
startTalking(this, 230022, findView());
|
||||
}
|
||||
|
||||
_sendAction = SA_FEATHERS;
|
||||
if (_sendStartFrame >= 0)
|
||||
playMovie(_sendStartFrame, _sendEndFrame, 0);
|
||||
|
||||
if (_receiveStartFrame >= 0) {
|
||||
_mailP = mailObject;
|
||||
playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
}
|
||||
|
||||
if (_afterReceiveStartFrame >= 0) {
|
||||
playMovie(_afterReceiveStartFrame, _afterReceiveEndFrame, 0);
|
||||
}
|
||||
} else {
|
||||
// Send the mail to the destination
|
||||
sendMail(pet->getRoomFlags(), roomFlags);
|
||||
pet->phonographAction("");
|
||||
|
||||
if (_okStartFrame >= 0) {
|
||||
playMovie(_okStartFrame, _okEndFrame, 0);
|
||||
startTalking(this, 230012, findView());
|
||||
}
|
||||
|
||||
if (_sendStartFrame >= 0)
|
||||
playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::PETReceiveMsg(CPETReceiveMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
|
||||
if (_inProgress || !pet)
|
||||
return true;
|
||||
if (!_isOn) {
|
||||
petDisplayMessage(2, SUCCUBUS_IS_IN_STANDBY);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint petRoomFlags = pet->getRoomFlags();
|
||||
if (mailExists(petRoomFlags)) {
|
||||
// There's already something to send in the tray, so you can't receive
|
||||
switch (getRandomNumber(2)) {
|
||||
case 0:
|
||||
startTalking(this, 70080, findView());
|
||||
break;
|
||||
case 1:
|
||||
startTalking(this, 70081, findView());
|
||||
break;
|
||||
case 2:
|
||||
startTalking(this, 70082, findView());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// When the SuccUBus dial in Titania's fusebox is on, then
|
||||
// any mail can be received by the SuccUBus in the bomb room.
|
||||
// Otherwise, only get mail sent to this specific SuccUBus
|
||||
CGameObject *mailObject = findMailByFlags(
|
||||
_fuseboxOn && compareRoomNameTo("Titania") ? RFC_TITANIA : _flagsComparison, petRoomFlags);
|
||||
|
||||
if (!mailObject) {
|
||||
// No mail for this SuccUBus
|
||||
if (getRandomNumber(1) == 0) {
|
||||
startTalking(this, 70104, findView());
|
||||
} else {
|
||||
startTalking(this, 70105, findView());
|
||||
}
|
||||
|
||||
playMovie(_emptyStartFrame, _emptyEndFrame, 0);
|
||||
playMovie(_smokeStartFrame, _smokeEndFrame, 0);
|
||||
petDisplayMessage(2, NOTHING_TO_DELIVER);
|
||||
} else {
|
||||
// Receive the mail addressed to this SuccUBus
|
||||
_mailP = mailObject;
|
||||
startTalking(this, 230004, findView());
|
||||
|
||||
if (_receiveStartFrame >= 0) {
|
||||
_sendAction = SA_FEATHERS;
|
||||
_inProgress = true;
|
||||
lockMouse();
|
||||
playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
uint petRoomFlags = pet ? pet->getRoomFlags() : 0;
|
||||
|
||||
if (msg->_endFrame == _offEndFrame) {
|
||||
if (_endingStartFrame >= 0)
|
||||
playSound(TRANSLATE("z#30.wav", "z#561.wav"), 100);
|
||||
|
||||
if (_signalFlag) {
|
||||
_signalFlag = false;
|
||||
setVisible(false);
|
||||
CSignalObject signalMsg;
|
||||
signalMsg._numValue = 1;
|
||||
signalMsg.execute(_signalTarget);
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _onEndFrame) {
|
||||
bool flag = false;
|
||||
|
||||
if (pet && !mailExists(petRoomFlags)) {
|
||||
CGameObject *mailObject = _fuseboxOn && compareRoomNameTo("Titania") ?
|
||||
findMailByFlags(RFC_TITANIA, petRoomFlags) :
|
||||
findMailByFlags(_flagsComparison, petRoomFlags);
|
||||
|
||||
if (mailObject) {
|
||||
switch (getRandomNumber(4)) {
|
||||
case 0:
|
||||
startTalking(this, 70094, findView());
|
||||
break;
|
||||
case 1:
|
||||
startTalking(this, 70095, findView());
|
||||
break;
|
||||
case 2:
|
||||
startTalking(this, 70096, findView());
|
||||
break;
|
||||
case 3:
|
||||
startTalking(this, 70098, findView());
|
||||
break;
|
||||
case 4:
|
||||
startTalking(this, 70099, findView());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_mailPresent && !flag) {
|
||||
stopSound(_soundHandle);
|
||||
_soundHandle = -1;
|
||||
|
||||
switch (getRandomNumber(_motherBlocked ? 7 : 5, &_priorRandomVal2)) {
|
||||
case 2:
|
||||
startTalking(this, 230001, findView());
|
||||
break;
|
||||
case 3:
|
||||
startTalking(this, 230002, findView());
|
||||
break;
|
||||
case 4:
|
||||
startTalking(this, 230003, findView());
|
||||
break;
|
||||
case 5:
|
||||
startTalking(this, 230064, findView());
|
||||
break;
|
||||
case 6:
|
||||
startTalking(this, 230062, findView());
|
||||
break;
|
||||
case 7:
|
||||
startTalking(this, 230063, findView());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _sendEndFrame) {
|
||||
if (_sendAction == SA_FEATHERS) {
|
||||
startTalking(this, 230022, findView());
|
||||
} else if (_sendAction == SA_EATEN) {
|
||||
startTalking(this, 230017, findView());
|
||||
} else if (_sendLost) {
|
||||
startTalking(this, 230019, findView());
|
||||
_sendLost = false;
|
||||
} else if (_isChicken) {
|
||||
startTalking(this, 230018, findView());
|
||||
_isChicken = false;
|
||||
} else {
|
||||
startTalking(this, 230013, findView());
|
||||
}
|
||||
|
||||
if (_inProgress) {
|
||||
_inProgress = false;
|
||||
unlockMouse();
|
||||
}
|
||||
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
}
|
||||
|
||||
if (msg->_endFrame == _receiveEndFrame) {
|
||||
// SuccUBus disgorged mail
|
||||
if (pet && _mailP) {
|
||||
_mailP->setMailDest(petRoomFlags);
|
||||
}
|
||||
|
||||
_mailPresent = true;
|
||||
_mailP = nullptr;
|
||||
if (_inProgress) {
|
||||
_inProgress = false;
|
||||
unlockMouse();
|
||||
}
|
||||
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg) {
|
||||
if (msg->_stateNum == 1)
|
||||
msg->_stateVal = _isOn;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::SignalObject(CSignalObject *msg) {
|
||||
if (msg->_numValue == 1) {
|
||||
_signalTarget = msg->_strValue;
|
||||
_signalFlag = true;
|
||||
setVisible(true);
|
||||
CTurnOn onMsg;
|
||||
onMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::TurnOn(CTurnOn *msg) {
|
||||
if (getRandomNumber(9) == 0) {
|
||||
CParrotSpeakMsg speakMsg("SuccUBus", "TurnOn");
|
||||
speakMsg.execute("PerchedParrot");
|
||||
}
|
||||
|
||||
CPetControl *pet = getPetControl();
|
||||
if (pet) {
|
||||
if (!_signalFlag && _initialStartFrame >= 0) {
|
||||
playMovie(_initialStartFrame, _initialEndFrame, 0);
|
||||
playSound(TRANSLATE("z#30.wav", "z#561.wav"), 100);
|
||||
}
|
||||
|
||||
if (_onStartFrame >= 0) {
|
||||
playMovie(_onStartFrame, _onEndFrame, MOVIE_NOTIFY_OBJECT);
|
||||
playSound(TRANSLATE("z#26.wav", "z#557.wav"), 100);
|
||||
}
|
||||
|
||||
uint petRoomFlags = pet->getRoomFlags();
|
||||
if (mailExists(petRoomFlags) && _endFrame1 >= 0)
|
||||
// Mail canister present
|
||||
playMovie(_endFrame1, _endFrame1, 0);
|
||||
|
||||
_isOn = true;
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
|
||||
setTalking(this, true, findView());
|
||||
petSetArea(PET_REMOTE);
|
||||
petHighlightGlyph(16);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::TurnOff(CTurnOff *msg) {
|
||||
if (_soundHandle != -1) {
|
||||
stopSound(_soundHandle);
|
||||
_soundHandle = -1;
|
||||
}
|
||||
|
||||
if (_offStartFrame >= 0) {
|
||||
playSound(TRANSLATE("z#27.wav", "z#558.wav"), 100);
|
||||
playMovie(_offStartFrame, _offEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
}
|
||||
|
||||
if (!_signalFlag && _endingStartFrame >= 0)
|
||||
playMovie(_endingStartFrame, _endingEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_WAIT_FOR_FINISH);
|
||||
|
||||
_isOn = false;
|
||||
performAction(true);
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::SUBTransition(CSUBTransition *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
|
||||
if (pet) {
|
||||
uint petRoomFlags = pet->getRoomFlags();
|
||||
|
||||
if (_isOn) {
|
||||
CGameObject *mailObject = findMail(petRoomFlags);
|
||||
if (mailObject)
|
||||
pet->phonographAction("Send");
|
||||
else
|
||||
pet->phonographAction("Receive");
|
||||
} else {
|
||||
if (pet->isSuccUBusRoom(petRoomFlags))
|
||||
pet->phonographAction("Record");
|
||||
else
|
||||
pet->phonographAction("");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::SetChevRoomBits(CSetChevRoomBits *msg) {
|
||||
if (_isOn) {
|
||||
_destRoomFlags = msg->_roomFlags;
|
||||
playSound(TRANSLATE("z#98.wav", "z#629.wav"), 100);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::ActMsg(CActMsg *msg) {
|
||||
if (msg->_action == "EnableObject")
|
||||
// SuccUBus dial in fusebox was turned on
|
||||
_fuseboxOn = true;
|
||||
else if (msg->_action == "DisableObject")
|
||||
// SuccUBus dial in fusebox was turned off
|
||||
_fuseboxOn = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSuccUBus::MouseDragStartMsg(CMouseDragStartMsg *msg) {
|
||||
CPetControl *pet = getPetControl();
|
||||
Rect tempRect = _rect1;
|
||||
tempRect.translate(_bounds.left, _bounds.top);
|
||||
|
||||
if (_inProgress || !_isOn || !_mailPresent || !tempRect.contains(msg->_mousePos)
|
||||
|| !pet)
|
||||
return true;
|
||||
|
||||
uint petRoomFlags = pet->getRoomFlags();
|
||||
CGameObject *mailObject = findMail(petRoomFlags);
|
||||
if (!mailObject)
|
||||
return true;
|
||||
|
||||
petAddToCarryParcel(mailObject);
|
||||
CViewItem *view = getView();
|
||||
if (!view)
|
||||
return true;
|
||||
|
||||
mailObject->moveUnder(view);
|
||||
mailObject->setPosition(Point(msg->_mousePos.x + mailObject->_bounds.width() / 2,
|
||||
msg->_mousePos.y + mailObject->_bounds.height() / 2));
|
||||
|
||||
CVisibleMsg visibleMsg(true);
|
||||
visibleMsg.execute(mailObject);
|
||||
CPassOnDragStartMsg dragMsg;
|
||||
dragMsg._mousePos = msg->_mousePos;
|
||||
dragMsg._value3 = 1;
|
||||
dragMsg.execute(mailObject);
|
||||
|
||||
if (!dragMsg._value4)
|
||||
msg->_dragItem = mailObject;
|
||||
|
||||
loadFrame(_field184);
|
||||
_mailPresent = false;
|
||||
CSUBTransition transMsg;
|
||||
transMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
117
engines/titanic/npcs/succubus.h
Normal file
117
engines/titanic/npcs/succubus.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_SUCCUBUS_H
|
||||
#define TITANIC_SUCCUBUS_H
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
#include "titanic/messages/pet_messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum SuccUBusAction { SA_SENT = 0, SA_FEATHERS = 1, SA_EATEN = 2,
|
||||
SA_BILGE_FEATHERS = 3, SA_BILGE_SENT = 4, SA_BILGE_EATEN = 5 };
|
||||
|
||||
class CSuccUBus : public CTrueTalkNPC {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
|
||||
bool SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
bool PETDeliverMsg(CPETDeliverMsg *msg);
|
||||
bool PETReceiveMsg(CPETReceiveMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg);
|
||||
bool SignalObject(CSignalObject *msg);
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool TurnOff(CTurnOff *msg);
|
||||
bool SUBTransition(CSUBTransition *msg);
|
||||
bool SetChevRoomBits(CSetChevRoomBits *msg);
|
||||
bool ActMsg(CActMsg *msg);
|
||||
bool MouseDragStartMsg(CMouseDragStartMsg *msg);
|
||||
protected:
|
||||
static bool _isOn;
|
||||
static bool _motherBlocked;
|
||||
static bool _fuseboxOn;
|
||||
protected:
|
||||
int _initialStartFrame;
|
||||
int _initialEndFrame;
|
||||
int _endingStartFrame;
|
||||
int _endingEndFrame;
|
||||
int _sendStartFrame;
|
||||
int _sendEndFrame;
|
||||
int _receiveStartFrame;
|
||||
int _receiveEndFrame;
|
||||
int _onStartFrame;
|
||||
int _onEndFrame;
|
||||
int _offStartFrame;
|
||||
int _offEndFrame;
|
||||
int _okStartFrame;
|
||||
int _okEndFrame;
|
||||
RoomFlagsComparison _flagsComparison;
|
||||
CGameObject *_mailP;
|
||||
int _afterReceiveStartFrame;
|
||||
int _afterReceiveEndFrame;
|
||||
int _trayOutStartFrame;
|
||||
int _trayOutEndFrame;
|
||||
SuccUBusAction _sendAction;
|
||||
bool _signalFlag;
|
||||
CString _signalTarget;
|
||||
int _startFrame1;
|
||||
int _endFrame1;
|
||||
Rect _rect1;
|
||||
int _field184;
|
||||
bool _mailPresent;
|
||||
Rect _rect2;
|
||||
bool _sendLost;
|
||||
int _soundHandle;
|
||||
bool _isChicken;
|
||||
bool _isFeathers;
|
||||
int _priorRandomVal1;
|
||||
int _priorRandomVal2;
|
||||
int _emptyStartFrame;
|
||||
int _emptyEndFrame;
|
||||
int _smokeStartFrame;
|
||||
int _smokeEndFrame;
|
||||
int _hoseStartFrame;
|
||||
int _hoseEndFrame;
|
||||
int _pumpingStartFrame;
|
||||
int _pumpingEndFrame;
|
||||
uint _destRoomFlags;
|
||||
bool _inProgress;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CSuccUBus();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_SUCCUBUS_H */
|
||||
85
engines/titanic/npcs/summon_bots.cpp
Normal file
85
engines/titanic/npcs/summon_bots.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/summon_bots.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSummonBots, CRobotController)
|
||||
ON_MESSAGE(SummonBotQueryMsg)
|
||||
ON_MESSAGE(SummonBotMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CSummonBots::CSummonBots() : CRobotController(), _validSummonLocations("NULL"),
|
||||
_canSummonBellbot(false), _canSummonDoorbot(false) {
|
||||
}
|
||||
|
||||
void CSummonBots::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_canSummonBellbot, indent);
|
||||
file->writeNumberLine(_canSummonDoorbot, indent);
|
||||
file->writeQuotedLine(_validSummonLocations, indent);
|
||||
|
||||
CRobotController::save(file, indent);
|
||||
}
|
||||
|
||||
void CSummonBots::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_canSummonBellbot = file->readNumber();
|
||||
_canSummonDoorbot = file->readNumber();
|
||||
_validSummonLocations = file->readString();
|
||||
|
||||
CRobotController::load(file);
|
||||
}
|
||||
|
||||
bool CSummonBots::SummonBotQueryMsg(CSummonBotQueryMsg *msg) {
|
||||
if (msg->_npcName == "BellBot") {
|
||||
if (_canSummonBellbot && !petCheckNode(_validSummonLocations))
|
||||
return true;
|
||||
} else if (msg->_npcName == "DoorBot") {
|
||||
if (_canSummonDoorbot && !petCheckNode(_validSummonLocations))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSummonBots::SummonBotMsg(CSummonBotMsg *msg) {
|
||||
if (msg->_npcName == "BellBot") {
|
||||
if (!_canSummonBellbot)
|
||||
return false;
|
||||
|
||||
if (!petDismissBot("BellBot"))
|
||||
petOnSummonBot("Bellbot", msg->_value);
|
||||
} else if (msg->_npcName == "DoorBot") {
|
||||
if (!_canSummonDoorbot)
|
||||
return false;
|
||||
|
||||
if (!petDismissBot("Doorbot"))
|
||||
petOnSummonBot("Doorbot", msg->_value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
54
engines/titanic/npcs/summon_bots.h
Normal file
54
engines/titanic/npcs/summon_bots.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_SUMMON_BOTS_H
|
||||
#define TITANIC_SUMMON_BOTS_H
|
||||
|
||||
#include "titanic/npcs/robot_controller.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CSummonBots : public CRobotController {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool SummonBotQueryMsg(CSummonBotQueryMsg *msg);
|
||||
bool SummonBotMsg(CSummonBotMsg *msg);
|
||||
protected:
|
||||
CString _validSummonLocations;
|
||||
bool _canSummonBellbot;
|
||||
bool _canSummonDoorbot;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CSummonBots();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_SUMMON_BOTS_H */
|
||||
234
engines/titanic/npcs/titania.cpp
Normal file
234
engines/titanic/npcs/titania.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/titania.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CTitania, CCharacter)
|
||||
ON_MESSAGE(AddHeadPieceMsg)
|
||||
ON_MESSAGE(TakeHeadPieceMsg)
|
||||
ON_MESSAGE(ActMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(TimerMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CTitania::CTitania() : CCharacter() {
|
||||
_speechCentre = false;
|
||||
_olfactoryCentre = false;
|
||||
_centralCore = false;
|
||||
_visionCentre = false;
|
||||
_eye1 = false;
|
||||
_eye2 = false;
|
||||
_ear1 = false;
|
||||
_ear2 = false;
|
||||
_nose = false;
|
||||
_mouth = false;
|
||||
_showSpeech = true;
|
||||
}
|
||||
|
||||
void CTitania::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_speechCentre, indent);
|
||||
file->writeNumberLine(_olfactoryCentre, indent);
|
||||
file->writeNumberLine(_auditoryCentre, indent);
|
||||
file->writeNumberLine(_centralCore, indent);
|
||||
file->writeNumberLine(_visionCentre, indent);
|
||||
file->writeNumberLine(_eye1, indent);
|
||||
file->writeNumberLine(_eye2, indent);
|
||||
file->writeNumberLine(_ear1, indent);
|
||||
file->writeNumberLine(_ear2, indent);
|
||||
file->writeNumberLine(_nose, indent);
|
||||
file->writeNumberLine(_mouth, indent);
|
||||
file->writeNumberLine(_showSpeech, indent);
|
||||
|
||||
CCharacter::save(file, indent);
|
||||
}
|
||||
|
||||
void CTitania::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_speechCentre = file->readNumber();
|
||||
_olfactoryCentre = file->readNumber();
|
||||
_auditoryCentre = file->readNumber();
|
||||
_centralCore = file->readNumber();
|
||||
_visionCentre = file->readNumber();
|
||||
_eye1 = file->readNumber();
|
||||
_eye2 = file->readNumber();
|
||||
_ear1 = file->readNumber();
|
||||
_ear2 = file->readNumber();
|
||||
_nose = file->readNumber();
|
||||
_mouth = file->readNumber();
|
||||
_showSpeech = file->readNumber();
|
||||
|
||||
CCharacter::load(file);
|
||||
}
|
||||
|
||||
bool CTitania::AddHeadPieceMsg(CAddHeadPieceMsg *msg) {
|
||||
if (msg->_value == "VisionCentre") {
|
||||
_visionCentre = true;
|
||||
} else if (msg->_value == "AuditoryCentre") {
|
||||
_auditoryCentre = true;
|
||||
} else if (msg->_value == "OlfactoryCentre") {
|
||||
_olfactoryCentre = true;
|
||||
} else if (msg->_value == "SpeechCentre") {
|
||||
_speechCentre = true;
|
||||
} else if (msg->_value == "CentralCore") {
|
||||
_centralCore = true;
|
||||
} else if (msg->_value == "Eye1") {
|
||||
_eye1 = true;
|
||||
} else if (msg->_value == "Eye2") {
|
||||
_eye2 = true;
|
||||
} else if (msg->_value == "Ear1") {
|
||||
_ear1 = true;
|
||||
} else if (msg->_value == "Ear 2") {
|
||||
_ear2 = true;
|
||||
} else if (msg->_value == "Mouth") {
|
||||
_mouth = true;
|
||||
} else if (msg->_value == "Nose") {
|
||||
_nose = true;
|
||||
}
|
||||
|
||||
CActMsg actMsg("CheckHead");
|
||||
actMsg.execute(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTitania::TakeHeadPieceMsg(CTakeHeadPieceMsg *msg) {
|
||||
if (msg->_value == "VisionCentre") {
|
||||
_visionCentre = false;
|
||||
} else if (msg->_value == "AuditoryCentre") {
|
||||
_auditoryCentre = false;
|
||||
} else if (msg->_value == "OlfactoryCentre") {
|
||||
_olfactoryCentre = false;
|
||||
} else if (msg->_value == "SpeechCentre") {
|
||||
_speechCentre = false;
|
||||
} else if (msg->_value == "CentralCore") {
|
||||
_centralCore = false;
|
||||
} else if (msg->_value == "Eye1") {
|
||||
_eye1 = false;
|
||||
} else if (msg->_value == "Eye2") {
|
||||
_eye2 = false;
|
||||
} else if (msg->_value == "Ear1") {
|
||||
_ear1 = false;
|
||||
} else if (msg->_value == "Ear 2") {
|
||||
_ear2 = false;
|
||||
} else if (msg->_value == "Mouth") {
|
||||
_mouth = false;
|
||||
} else if (msg->_value == "Nose") {
|
||||
_nose = false;
|
||||
}
|
||||
|
||||
CActMsg actMsg("CheckHead");
|
||||
actMsg.execute(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTitania::ActMsg(CActMsg *msg) {
|
||||
if (msg->_action == "SleepTitania") {
|
||||
setVisible(true);
|
||||
playCutscene(52, 104);
|
||||
playSound(TRANSLATE("z#47.wav", "z#578.wav"), 100);
|
||||
changeView("Titania.Node 7.S", "");
|
||||
|
||||
// Re-enable control, and reset bomb's volume back to normal 60%
|
||||
petShow();
|
||||
enableMouse();
|
||||
CSetFrameMsg frameMsg(60);
|
||||
frameMsg.execute("Bomb");
|
||||
|
||||
} else if (msg->_action == "CheckHead") {
|
||||
CSenseWorkingMsg workingMsg1("Not Working");
|
||||
CSenseWorkingMsg workingMsg2("Not Working");
|
||||
CSenseWorkingMsg workingMsg3("Not Working");
|
||||
CSenseWorkingMsg workingMsg4("Not Working");
|
||||
|
||||
if (_eye1 && _eye2) {
|
||||
workingMsg1._value = _visionCentre ? "Working" : "Random";
|
||||
}
|
||||
if (_ear1 && _ear2) {
|
||||
workingMsg2._value = _auditoryCentre ? "Working" : "Random";
|
||||
}
|
||||
if (_nose) {
|
||||
workingMsg4._value = _olfactoryCentre ? "Working" : "Random";
|
||||
}
|
||||
if (_mouth) {
|
||||
workingMsg3._value = _speechCentre ? "Working" : "Random";
|
||||
}
|
||||
|
||||
if (_centralCore && _eye1 && _eye2 && _ear1 && _ear2 && _nose
|
||||
&& _mouth && _visionCentre && _speechCentre
|
||||
&& _olfactoryCentre && _auditoryCentre) {
|
||||
CProximity prox(Audio::Mixer::kSpeechSoundType);
|
||||
playSound(TRANSLATE("z#47.wav", "z#578.wav"), prox);
|
||||
|
||||
CActMsg actMsg("Woken");
|
||||
actMsg.execute("MouthSlot");
|
||||
actMsg.execute("VisionCentreSlot");
|
||||
setPassengerClass(UNCHECKED);
|
||||
|
||||
addTimer(1000);
|
||||
} else {
|
||||
workingMsg1.execute("Eye1Slot");
|
||||
workingMsg1.execute("Eye2Slot");
|
||||
workingMsg2.execute("Ear1Slot");
|
||||
workingMsg2.execute("Ear2Slot");
|
||||
workingMsg3.execute("MouthSlot");
|
||||
workingMsg4.execute("NoseSlot");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTitania::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
if (_showSpeech) {
|
||||
_showSpeech = false;
|
||||
disableMouse();
|
||||
petHide();
|
||||
|
||||
// The Bomb uses the CSetFrameMsg as a hack for setting the volume.
|
||||
// In case it's currently active, set it to a quieter 25% so that
|
||||
// it won't obscure Titania's speech.
|
||||
CSetFrameMsg frameMsg;
|
||||
frameMsg._frameNumber = 25;
|
||||
frameMsg.execute("Bomb");
|
||||
|
||||
playCutscene(0, 52);
|
||||
setVisible(false);
|
||||
CActMsg actMsg("TitaniaSpeech");
|
||||
actMsg.execute("TitaniaSpeech");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTitania::TimerMsg(CTimerMsg *msg) {
|
||||
// WORKAROUND: The original uses the disc change dialog as a pause
|
||||
// to allow the parrot speech to finish. I've rewritten it to instead
|
||||
// use the standard TrueTalkNotifySpeechEndedMsg message instead
|
||||
startTalking("PerchedParrot", 80022);
|
||||
lockMouse();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
66
engines/titanic/npcs/titania.h
Normal file
66
engines/titanic/npcs/titania.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_TITANIA_H
|
||||
#define TITANIC_TITANIA_H
|
||||
|
||||
#include "titanic/npcs/character.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CTitania : public CCharacter {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool AddHeadPieceMsg(CAddHeadPieceMsg *msg);
|
||||
bool TakeHeadPieceMsg(CTakeHeadPieceMsg *msg);
|
||||
bool ActMsg(CActMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool TimerMsg(CTimerMsg *msg);
|
||||
private:
|
||||
bool _speechCentre;
|
||||
bool _olfactoryCentre;
|
||||
bool _auditoryCentre;
|
||||
bool _centralCore;
|
||||
bool _visionCentre;
|
||||
bool _eye1;
|
||||
bool _eye2;
|
||||
bool _ear1;
|
||||
bool _ear2;
|
||||
bool _nose;
|
||||
bool _mouth;
|
||||
bool _showSpeech;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CTitania();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_TITANIA_H */
|
||||
262
engines/titanic/npcs/true_talk_npc.cpp
Normal file
262
engines/titanic/npcs/true_talk_npc.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/npcs/true_talk_npc.h"
|
||||
#include "titanic/core/view_item.h"
|
||||
#include "titanic/debugger.h"
|
||||
#include "titanic/game_manager.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CTrueTalkNPC, CCharacter)
|
||||
ON_MESSAGE(TextInputMsg)
|
||||
ON_MESSAGE(TrueTalkGetAssetDetailsMsg)
|
||||
ON_MESSAGE(DismissBotMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechStartedMsg)
|
||||
ON_MESSAGE(TrueTalkNotifySpeechEndedMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(NPCQueueIdleAnimMsg)
|
||||
ON_MESSAGE(TimerMsg)
|
||||
ON_MESSAGE(NPCPlayAnimationMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CTrueTalkNPC::CTrueTalkNPC() : _assetName("z451.dlg"),
|
||||
_assetNumber(0x11170), _fieldE4(0), _npcFlags(0), _speechDuration(0), _startTicks(0),
|
||||
_fieldF4(0), _fieldF8(0), _speechTimerId(0), _speechCounter(0), _field104(0) {
|
||||
}
|
||||
|
||||
void CTrueTalkNPC::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_assetNumber, indent);
|
||||
file->writeQuotedLine(_assetName, indent);
|
||||
file->writeNumberLine(_fieldE4, indent);
|
||||
file->writeNumberLine(_npcFlags, indent);
|
||||
file->writeNumberLine(_speechDuration, indent);
|
||||
file->writeNumberLine(_startTicks, indent);
|
||||
file->writeNumberLine(_fieldF4, indent);
|
||||
file->writeNumberLine(_fieldF8, indent);
|
||||
file->writeNumberLine(_speechTimerId, indent);
|
||||
file->writeNumberLine(_speechCounter, indent);
|
||||
file->writeNumberLine(_field104, indent);
|
||||
|
||||
CCharacter::save(file, indent);
|
||||
}
|
||||
|
||||
void CTrueTalkNPC::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_assetNumber = file->readNumber();
|
||||
_assetName = file->readString();
|
||||
_fieldE4 = file->readNumber();
|
||||
_npcFlags = file->readNumber();
|
||||
_speechDuration = file->readNumber();
|
||||
_startTicks = file->readNumber();
|
||||
_fieldF4 = file->readNumber();
|
||||
_fieldF8 = file->readNumber();
|
||||
_speechTimerId = file->readNumber();
|
||||
_speechCounter = file->readNumber();
|
||||
_field104 = file->readNumber();
|
||||
|
||||
CCharacter::load(file);
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::TextInputMsg(CTextInputMsg *msg) {
|
||||
processInput(msg, _field104 ? findView() : nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::TrueTalkGetAssetDetailsMsg(CTrueTalkGetAssetDetailsMsg *msg) {
|
||||
msg->_filename = _assetName;
|
||||
msg->_numValue = _assetNumber;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::DismissBotMsg(CDismissBotMsg *msg) {
|
||||
performAction(1, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg) {
|
||||
debugC(DEBUG_DETAILED, kDebugScripts, "%s TrueTalkNotifySpeechStartedMsg flags=%x dialogueId=%d",
|
||||
getName().c_str(), _npcFlags, msg->_dialogueId);
|
||||
|
||||
_npcFlags |= NPCFLAG_SPEAKING;
|
||||
++_speechCounter;
|
||||
|
||||
if (!(_npcFlags & NPCFLAG_DOORBOT_IN_HOME)) {
|
||||
// Stop any previous animation
|
||||
if (_speechTimerId)
|
||||
stopAnimTimer(_speechTimerId);
|
||||
_speechTimerId = 0;
|
||||
|
||||
_speechDuration = msg->_speechDuration;
|
||||
_startTicks = getTicksCount();
|
||||
|
||||
if (!hasActiveMovie() || (_npcFlags & NPCFLAG_IDLING)) {
|
||||
_npcFlags &= ~NPCFLAG_IDLING;
|
||||
stopMovie();
|
||||
|
||||
CNPCPlayTalkingAnimationMsg msg1(_speechDuration, 0, nullptr);
|
||||
msg1.execute(this);
|
||||
|
||||
if (msg1._names) {
|
||||
CNPCPlayAnimationMsg msg2(msg1._names, msg1._speechDuration);
|
||||
msg2.execute(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) {
|
||||
debugC(DEBUG_DETAILED, kDebugScripts, "%s TrueTalkNotifySpeechEndedMsg flags=%x dialogueId=%d", getName().c_str(), _npcFlags, msg->_dialogueId);
|
||||
|
||||
if (!getGameManager())
|
||||
return false;
|
||||
|
||||
_npcFlags &= ~NPCFLAG_SPEAKING;
|
||||
--_speechCounter;
|
||||
_speechDuration = 0;
|
||||
|
||||
if (!(_npcFlags & NPCFLAG_DOORBOT_IN_HOME)) {
|
||||
CNPCPlayTalkingAnimationMsg msg1(0, 2, nullptr);
|
||||
msg1.execute(this);
|
||||
CNPCQueueIdleAnimMsg msg2;
|
||||
msg2.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
if (_npcFlags & NPCFLAG_IDLING) {
|
||||
_npcFlags &= ~NPCFLAG_IDLING;
|
||||
CNPCQueueIdleAnimMsg idleMsg;
|
||||
idleMsg.execute(this);
|
||||
return true;
|
||||
} else if (!(_npcFlags & NPCFLAG_SPEAKING)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int diff = getTicksCount() - _startTicks;
|
||||
int ticks = MAX((int)_speechDuration - diff, 0);
|
||||
CNPCPlayTalkingAnimationMsg msg1(ticks, ticks > 1000 ? 1 : 2, 0);
|
||||
msg1.execute(this);
|
||||
|
||||
if (msg1._names) {
|
||||
CNPCPlayAnimationMsg msg2(msg1._names, ticks);
|
||||
msg2.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::NPCQueueIdleAnimMsg(CNPCQueueIdleAnimMsg *msg) {
|
||||
int rndVal = getRandomNumber(_fieldF8 - 1) - (_fieldF8 / 2);
|
||||
_speechTimerId = startAnimTimer("NPCIdleAnim", _fieldF4 + rndVal, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::TimerMsg(CTimerMsg *msg) {
|
||||
if (_npcFlags & NPCFLAG_START_IDLING) {
|
||||
if (_speechCounter > 0)
|
||||
return false;
|
||||
|
||||
CNPCPlayIdleAnimationMsg idleMsg;
|
||||
if (idleMsg.execute(this)) {
|
||||
if (idleMsg._names) {
|
||||
CNPCPlayAnimationMsg animMsg(idleMsg._names, 0);
|
||||
animMsg.execute(this);
|
||||
}
|
||||
|
||||
_npcFlags |= NPCFLAG_IDLING;
|
||||
}
|
||||
}
|
||||
|
||||
_speechTimerId = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTrueTalkNPC::NPCPlayAnimationMsg(CNPCPlayAnimationMsg *msg) {
|
||||
// const char *const *nameP = msg->_names;
|
||||
int count;
|
||||
for (count = 0; msg->_names[count]; ++count)
|
||||
;
|
||||
|
||||
if (msg->_maxDuration) {
|
||||
// Randomly pick a clip that's less than the allowed maximum
|
||||
int tries = 10, index;
|
||||
do {
|
||||
index = getRandomNumber(count - 1);
|
||||
} while (getClipDuration(msg->_names[index]) > msg->_maxDuration && --tries);
|
||||
|
||||
if (!tries) {
|
||||
// Sequentially go through the clips to find any below the maximum
|
||||
index = 0;
|
||||
for (int idx = 0; idx < count; ++idx) {
|
||||
if (getClipDuration(msg->_names[idx]) < msg->_maxDuration) {
|
||||
index = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
playClip(msg->_names[index], MOVIE_NOTIFY_OBJECT);
|
||||
} else {
|
||||
playClip(msg->_names[getRandomNumber(count - 1)], MOVIE_NOTIFY_OBJECT);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTrueTalkNPC::processInput(CTextInputMsg *msg, CViewItem *view) {
|
||||
CTrueTalkManager *talkManager = getGameManager()->getTalkManager();
|
||||
if (talkManager)
|
||||
talkManager->processInput(this, msg, view);
|
||||
}
|
||||
|
||||
void CTrueTalkNPC::setView(CViewItem *view) {
|
||||
CTrueTalkManager *talkManager = getGameManager()->getTalkManager();
|
||||
if (talkManager)
|
||||
talkManager->start3(this, view);
|
||||
}
|
||||
|
||||
void CTrueTalkNPC::startTalker(CViewItem *view) {
|
||||
CGameManager *gameManager = getGameManager();
|
||||
if (gameManager)
|
||||
gameManager->getTalkManager()->start4(this, view);
|
||||
}
|
||||
|
||||
void CTrueTalkNPC::performAction(bool startTalkingFlag, CViewItem *destView) {
|
||||
CPetControl *pet = getPetControl();
|
||||
if (pet)
|
||||
pet->resetActiveNPC();
|
||||
|
||||
if (startTalkingFlag)
|
||||
startTalker(destView);
|
||||
|
||||
if (pet)
|
||||
pet->convResetNPC();
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
101
engines/titanic/npcs/true_talk_npc.h
Normal file
101
engines/titanic/npcs/true_talk_npc.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_TRUE_TALK_NPC_H
|
||||
#define TITANIC_TRUE_TALK_NPC_H
|
||||
|
||||
#include "titanic/npcs/character.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
#include "titanic/true_talk/tt_talker.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum NpcFlag {
|
||||
NPCFLAG_SPEAKING = 1, NPCFLAG_IDLING = 2, NPCFLAG_START_IDLING = 4,
|
||||
NPCFLAG_DOORBOT_IN_HOME = 8, NPCFLAG_MOVING = 0x10000, NPCFLAG_MOVE_START = 0x20000,
|
||||
NPCFLAG_MOVE_LOOP = 0x40000, NPCFLAG_MOVE_FINISH = 0x80000,
|
||||
NPCFLAG_MOVE_LEFT = 0x100000, NPCFLAG_MOVE_RIGHT = 0x200000,
|
||||
NPCFLAG_MOVE_END = 0x400000, NPCFLAG_PECKING = 0x800000,
|
||||
NPCFLAG_CHICKEN_OUTSIDE_CAGE = 0x1000000, NPCFLAG_TAKE_OFF = 0x2000000,
|
||||
NPCFLAG_SUMMON_BELLBOT = 0x4000000, NPCFLAG_DOORBOT_INTRO = 0x8000000
|
||||
};
|
||||
|
||||
class CViewItem;
|
||||
|
||||
class CTrueTalkNPC : public CCharacter {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TextInputMsg(CTextInputMsg *msg);
|
||||
bool TrueTalkGetAssetDetailsMsg(CTrueTalkGetAssetDetailsMsg *msg);
|
||||
bool DismissBotMsg(CDismissBotMsg *msg);
|
||||
bool TrueTalkNotifySpeechStartedMsg(CTrueTalkNotifySpeechStartedMsg *msg);
|
||||
bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool NPCQueueIdleAnimMsg(CNPCQueueIdleAnimMsg *msg);
|
||||
bool TimerMsg(CTimerMsg *msg);
|
||||
bool NPCPlayAnimationMsg(CNPCPlayAnimationMsg *msg);
|
||||
protected:
|
||||
int _assetNumber;
|
||||
CString _assetName;
|
||||
int _fieldE4;
|
||||
uint _npcFlags;
|
||||
uint _speechDuration;
|
||||
uint _startTicks;
|
||||
int _fieldF4;
|
||||
int _fieldF8;
|
||||
int _speechTimerId;
|
||||
int _field104;
|
||||
protected:
|
||||
void processInput(CTextInputMsg *msg, CViewItem *view);
|
||||
public:
|
||||
int _speechCounter;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CTrueTalkNPC();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
|
||||
/**
|
||||
* Set the view for the NPC
|
||||
*/
|
||||
void setView(CViewItem *view);
|
||||
|
||||
/**
|
||||
* Start the talker in the given view
|
||||
*/
|
||||
void startTalker(CViewItem *view);
|
||||
|
||||
/**
|
||||
* Perform an action
|
||||
*/
|
||||
void performAction(bool startTalking, CViewItem *view = nullptr);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_TRUE_TALK_NPC_H */
|
||||
Reference in New Issue
Block a user