Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
/* 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_SCRIPT_H
#define TITANIC_BARBOT_SCRIPT_H
#include "titanic/true_talk/tt_npc_script.h"
namespace Titanic {
class BarbotScript : public TTnpcScript {
private:
int _state;
int _arrIndex;
TTsentenceEntries _entries2;
TTupdateStateArray _states;
TTmapEntryArray _preResponses;
private:
/**
* Adjust a given dial number by a given delta amount
*/
void adjustDial(int dialNum, int amount);
/**
* Setup sentence data
*/
void setupSentences();
bool isState9() const;
int applySentenceIds(int dialogueId, int v34 = -1);
/**
* Add a response and optionally set the state
*/
int setResponse(int dialogueId, int state = -1);
public:
BarbotScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4, int v5, int v6, int v7);
/**
* Chooses and adds a conversation response based on a specified tag Id.
*/
int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) override;
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override;
int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
uint tag1, uint tag2, uint remainder) override;
/**
* Returns true if the NPC's dial region affects quote responses
*/
bool isQuoteDialled() const override { return true; }
/**
* Handles updating NPC state based on specified dialogue Ids and dial positions
*/
int updateState(uint oldId, uint newId, int index) override;
/**
* Handles getting a pre-response
*/
int preResponse(uint id) override;
/**
* Returns a bitset of the first three dialgs being on or not
*/
uint getDialsBitset() const override;
/**
* Process a sentence fragment entry
*/
int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Sets a given dial to be pointing in a specified region (0 to 2)
*/
void setDialRegion(int dialNum, int region) override;
};
} // End of namespace Titanic
#endif /* TITANIC_BARBOT_SCRIPT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,125 @@
/* 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_SCRIPT_H
#define TITANIC_BELLBOT_SCRIPT_H
#include "titanic/true_talk/tt_npc_script.h"
namespace Titanic {
class BellbotScript : public TTnpcScript {
private:
static uint _oldId;
TTmapEntryArray _states;
TTmapEntryArray _preResponses;
TTsentenceEntries _sentences[20];
TTcommonPhraseArray _phrases;
int _array[150];
bool _responseFlag;
bool _room107First;
private:
/**
* Setup sentence data
*/
void setupSentences();
/**
* Add the current location to the response
*/
int addLocation();
/**
* Get a dialogue Id based on the state
*/
int getStateDialogueId() const;
/**
* Sets the state value 25 based on the passed Id
*/
void setValue23(uint id);
/**
* Does preprocessing for the sentence
*/
int preprocess(const TTroomScript *roomScript, const TTsentence *sentence);
/**
* Checks for good, better, or bad in the sentence
*/
bool better(const TTsentence *sentence, uint id1, uint id2);
bool randomResponse0(const TTroomScript *roomScript, uint id);
bool randomResponse1(const TTroomScript *roomScript, uint id);
bool randomResponse2(const TTroomScript *roomScript, uint id);
void randomResponse3(const TTroomScript *roomScript, uint id);
void randomResponse4(const TTroomScript *roomScript, uint id);
int checkCommonSentences(const TTroomScript *roomScript, const TTsentence *sentence);
bool checkCommonWords(const TTroomScript *roomScript, const TTsentence *sentence);
uint getRoomDialogueId(const TTroomScript *roomScript);
/**
* Adds a description of the room to the conversation response
*/
bool addRoomDescription(const TTroomScript *roomScript);
public:
BellbotScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2);
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override;
int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
uint tag1, uint tag2, uint remainder) override;
/**
* Handles updating NPC state based on specified dialogue Ids and dial positions
*/
int updateState(uint oldId, uint newId, int index) override;
/**
* Handles getting a pre-response
*/
int preResponse(uint id) override;
/**
* Process a sentence fragment entry
*/
int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Handles a randomzied response
*/
bool randomResponse(uint index) override;
};
} // End of namespace Titanic
#endif /* TITANIC_BELLBOT_SCRIPT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
/* 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_SCRIPT_H
#define TITANIC_DESKBOT_SCRIPT_H
#include "common/array.h"
#include "titanic/true_talk/tt_npc_script.h"
namespace Titanic {
class DeskbotScript : public TTnpcScript {
private:
/**
* Setup sentence data
*/
void setupSentences();
/**
* Adds dialogue for the player's assigned room
*/
uint addAssignedRoomDialogue2();
/**
* Adds dialogue for the player's assigned room
*/
void addAssignedRoomDialogue3();
/**
* Gets a dialogue Id based on the NPC's state
*/
uint getStateDialogueId() const;
/**
* Sets the current state for what the Deskbot is doing/asking
*/
void setCurrentState(uint newId, uint index);
/**
* Scans the quotes tree
*/
int searchQuotes(const TTroomScript *roomScript, const TTsentence *sentence);
/**
* Checks for common words
*/
int checkCommonWords(const TTsentence *sentence);
/**
* Adds a dialogue for asking the player what kind of breakfast they'd like
*/
void addAskBreakfast();
/**
* Adds a dialogue description for the player's assigned room
*/
void addAssignedRoom();
protected:
static int _oldId;
TTupdateStateArray _states;
TTsentenceEntries _entries2;
TTsentenceEntries _entries3;
protected:
/**
* Does preprocessing for the sentence
*/
int preprocess(const TTroomScript *roomScript, const TTsentence *sentence);
/**
* Adds dialogue for the player's assigned room
*/
uint addAssignedRoomDialogue();
public:
DeskbotScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2);
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override;
int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
uint tag1, uint tag2, uint remainder) override;
/**
* Handles updating NPC state based on specified dialogue Ids and dial positions
*/
int updateState(uint oldId, uint newId, int index) override;
/**
* Handles getting a pre-response
*/
int preResponse(uint id) override;
/**
* Returns a bitset of the first three dialgs being on or not
*/
uint getDialsBitset() const override;
/**
* Process a sentence fragment entry
*/
int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Handles a randomzied response
*/
bool randomResponse(uint index) override;
/**
* Returns true if dial 1 is the medium (1) region
*/
virtual bool isDial0Medium() const;
/**
* Returns true if dial 0 is the low end region
*/
virtual bool isDial0Low() const;
/**
* Returns true if dial 1 is the medium (1) region
*/
bool isDial1Medium() const;
/**
* Returns true if dial 1 is the low end region
*/
virtual bool isDial1Low() const;
};
} // End of namespace Titanic
#endif /* TITANIC_DESKBOT_SCRIPT_H */

View File

@@ -0,0 +1,108 @@
/* 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/true_talk/dialogue_file.h"
namespace Titanic {
void DialogueIndexEntry::load(Common::SeekableReadStream &s) {
_v1 = s.readUint32LE();
_offset = s.readUint32LE();
}
/*------------------------------------------------------------------------*/
CDialogueFile::CDialogueFile(const CString &filename, uint count) {
if (!_file.open(Common::Path(filename)))
error("Could not locate dialogue file - %s", filename.c_str());
_cache.resize(count);
_file.readUint32LE(); // Skip over file Id
_index.resize(_file.readUint32LE());
// Read in the entries
for (uint idx = 0; idx < _index.size(); ++idx)
_index[idx].load(_file);
}
CDialogueFile::~CDialogueFile() {
clear();
}
void CDialogueFile::clear() {
_file.close();
}
DialogueResource *CDialogueFile::addToCache(int index) {
if (_index.size() == 0 || index < 0 || index >= (int)_index.size()
|| _cache.empty())
return nullptr;
// Scan cache for a free slot
uint cacheIndex = 0;
while (cacheIndex < _cache.size() && _cache[cacheIndex]._active)
++cacheIndex;
if (cacheIndex == _cache.size())
return nullptr;
DialogueIndexEntry &indexEntry = _index[index];
DialogueResource &res = _cache[cacheIndex];
res._active = true;
res._offset = indexEntry._offset;
res._bytesRead = 0;
res._entryPtr = &indexEntry;
// Figure out the size of the entry
if (index == ((int)_index.size() - 1)) {
res._size = _file.size() - indexEntry._offset;
} else {
res._size = _index[index + 1]._offset - indexEntry._offset;
}
// Return a pointer to the loaded entry
return &res;
}
bool CDialogueFile::closeEntry(DialogueResource *cacheEntry) {
if (!cacheEntry || !cacheEntry->_active)
return false;
cacheEntry->_active = false;
return true;
}
bool CDialogueFile::read(DialogueResource *cacheEntry, byte *buffer, size_t bytesToRead) {
// Sanity checks that a valid record is passed, and the size can be read
if (!cacheEntry || !cacheEntry->_active || !bytesToRead
|| (cacheEntry->_bytesRead + bytesToRead) > cacheEntry->_size)
return false;
// Move to the correct position in the file
_file.seek(cacheEntry->_offset + cacheEntry->_bytesRead);
bool result = _file.read(buffer, bytesToRead) == bytesToRead;
cacheEntry->_bytesRead += bytesToRead;
return result;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,99 @@
/* 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_DIALOGUE_FILE_H
#define TITANIC_DIALOGUE_FILE_H
#include "titanic/support/simple_file.h"
#include "titanic/support/string.h"
namespace Titanic {
struct DialogueIndexEntry {
uint _v1, _offset;
DialogueIndexEntry() : _v1(0), _offset(0) {}
void load(Common::SeekableReadStream &s);
};
struct DialogueResource {
bool _active;
uint _offset, _bytesRead, _size;
DialogueIndexEntry *_entryPtr;
DialogueResource() : _active(false), _offset(0),
_bytesRead(0), _size(0), _entryPtr(nullptr) {}
/**
* Return the size of a cache entry
*/
size_t size() const { return _active ? _size : 0; }
};
class CDialogueFile {
private:
File _file;
Common::Array<DialogueIndexEntry> _index;
Common::Array<DialogueResource> _cache;
private:
/**
* Add a dialogue file entry to the active cache
*/
DialogueResource *addToCache(int index);
public:
CDialogueFile(const CString &filename, uint count);
~CDialogueFile();
/**
* Clear the loaded data
*/
void clear();
File *getFile() { return &_file; }
/**
* Sets up a text entry within the dialogue file for access
*/
DialogueResource *openTextEntry(int index) {
return addToCache(index * 2);
}
/**
* Sets up a wave (sound) entry within the dialogue file for access
*/
DialogueResource *openWaveEntry(int index) {
return addToCache(index * 2 + 1);
}
/**
* Removes an entry from the cache
*/
bool closeEntry(DialogueResource *cacheEntry);
/**
* Read data for a resource
*/
bool read(DialogueResource *cacheEntry, byte *buffer, size_t bytesToRead);
};
} // End of namespace Titanic
#endif /* TITANIC_TITLE_ENGINE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
/* 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_SCRIPT_H
#define TITANIC_DOORBOT_SCRIPT_H
#include "common/hashmap.h"
#include "titanic/true_talk/tt_npc_script.h"
namespace Titanic {
class DoorbotScript : public TTnpcScript {
typedef Common::HashMap<uint, TTsentenceEntries> SentenceEntriesMap;
private:
TTupdateStateArray _states;
SentenceEntriesMap _sentences;
int _stateIndex;
int _doorbotState;
private:
/**
* Setup sentence data
*/
void setupSentences();
/**
* Sets a response
*/
int setResponse(int dialogueId, int v34 = -1);
/**
* Gets the dialogue Id for a given room
*/
int getRoomDialogueId1(const TTroomScript *roomScript);
/**
* Gets the dialogue Id for a given room
*/
int getRoomDialogueId2(const TTroomScript *roomScript);
public:
DoorbotScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4, int v5, int v6, int v7);
~DoorbotScript() override;
/**
* Chooses and adds a conversation response based on a specified tag Id.
*/
int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) override;
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override;
int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
uint tag1, uint tag2, uint remainder) override;
/**
* Returns true if the NPC's dial region affects quote responses
*/
bool isQuoteDialled() const override { return true; }
/**
* Handles updating NPC state based on specified dialogue Ids and dial positions
*/
int updateState(uint oldId, uint newId, int index) override;
/**
* Handles getting a pre-response
*/
int preResponse(uint id) override;
/**
* Returns a bitset of the dials being off or not
*/
uint getDialsBitset() const override;
/**
* Process a sentence fragment entry
*/
int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Sets a given dial to be pointing in a specified region (0 to 2)
*/
void setDialRegion(int dialNum, int region) override;
/**
* Handles a randomzied response
*/
bool randomResponse(uint index) override;
};
} // End of namespace Titanic
#endif /* TITANIC_DOORBOT_SCRIPT_H */

View File

@@ -0,0 +1,723 @@
/* 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 "common/textconsole.h"
#include "titanic/true_talk/liftbot_script.h"
#include "titanic/true_talk/true_talk_manager.h"
#include "titanic/titanic.h"
#include "titanic/translation.h"
namespace Titanic {
int LiftbotScript::_stateIndex;
static const int STATE_ARRAY_EN[7] = {
30910, 30912, 30913, 30914, 30915, 30916, 30917
};
static const int STATE_ARRAY_DE[7] = {
30919, 30921, 30922, 30923, 30924, 30925, 30926
};
LiftbotScript::LiftbotScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) :
TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7) {
_stateIndex = 0;
loadRanges("Ranges/Liftbot");
loadResponses("Responses/Liftbot");
setupSentences();
_tagMappings.load("TagMap/Liftbot");
_words.load("Words/Liftbot");
_quotes.load("Quotes/Liftbot");
_states.load("States/Liftbot");
}
void LiftbotScript::setupSentences() {
CTrueTalkManager::setFlags(27, 0);
setupDials(getRandomNumber(40) + 60, getRandomNumber(40) + 60, 0);
_mappings.load("Mappings/Liftbot", 4);
_entries.load("Sentences/Liftbot");
_field68 = 0;
_entryCount = 0;
}
int LiftbotScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) {
switch (tag) {
case MKTAG('D', 'N', 'A', '1'):
case MKTAG('H', 'H', 'G', 'Q'):
case MKTAG('A', 'N', 'S', 'W'):
if (_stateIndex >= 7) {
selectResponse(TRANSLATE(30918, 30927));
setState(2);
_stateIndex = 0;
} else {
addResponse(TRANSLATE(STATE_ARRAY_EN[_stateIndex++],
STATE_ARRAY_DE[_stateIndex++]));
}
applyResponse();
return 2;
case MKTAG('O', 'R', 'D', '8'):
addResponse(TRANSLATE(30475, 30484));
addResponse(TRANSLATE(30467, 30476));
addResponse(TRANSLATE(30466, 30475));
addResponse(TRANSLATE(30474, 30483));
applyResponse();
return SS_2;
default:
return TTnpcScript::chooseResponse(roomScript, sentence, tag);
}
}
int LiftbotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) {
if (roomScript->_scriptId != 103)
return 2;
checkItems(roomScript, sentence);
int currState = getState();
int sentMode = sentence->_category;
TTtreeResult treeResult[32];
if (currState) {
setState(0);
bool flag1 = sentMode == 11 || sentMode == 13;
bool flag2 = sentMode == 12;
switch (currState) {
case 2:
if (flag1)
return addDialogueAndState(TRANSLATE(30920, 30929), 3);
if (flag2)
return addDialogueAndState(TRANSLATE(30919, 30928), 1);
break;
case 3:
if (flag1)
return addDialogueAndState(TRANSLATE(30919, 30928), 1);
break;
case 4:
return addDialogueAndState(getDialogueId(210391), 1);
case 5:
if (sentence->contains("reborzo") || sentence->contains("is that"))
return addDialogueAndState(TRANSLATE(30515, 30524), 1);
break;
case 6:
if (sentMode == 6)
return addDialogueAndState(getDialogueId(210771), 1);
break;
case 7:
case 8:
if (sentMode == 6 || sentMode == 10)
return addDialogueAndState(getDialogueId(210099), 1);
break;
case 9:
if (sentMode == 10 || g_vm->_trueTalkManager->_quotesTree.search(
sentence->_normalizedLine.c_str(), TREE_2, &treeResult[0], 0, 0) != -1)
return addDialogueAndState(getDialogueId(210970), 9);
break;
default:
break;
}
}
updateCurrentDial(true);
if (processEntries(&_entries, _entryCount, roomScript, sentence) == 2)
return 2;
if (sentence->localWord("injury") || sentence->localWord("illness")) {
addResponse(getDialogueId(210059));
applyResponse();
} else if (processEntries(_defaultEntries, 0, roomScript, sentence) != 2
&& !defaultProcess(roomScript, sentence)
&& !sentence1(sentence)) {
if (getDialRegion(1) != 0 && getRandomNumber(100) <= 20) {
addResponse(getDialogueId(210906));
addResponse(getDialogueId(210901));
} else {
addResponse(getDialogueId(210590));
}
applyResponse();
}
return 2;
}
ScriptChangedResult LiftbotScript::scriptChanged(uint id) {
return scriptChanged(nullptr, id);
}
ScriptChangedResult LiftbotScript::scriptChanged(const TTroomScript *roomScript, uint id) {
switch (id) {
case 3:
if (getValue(27) == 0) {
addResponse(getDialogueId(210018));
} else if (getStateValue()) {
addResponse(getDialogueId(210682));
} else {
addResponse(getDialogueId(210033));
}
CTrueTalkManager::setFlags(27, 1);
applyResponse();
break;
case 155:
selectResponse(TRANSLATE(30446, 30455));
applyResponse();
break;
case 156:
if (getCurrentFloor() == 1) {
addResponse(getDialogueId(210614));
} else {
selectResponse(TRANSLATE(30270, 30272));
}
applyResponse();
break;
default:
break;
}
if (id >= 210000 && id <= (uint)TRANSLATE(211001, 211003)) {
addResponse(getDialogueId(id));
applyResponse();
}
return SCR_2;
}
int LiftbotScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
uint tag1, uint tag2, uint remainder) {
switch (tag2) {
case MKTAG('A', 'D', 'V', 'T'):
case MKTAG('A', 'R', 'T', 'I'):
case MKTAG('A', 'R', 'T', 'Y'):
case MKTAG('B', 'R', 'N', 'D'):
case MKTAG('C', 'O', 'M', 'D'):
case MKTAG('D', 'N', 'C', 'E'):
case MKTAG('H', 'B', 'B', 'Y'):
case MKTAG('L', 'I', 'T', 'R'):
case MKTAG('M', 'A', 'G', 'S'):
case MKTAG('M', 'C', 'P', 'Y'):
case MKTAG('M', 'I', 'N', 'S'):
case MKTAG('M', 'U', 'S', 'I'):
case MKTAG('N', 'I', 'K', 'E'):
case MKTAG('S', 'F', 'S', 'F'):
case MKTAG('S', 'O', 'A', 'P'):
case MKTAG('S', 'O', 'N', 'G'):
case MKTAG('S', 'P', 'R', 'T'):
case MKTAG('T', 'E', 'A', 'M'):
case MKTAG('T', 'V', 'S', 'H'):
case MKTAG('W', 'W', 'E', 'B'):
tag2 = MKTAG('E', 'N', 'T', 'N');
break;
case MKTAG('A', 'C', 'T', 'R'):
case MKTAG('A', 'C', 'T', 'S'):
case MKTAG('A', 'U', 'T', 'H'):
case MKTAG('B', 'A', 'R', 'K'):
case MKTAG('B', 'A', 'R', 'U'):
case MKTAG('B', 'L', 'F', '1'):
case MKTAG('B', 'L', 'F', '2'):
case MKTAG('B', 'L', 'R', '1'):
case MKTAG('B', 'L', 'R', '2'):
case MKTAG('B', 'L', 'P', '1'):
case MKTAG('B', 'L', 'P', '2'):
case MKTAG('B', 'L', 'P', '3'):
case MKTAG('B', 'L', 'P', '4'):
case MKTAG('B', 'L', 'T', '1'):
case MKTAG('B', 'L', 'T', '2'):
case MKTAG('B', 'L', 'T', '3'):
case MKTAG('B', 'L', 'T', '4'):
case MKTAG('B', 'L', 'T', '5'):
case MKTAG('B', 'O', 'Y', 'S'):
case MKTAG('C', 'O', 'P', 'S'):
case MKTAG('D', 'C', 'T', 'R'):
case MKTAG('F', 'A', 'M', 'E'):
case MKTAG('F', 'A', 'S', 'H'):
case MKTAG('G', 'I', 'R', 'L'):
case MKTAG('H', 'E', 'R', 'O'):
case MKTAG('H', 'O', 'S', 'T'):
case MKTAG('K', 'N', 'O', 'B'):
case MKTAG('N', 'H', 'R', 'O'):
case MKTAG('R', 'A', 'C', 'E'):
case MKTAG('S', 'C', 'I', 'T'):
case MKTAG('T', 'D', 'V', 'P'):
case MKTAG('T', 'W', 'A', 'T'):
case MKTAG('W', 'E', 'A', 'T'):
tag2 = MKTAG('P', 'R', 'S', 'N');
break;
case MKTAG('C', 'H', 'S', 'E'):
case MKTAG('C', 'M', 'N', 'T'):
case MKTAG('F', 'I', 'L', 'M'):
case MKTAG('J', 'F', 'O', 'D'):
case MKTAG('L', 'I', 'Q', 'D'):
tag2 = MKTAG('F', 'O', 'O', 'D');
break;
case MKTAG('C', 'R', 'I', 'M'):
case MKTAG('C', 'S', 'P', 'Y'):
case MKTAG('D', 'R', 'U', 'G'):
tag2 = MKTAG('V', 'B', 'A', 'D');
break;
case MKTAG('E', 'A', 'R', 'T'):
case MKTAG('H', 'O', 'M', 'E'):
case MKTAG('N', 'P', 'L', 'C'):
case MKTAG('P', 'L', 'A', 'N'):
tag2 = MKTAG('P', 'L', 'A', 'C');
break;
case MKTAG('F', 'A', 'U', 'N'):
case MKTAG('F', 'I', 'S', 'H'):
case MKTAG('F', 'L', 'O', 'R'):
tag2 = MKTAG('N', 'A', 'T', 'R');
break;
case MKTAG('H', 'H', 'L', 'D'):
case MKTAG('T', 'O', 'Y', 'S'):
case MKTAG('W', 'E', 'A', 'P'):
tag2 = MKTAG('M', 'A', 'C', 'H');
break;
case MKTAG('M', 'L', 'T', 'Y'):
case MKTAG('P', 'G', 'R', 'P'):
case MKTAG('P', 'T', 'I', 'C'):
tag2 = MKTAG('G', 'R', 'U', 'P');
break;
case MKTAG('P', 'K', 'U', 'P'):
case MKTAG('S', 'E', 'X', '1'):
case MKTAG('S', 'W', 'E', 'R'):
tag2 = MKTAG('R', 'U', 'D', 'E');
break;
case MKTAG('P', 'H', 'I', 'L'):
case MKTAG('R', 'C', 'K', 'T'):
tag2 = MKTAG('S', 'C', 'I', 'E');
break;
case MKTAG('T', 'R', 'A', '2'):
case MKTAG('T', 'R', 'A', '3'):
tag2 = MKTAG('T', 'R', 'A', 'V');
break;
default:
break;
}
return TTnpcScript::handleQuote(roomScript, sentence, tag1, tag2, remainder);
}
int LiftbotScript::updateState(uint oldId, uint newId, int index) {
for (uint idx = 0; idx < _states.size(); ++idx) {
TTmapEntry &us = _states[idx];
if (us._src == newId) {
setState(us._dest);
break;
}
}
return newId;
}
int LiftbotScript::preResponse(uint id) {
if (id == (uint)TRANSLATE(30565, 30574)
|| id == (uint)TRANSLATE(30566, 30575)
|| id == (uint)TRANSLATE(30567, 30576)
|| id == (uint)TRANSLATE(30568, 30577)
|| id == (uint)TRANSLATE(30569, 30578)
|| id == (uint)TRANSLATE(30570, 30579)
|| id == (uint)TRANSLATE(30571, 30580))
return 210901;
if (getDialRegion(0) == 0 && getRandomNumber(100) > 60)
return 210830;
return 0;
}
uint LiftbotScript::getDialsBitset() const {
uint bits = 0;
if (!getDialRegion(1))
bits = 1;
if (!getDialRegion(0))
bits |= 2;
if (bits > 1)
bits ^= 1;
return bits;
}
int LiftbotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) {
// Responses for each floor when asked "what floor are we on"
static const int FLOOR_RESPONSE_IDS[] = {
0, 210724, 210735, 210746, 210757, 210758, 210759, 210760,
210761, 210762, 210725, 210726, 210727, 210728, 210729,
210730, 210731, 210732, 210733, 210734, 210736, 210737,
210738, 210739, 210740, 210741, 210742, 210743, 210744,
210745, 210747, 210748, 210749, 210750, 210751, 210752,
210753, 210754, 210755, 210756
};
// Responses for each lift when asked "which lift am I in"
static const int LIFT_RESPONSE_IDS[] = {
0, 210849, 210850, 210851, 210852, 210838, 210839, 210840, 210841, 0
};
getState();
int stateVal;
int state = (g_language == Common::DE_DEU && val1 > 3000 && val1 < 3020)
? val1 - 3000 : val1;
switch (state) {
case 1:
if (getValue(1) != 1)
return 1;
break;
case 2:
if (getValue(1) != 2)
return 1;
break;
case 3:
if (getValue(1) != 3)
return 1;
break;
case 4:
case 5:
return !sentence1(sentence);
case 6:
if (sentence->localWord("big") || sentence->localWord("small")) {
addResponse(getDialogueId(210215));
applyResponse();
} else if (sentence->localWord("my") || sentence->contains("my")
|| sentence->contains("bedroom") || sentence->contains("state")
|| sentence->contains("mein") || sentence->contains("schlafzimmer")) {
addResponse1(CTrueTalkManager::getStateValue(4), true, 0);
} else {
selectResponse(210763);
applyResponse();
}
return 2;
case 7:
if (!sentence->localWord("ill") && !sentence->localWord("well"))
return 1;
break;
case 8:
if (!sentence->localWord("long"))
return 1;
break;
case 9:
if (addResponse1(1, false, 0))
return 2;
break;
case 10:
if (addResponse1(39, false, 0))
return 2;
break;
case 11:
if (getState6() == 2 || getState6() == 4)
return 1;
break;
case 12:
if (getState6() == 1 || getState6() == 3)
return 1;
break;
case 13:
// What floor am I on
selectResponse(FLOOR_RESPONSE_IDS[getCurrentFloor()]);
applyResponse();
return 2;
case 14:
// Which lift am I in
stateVal = getState6();
if (g_language == Common::EN_ANY) {
if (sentence->contains("elevator") ||
(!sentence->contains("lift") && getRandomNumber(100) > 60))
stateVal += 4;
}
selectResponse(LIFT_RESPONSE_IDS[stateVal]);
applyResponse();
return 2;
case 15:
if (getRandomNumber(100) > 60) {
addResponse(getDialogueId(210440));
} else {
addResponse(getDialogueId(210906));
addResponse(getDialogueId(210901));
}
applyResponse();
return 2;
case 16:
if (g_language == Common::DE_DEU)
addResponse(30589);
else if (sentence->contains("elevator") || sentence->contains("elavator"))
addResponse(30579);
else
addResponse(30580);
applyResponse();
return 2;
case 17:
if (sentence->localWord("restaurant") || sentence->contains("restaurant"))
return 1;
break;
default:
break;
}
return 0;
}
void LiftbotScript::setDialRegion(int dialNum, int region) {
TTnpcScript::setDialRegion(dialNum, region);
addResponse(getDialogueId(210688));
applyResponse();
}
int LiftbotScript::getCurrentFloor() const {
int val = CTrueTalkManager::getStateValue(5);
return CLIP(val, 1, 39);
}
int LiftbotScript::getState6() const {
int val = CTrueTalkManager::getStateValue(6);
return (val < 1 || val > 4) ? 1 : val;
}
int LiftbotScript::addDialogueAndState(int id, int state) {
addResponse(id);
applyResponse();
if (state != 1)
setState(state);
return 2;
}
int LiftbotScript::addResponse1(int index, bool flag, int id) {
static const int DIALOGUE_IDS[37] = {
210735, 210746, 210757, 210758, 210759, 210760, 210761, 210762,
210725, 210726, 210727, 210728, 210729, 210730, 210731, 210732,
210733, 210734, 210736, 210737, 210738, 210739, 210740, 210741,
210742, 210743, 210744, 210745, 210747, 210748, 210749, 210750,
210751, 210752, 210753, 210754, 210755
};
int stateVal = getState6();
int maxIndex = (stateVal == 2 || stateVal == 4) ? 27 : 39;
if (index < 1 || index > maxIndex) {
addResponse(getDialogueId(maxIndex == 27 ? 210587 : 210586));
applyResponse();
return 1;
} else if (index == getCurrentFloor()) {
if (index == 1) {
addResponse(TRANSLATE(30558 - (getRandomBit() ? 290 : 0),
30567 - (getRandomBit() ? 297 : 0)));
addResponse(getDialogueId(210589));
} else {
if (index == 39)
addResponse(TRANSLATE(30346, 30348));
addResponse(getDialogueId(210589));
}
applyResponse();
return 2;
}
stateVal = getValue(1);
if (index >= 2 && index <= 19 && stateVal > 1) {
addResponse(getDialogueId(210203));
applyResponse();
setState(7);
return true;
}
if (index >= 20 && index <= 27 && stateVal > 2) {
addResponse(getDialogueId(210210));
applyResponse();
setState(8);
return true;
}
if (flag) {
if (index == 1) {
selectResponse(TRANSLATE(30558 - (getRandomBit() ? 290 : 0),
30567 - (getRandomBit() ? 297 : 0)));
} else if (index == 39) {
addResponse(TRANSLATE(30346, 30348));
} else {
if (getRandomNumber(100) > 35 && index >= 2 && index <= 38) {
addResponse(getDialogueId(DIALOGUE_IDS[index - 2]));
}
addResponse(getDialogueId(210588));
}
if (id) {
if (id == 210717 || id == 210716 || id == 210719 || id == 210718) {
addResponse(getDialogueId(210720));
addResponse(getDialogueId(id));
addResponse(getDialogueId(210715));
} else {
addResponse(getDialogueId(id));
}
}
applyResponse();
}
CTrueTalkManager::triggerAction(2, index);
return flag;
}
int LiftbotScript::sentence1(const TTsentence *sentence) {
if (CTrueTalkManager::_v1 >= 0) {
if (sentence->localWord("room")) {
addResponse1(getStateValue(), true, 0);
} else if (CTrueTalkManager::_v1 >= 1 && CTrueTalkManager::_v1 <= 39) {
if (CTrueTalkManager::_v1 != 1 || !sentence->localWord("floor")) {
addResponse1(CTrueTalkManager::_v1, true, 0);
} else if (sentence->localWord("up") || sentence->localWord("above")) {
addResponse1(getCurrentFloor() - 1, true, 0);
} else if (sentence->localWord("down") || sentence->localWord("below")) {
addResponse1(getCurrentFloor() + 1, true, 0);
} else {
addResponse1(CTrueTalkManager::_v1, true, 0);
}
}
return 1;
}
PassengerClass classNum = FIRST_CLASS;
bool classSet = true;
if (sentence->localWord("firstclass"))
classNum = FIRST_CLASS;
else if (sentence->localWord("secondclass"))
classNum = SECOND_CLASS;
else if (sentence->localWord("thirdclass"))
classNum = THIRD_CLASS;
else
classSet = false;
uint newId = 0;
int diff = 1;
if (sentence->localWord("promenade")) {
newId = 210718;
} else if (sentence->localWord("bar")) {
newId = 210894 - (getRandomBit() ? 178 : 0);
} else if (sentence->localWord("musicroom")) {
newId = 210897 - (getRandomBit() ? 180 : 0);
} else if (sentence->localWord("creatorroom")) {
newId = 210713;
} else if (sentence->localWord("sculpture") || sentence->localWord("sculptureroom")) {
newId = 210722;
} else if (sentence->localWord("embarklobby")) {
newId = 210714;
} else if (sentence->localWord("parrotlobby")) {
newId = 210721;
} else if (sentence->localWord("arboretum")) {
newId = 210711;
} else if (sentence->localWord("canal")) {
newId = 210896;
} else if (sentence->localWord("bar")) {
newId = 210894;
} else if (sentence->localWord("bilgeroom")) {
newId = 210895;
} else if (sentence->localWord("titaniaroom")) {
newId = 210723;
} else if (sentence->localWord("restaurant")) {
if (classNum == FIRST_CLASS) {
newId = 210719;
diff = 1;
} else {
newId = 210898;
diff = -98;
}
} else if (sentence->localWord("topwell") || sentence->localWord("servicelift")
|| sentence->localWord("bridge") || sentence->localWord("dome")
|| sentence->localWord("pellerator") || sentence->localWord("top")) {
diff = 1;
} else {
diff = -100;
}
if (g_language == Common::EN_ANY && sentence->localWord("lobby"))
diff = (getValue(1) == 0 ? 1 : 0) - 99;
if (sentence->localWord("bottomofwell") || sentence->contains("bottom"))
diff = 39;
if (diff == -99 || (diff == -100 && classSet)) {
if (classNum == 1)
addResponse(getDialogueId(210235));
else if (classNum == 2)
addResponse(getDialogueId(210241));
else
addResponse(getDialogueId(210242));
applyResponse();
return 1;
}
if (sentence->_category == 4 || sentence->localWord("find")
|| sentence->contains("get to")
|| sentence->contains("komme ich")
|| sentence->contains("ich will zum")
|| sentence->contains("ich will zur")
|| sentence->contains("ich will ins")
|| sentence->contains("ich will in")) {
if (getCurrentFloor() != diff) {
selectResponse(diff == 1 ? 210769 : 210764);
} else if (!newId) {
selectResponse(210764);
} else if (newId > 210715 && newId <= 210719) {
addResponse(getDialogueId(210720));
selectResponse(getDialogueId(newId));
selectResponse(210715);
} else {
selectResponse(newId);
}
applyResponse();
return 1;
}
if (diff == -98) {
addResponse1(getStateValue(), true, newId);
return 1;
} else if (diff >= 0) {
addResponse1(diff, true, newId);
return 1;
} else if (sentence->localWord("up") || sentence->localWord("ascend")) {
selectResponse(210128);
applyResponse();
return 1;
} else if (sentence->localWord("down") || sentence->localWord("descend")) {
selectResponse(210138);
applyResponse();
return 1;
} else if (diff >= 0) {
addResponse1(diff, true, newId);
return 1;
} else {
return 0;
}
}
} // End of namespace Titanic

View File

@@ -0,0 +1,108 @@
/* 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_SCRIPT_H
#define TITANIC_LIFTBOT_SCRIPT_H
#include "titanic/true_talk/tt_npc_script.h"
namespace Titanic {
class LiftbotScript : public TTnpcScript {
private:
TTmapEntryArray _states;
static int _stateIndex;
private:
/**
* Setup sentence data
*/
void setupSentences();
int addResponse1(int mode, bool flag, int id);
int sentence1(const TTsentence *sentence);
/**
* Gets the current floor
*/
int getCurrentFloor() const;
int getState6() const;
/**
* Adds a dialogue response and sets the state
*/
int addDialogueAndState(int id, int state);
public:
LiftbotScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4, int v5, int v6, int v7);
/**
* Chooses and adds a conversation response based on a specified tag Id.
*/
int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) override;
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(uint id) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override;
int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
uint tag1, uint tag2, uint remainder) override;
/**
* Handles updating NPC state based on specified dialogue Ids and dial positions
*/
int updateState(uint oldId, uint newId, int index) override;
/**
* Handles getting a pre-response
*/
int preResponse(uint id) override;
/**
* Returns a bitset of the dials being off or not
*/
uint getDialsBitset() const override;
/**
* Process a sentence fragment entry
*/
int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Sets a given dial to be pointing in a specified region (0 to 2)
*/
void setDialRegion(int dialNum, int region) override;
};
} // End of namespace Titanic
#endif /* TITANIC_LIFTBOT_SCRIPT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
/* 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_SCRIPT_H
#define TITANIC_MAITRED_SCRIPT_H
#include "titanic/true_talk/tt_npc_script.h"
namespace Titanic {
class MaitreDScript : public TTnpcScript {
private:
TTmapEntryArray _states;
TTsentenceEntries _sentences1;
int _answerCtr;
private:
/**
* Setup sentence data
*/
void setupSentences();
/**
* Alter dialogue Id based on current NPC state
*/
uint getStateDialogueId(uint oldId, uint newId);
/**
* Starts the MaitreD fighting, if he isn't already
*/
void startFighting();
/**
* Stops the MaitreD fighting
*/
void stopFighting(bool flag);
/**
* Sets flags 10 to different values based on the passed
* dialogue Id
*/
void setFlags10(uint newId, uint index);
/**
* Does preprocessing for the sentence
*/
int preprocess(const TTroomScript *roomScript, const TTsentence *sentence);
public:
MaitreDScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2);
/**
* Chooses and adds a conversation response based on a specified tag Id.
*/
int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) override;
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override;
int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
uint tag1, uint tag2, uint remainder) override;
/**
* Handles updating NPC state based on specified dialogue Ids and dial positions
*/
int updateState(uint oldId, uint newId, int index) override;
/**
* Handles getting a pre-response
*/
int preResponse(uint id) override;
};
} // End of namespace Titanic
#endif /* TITANIC_MAITRED_SCRIPT_H */

View File

@@ -0,0 +1,110 @@
/* 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/true_talk/parrot_script.h"
#include "titanic/true_talk/true_talk_manager.h"
#include "titanic/titanic.h"
#include "common/textconsole.h"
namespace Titanic {
ParrotScript::ParrotScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) :
TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7) {
loadRanges("Ranges/Parrot");
setupSentences();
}
void ParrotScript::setupSentences() {
_mappings.load("Mappings/Parrot", 1);
_entries.load("Sentences/Parrot");
_field68 = 0;
_entryCount = 0;
}
int ParrotScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) {
if (tag == MKTAG('B', 'Y', 'Z', 'A')) {
addResponse(getDialogueId(280246));
applyResponse();
return 2;
} else {
return 1;
}
}
int ParrotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) {
if (processEntries(roomScript, sentence) != 2) {
int tagId = g_vm->_trueTalkManager->_quotes.find(sentence->_normalizedLine);
if (!tagId || chooseResponse(roomScript, sentence, tagId) != 2) {
addResponse(getDialogueId(sentence->checkCategory() ? 280248 : 280235));
applyResponse();
}
}
return 2;
}
ScriptChangedResult ParrotScript::scriptChanged(const TTroomScript *roomScript, uint id) {
if (id >= 280000 && id <= 280276) {
if (id == 280258) {
if (CTrueTalkManager::_currentNPC) {
CGameObject *chicken;
if (CTrueTalkManager::_currentNPC->find("Chicken", &chicken, FIND_PET))
id = 280147 - getRandomBit();
}
id = getDialogueId(id);
} else {
if ((id == 280146 || id == 280147) && CTrueTalkManager::_currentNPC) {
CGameObject *chicken;
if (!CTrueTalkManager::_currentNPC->find("Chicken", &chicken, FIND_PET))
id = 280142;
}
addResponse(getDialogueId(id));
if (id == 280192)
addResponse(getDialogueId(280222));
applyResponse();
}
}
if (id >= 80000 && id <= 80244) {
if ((id == 80155 || id == 80156) && CTrueTalkManager::_currentNPC) {
CGameObject *chicken;
if (!CTrueTalkManager::_currentNPC->find("Chicken", &chicken, FIND_PET))
id = 80151;
}
addResponse(id);
if (id == 80201)
addResponse(getDialogueId(280222));
applyResponse();
}
return (id == 3) ? SCR_2 : SCR_1;
}
int ParrotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) {
return 0;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,62 @@
/* 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_SCRIPT_H
#define TITANIC_PARROT_SCRIPT_H
#include "titanic/true_talk/tt_npc_script.h"
namespace Titanic {
class ParrotScript : public TTnpcScript {
private:
/**
* Setup sentence data
*/
void setupSentences();
public:
ParrotScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4, int v5, int v6, int v7);
/**
* Chooses and adds a conversation response based on a specified tag Id.
*/
int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) override;
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override;
/**
* Process a sentence fragment entry
*/
int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) override;
};
} // End of namespace Titanic
#endif /* TITANIC_PARROT_SCRIPT_H */

View File

@@ -0,0 +1,145 @@
/* 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/true_talk/script_handler.h"
#include "titanic/true_talk/title_engine.h"
#include "titanic/true_talk/tt_concept.h"
#include "titanic/true_talk/tt_parser.h"
#include "titanic/true_talk/tt_sentence.h"
#include "titanic/true_talk/tt_word.h"
#include "titanic/titanic.h"
namespace Titanic {
/*------------------------------------------------------------------------*/
CScriptHandler::CScriptHandler(CTitleEngine *owner, int val1, VocabMode vocabMode) :
_owner(owner), _script(owner->_script), _parser(this), _inputCtr(0), _concept1P(nullptr),
_concept2P(nullptr), _concept3P(nullptr), _concept4P(nullptr) {
g_vm->_scriptHandler = this;
g_vm->_script = _script;
g_vm->_exeResources.reset(this, val1, vocabMode);
_vocab = new TTvocab(vocabMode);
}
CScriptHandler::~CScriptHandler() {
delete _vocab;
delete _concept1P;
delete _concept2P;
delete _concept3P;
delete _concept4P;
}
ScriptChangedResult CScriptHandler::scriptChanged(TTroomScript *roomScript, TTnpcScript *npcScript, uint dialogueId) {
if (!npcScript || !roomScript) {
++_inputCtr;
return SCR_5;
}
ScriptChangedResult result = roomScript->notifyScript(npcScript, dialogueId);
if (result == SCR_1)
result = npcScript->notifyScript(roomScript, dialogueId);
if (dialogueId == 3 || dialogueId == 4) {
delete _concept1P;
delete _concept2P;
delete _concept3P;
delete _concept4P;
_concept1P = nullptr;
_concept2P = nullptr;
_concept3P = nullptr;
_concept4P = nullptr;
}
++_inputCtr;
return result;
}
int CScriptHandler::processInput(TTroomScript *roomScript, TTnpcScript *npcScript,
const TTstring &line) {
if (!roomScript || !line.isValid())
return SS_5;
TTsentence *sentence = new TTsentence(_inputCtr++, line, this, roomScript, npcScript);
int result = _parser.preprocess(sentence);
roomScript->scriptPreprocess(sentence);
npcScript->scriptPreprocess(sentence);
int canProcess = 0;
if (result) {
sentence->setState(result);
if (roomScript->canRespond(npcScript, sentence, result)) {
canProcess = npcScript->chooseResponse(roomScript, sentence, result);
}
}
if (canProcess == 0 || canProcess == 1) {
if (!_parser.findFrames(sentence)) {
if (roomScript->canProcess(npcScript, sentence) && npcScript) {
npcScript->process(roomScript, sentence);
}
}
}
delete sentence;
return SS_VALID;
}
SimpleFile *CScriptHandler::openResource(const CString &name) {
return _owner->open(name);
}
void CScriptHandler::setParserConcept(TTconcept *newConcept, TTconcept *oldConcept) {
_parser.conceptChanged(newConcept, oldConcept);
}
int CScriptHandler::setResponse(TTscriptBase *script, TTresponse *response) {
return _owner->setResponse(script, response);
}
void CScriptHandler::handleWord(const TTstring *str) {
handleWord1(str);
handleWord2(str);
}
void CScriptHandler::handleWord1(const TTstring *str) {
if (_concept2P)
delete _concept2P;
_concept2P = nullptr;
if (str) {
TTword word(*str, WC_UNKNOWN, 0);
_concept2P = new TTconcept(&word);
}
}
void CScriptHandler::handleWord2(const TTstring *str) {
if (_concept1P)
delete _concept1P;
_concept1P = nullptr;
if (str) {
TTword word(*str, WC_UNKNOWN, 0);
_concept1P = new TTconcept(&word);
}
}
} // End of namespace Titanic

View File

@@ -0,0 +1,84 @@
/* 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_SCRIPT_HANDLER_H
#define TITANIC_SCRIPT_HANDLER_H
#include "titanic/true_talk/tt_npc_script.h"
#include "titanic/true_talk/tt_parser.h"
#include "titanic/true_talk/tt_room_script.h"
#include "titanic/true_talk/tt_string.h"
#include "titanic/true_talk/tt_vocab.h"
#include "titanic/support/exe_resources.h"
namespace Titanic {
class CTitleEngine;
class CScriptHandler {
private:
CTitleEngine *_owner;
int _inputCtr;
private:
void handleWord1(const TTstring *str);
void handleWord2(const TTstring *str);
public:
TTparser _parser;
TTvocab *_vocab;
TTscriptBase *_script;
TTconcept *_concept1P;
TTconcept *_concept2P;
TTconcept *_concept3P;
TTconcept *_concept4P;
public:
CScriptHandler(CTitleEngine *owner, int val1, VocabMode vocabMode);
~CScriptHandler();
/**
* Set the character and room
*/
ScriptChangedResult scriptChanged(TTroomScript *roomScript,
TTnpcScript *npcScript, uint dialogueId);
int processInput(TTroomScript *roomScript, TTnpcScript *npcScript,
const TTstring &line);
/**
* Open a resource for access
*/
SimpleFile *openResource(const CString &name);
/**
* Called when concept data is copied from one to another
*/
void setParserConcept(TTconcept *newConcept, TTconcept *oldConcept);
/**
* Sets a conversation response
*/
int setResponse(TTscriptBase *script, TTresponse *response);
void handleWord(const TTstring *str);
};
} // End of namespace Titanic
#endif /* TITANIC_SCRIPT_HANDLER_H */

View File

@@ -0,0 +1,225 @@
/* 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/true_talk/script_support.h"
#include "titanic/support/files_manager.h"
#include "titanic/titanic.h"
namespace Titanic {
int TTnpcScriptResponse::size() const {
for (int idx = 0; idx < 4; ++idx) {
if (_values[idx] == 0)
return idx;
}
return 4;
}
/*------------------------------------------------------------------------*/
TTscriptRange::TTscriptRange(uint id, const Common::Array<uint> &values,
bool isRandom, bool isSequential) :
_id(id), _nextP(nullptr), _priorIndex(0) {
_mode = SF_NONE;
if (isRandom)
_mode = SF_RANDOM;
if (isSequential)
_mode = SF_SEQUENTIAL;
for (uint idx = 0; idx < values.size(); ++idx)
_values.push_back(values[idx]);
}
/*------------------------------------------------------------------------*/
bool TTsentenceEntry::load(Common::SeekableReadStream *s) {
if (s->pos() >= s->size())
return false;
_field0 = s->readUint32LE();
_category = s->readUint32LE();
_string8 = readStringFromStream(s);
_fieldC = s->readUint32LE();
_string10 = readStringFromStream(s);
_string14 = readStringFromStream(s);
_string18 = readStringFromStream(s);
_string1C = readStringFromStream(s);
_field20 = s->readUint32LE();
_string24 = readStringFromStream(s);
_field28 = s->readUint32LE();
_field2C = s->readUint32LE();
_field30 = s->readUint32LE();
return true;
}
/*------------------------------------------------------------------------*/
void TTsentenceEntries::load(const CString &resName) {
TTsentenceEntry entry;
Common::SeekableReadStream *r = g_vm->_filesManager->getResource(resName);
while (entry.load(r))
push_back(entry);
delete r;
}
/*------------------------------------------------------------------------*/
TTscriptMapping::TTscriptMapping() : _id(0) {
Common::fill(&_values[0], &_values[8], 0);
}
/*------------------------------------------------------------------------*/
void TTscriptMappings::load(const char *name, int valuesPerMapping) {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name);
_valuesPerMapping = valuesPerMapping;
while (r->pos() < r->size()) {
resize(size() + 1);
TTscriptMapping &m = (*this)[size() - 1];
m._id = r->readUint32LE();
for (int idx = 0; idx < valuesPerMapping; ++idx)
m._values[idx] = r->readUint32LE();
}
delete r;
}
/*------------------------------------------------------------------------*/
void TTtagMappings::load(const char *name) {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name);
while (r->pos() < r->size()) {
uint src = r->readUint32LE();
uint dest = r->readUint32LE();
push_back(TTtagMapping(src, dest));
}
delete r;
}
/*------------------------------------------------------------------------*/
void TTwordEntries::load(const char *name) {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name);
while (r->pos() < r->size()) {
TTwordEntry we;
we._id = r->readUint32LE();
we._text = readStringFromStream(r);
push_back(we);
}
delete r;
}
/*------------------------------------------------------------------------*/
void TThandleQuoteEntries::load(const char *name) {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name);
_rangeStart = r->readUint32LE();
_rangeEnd = r->readUint32LE();
_incr = r->readUint32LE();
while (r->pos() < r->size()) {
TThandleQuoteEntry qe;
qe._tag1 = r->readUint32LE();
qe._tag2= r->readUint32LE();
qe._index = r->readUint32LE();
push_back(qe);
}
delete r;
}
/*------------------------------------------------------------------------*/
void TTmapEntryArray::load(const char *name) {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name);
while (r->pos() < r->size()) {
TTmapEntry us;
us._src = r->readUint32LE();
us._dest = r->readUint32LE();
push_back(us);
}
delete r;
}
int TTmapEntryArray::find(uint id) const {
for (uint idx = 0; idx < size(); ++idx) {
const TTmapEntry &me = (*this)[idx];
if (me._src == id)
return me._dest;
}
return 0;
}
/*------------------------------------------------------------------------*/
void TTupdateStateArray::load(const char *name) {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name);
while (r->pos() < r->size()) {
TTupdateState us;
us._newId = r->readUint32LE();
us._newValue = r->readUint32LE();
us._dialBits = r->readUint32LE();
push_back(us);
}
delete r;
}
/*------------------------------------------------------------------------*/
void TTcommonPhraseArray::load(const char *name) {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name);
while (r->pos() < r->size()) {
TTcommonPhrase cp;
cp._str = readStringFromStream(r);
cp._dialogueId = r->readUint32LE();
cp._roomNum = r->readUint32LE();
cp._val1 = r->readUint32LE();
push_back(cp);
}
delete r;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,196 @@
/* 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_SCRIPT_SUPPORT_H
#define TITANIC_SCRIPT_SUPPORT_H
#include "titanic/support/simple_file.h"
namespace Titanic {
#define DIALS_ARRAY_COUNT 10
enum ScriptArrayFlag { SF_NONE = 0, SF_RANDOM = 1, SF_SEQUENTIAL = 2 };
struct RoomDialogueId {
uint _roomNum;
uint _dialogueId;
};
struct TTnpcScriptResponse {
uint _tag;
uint _values[4];
TTnpcScriptResponse() : _tag(0) {
_values[0] = _values[1] = _values[2] = _values[3] = 0;
}
/**
* Returns the size of the values list plus 1
*/
int size() const;
};
struct TTscriptRange {
uint _id;
Common::Array<uint> _values;
TTscriptRange *_nextP;
uint _priorIndex;
ScriptArrayFlag _mode;
TTscriptRange() : _id(0), _nextP(nullptr),
_priorIndex(0), _mode(SF_NONE) {}
TTscriptRange(uint id, const Common::Array<uint> &values, bool isRandom,
bool isSequential);
};
struct TTsentenceEntry {
int _field0;
int _category;
CString _string8;
int _fieldC;
CString _string10;
CString _string14;
CString _string18;
CString _string1C;
int _field20;
CString _string24;
int _field28;
int _field2C;
int _field30;
TTsentenceEntry() : _field0(0), _category(0), _fieldC(0),
_field20(0), _field28(0), _field2C(0), _field30(0) {}
/**
* Load an entry from the passed stream, and returns true
* if an entry was successfully loaded
*/
bool load(Common::SeekableReadStream *s);
};
class TTsentenceEntries : public Common::Array<TTsentenceEntry> {
public:
/**
* Load a list of entries from the specified resource
*/
void load(const CString &resName);
};
struct TTscriptMapping {
uint _id;
uint _values[8];
TTscriptMapping();
};
class TTscriptMappings : public Common::Array<TTscriptMapping> {
public:
int _valuesPerMapping;
void load(const char *name, int valuesPerMapping);
};
struct TTtagMapping {
uint _src, _dest;
TTtagMapping() : _src(0), _dest(0) {}
TTtagMapping(uint src, uint dest) : _src(src), _dest(dest) {}
};
class TTtagMappings : public Common::Array<TTtagMapping> {
public:
void load(const char *name);
};
struct TTwordEntry {
uint _id;
CString _text;
TTwordEntry() : _id(0) {}
};
class TTwordEntries : public Common::Array<TTwordEntry> {
public:
void load(const char *name);
};
struct TThandleQuoteEntry {
uint _tag1;
uint _tag2;
uint _index;
TThandleQuoteEntry() : _tag1(0), _tag2(0), _index(0) {}
};
class TThandleQuoteEntries : public Common::Array<TThandleQuoteEntry> {
public:
uint _rangeStart, _rangeEnd;
uint _incr;
public:
TThandleQuoteEntries() : _rangeStart(0), _rangeEnd(0), _incr(0) {}
void load(const char *name);
};
struct TTmapEntry {
uint _src;
uint _dest;
TTmapEntry() : _src(0), _dest(0) {}
};
class TTmapEntryArray : public Common::Array<TTmapEntry> {
public:
void load(const char *name);
/**
* Finds a record by Id, and returns it's associated value
*/
int find(uint id) const;
};
struct TTupdateState {
uint _newId;
uint _newValue;
uint _dialBits;
TTupdateState() : _newId(0), _newValue(0), _dialBits(0) {}
};
class TTupdateStateArray : public Common::Array<TTupdateState> {
public:
void load(const char *name);
};
struct TTcommonPhrase {
CString _str;
uint _dialogueId;
uint _roomNum;
uint _val1;
};
class TTcommonPhraseArray : public Common::Array<TTcommonPhrase> {
public:
void load(const char *name);
};
} // End of namespace Titanic
#endif /* TITANIC_TT_NPC_SCRIPT_H */

View File

@@ -0,0 +1,250 @@
/* 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 "common/textconsole.h"
#include "titanic/true_talk/succubus_script.h"
#include "titanic/true_talk/true_talk_manager.h"
#include "titanic/titanic.h"
#include "titanic/translation.h"
namespace Titanic {
SuccUBusScript::SuccUBusScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) :
TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7),
_isRoom101(false) {
loadRanges("Ranges/SuccUBus");
setupSentences();
}
void SuccUBusScript::setupSentences() {
_mappings.load("Mappings/SuccUBus", 1);
_entries.load("Sentences/SuccUBus");
_field68 = 0;
_entryCount = 0;
}
int SuccUBusScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) {
uint dialogueId = tag;
switch (tag) {
case MKTAG('S', 'L', 'O', 'W'):
case MKTAG('T', 'H', 'R', 'T'):
dialogueId = 70021;
break;
case MKTAG('S', 'U', 'C', '1'):
dialogueId = getDialogueId(230009);
break;
case MKTAG('S', 'U', 'C', '2'):
dialogueId = 70117;
break;
case MKTAG('S', 'W', 'E', 'R'):
dialogueId = getRandomNumber(100) > 40 ? 70103 : getDialogueId(230030);
break;
default:
break;
}
if (dialogueId) {
addResponse(dialogueId);
applyResponse();
return 2;
} else {
return 1;
}
}
int SuccUBusScript::process(const TTroomScript *roomScript, const TTsentence *sentence) {
if (!CTrueTalkManager::getStateValue(1))
return 2;
if (roomScript && roomScript->_scriptId == 101)
_isRoom101 = true;
int currState = getState();
if (currState) {
int currMode = sentence->_category;
bool modeFlag1 = currMode == 11 || currMode == 13;
bool modeFlag2 = currMode == 12;
setState(0);
switch (currState) {
case 1:
if (currMode == 3 || currMode == 10)
return setResponse(70050, 0);
break;
case 2:
if (modeFlag1 || modeFlag2)
return setResponse(70070 + (getRandomBit() ? 254 : 0), 0);
break;
case 3:
if (currMode == 3 || currMode == 10)
return setResponse(70074, 0);
break;
case 4:
if (currMode == 4)
return setResponse(70077, 0);
if (currMode == 3)
return setResponse(getDialogueId(230117), 0);
break;
case 5:
if (currMode == 3 || currMode == 10)
return setResponse(70089, 0);
break;
case 6:
if (modeFlag1)
return setResponse(70103, 0);
if (modeFlag2)
return setResponse(70102, 0);
break;
case 7:
if (modeFlag1)
return setResponse(getDialogueId(230157), 0);
break;
case 8:
if (modeFlag1)
return setResponse(getDialogueId(230159), 0);
break;
case 9:
if (modeFlag1)
return setResponse(getDialogueId(230160), 0);
break;
case 10:
if (modeFlag1)
return setResponse(getDialogueId(230161), 0);
break;
case 11:
if (modeFlag1)
return setResponse(getDialogueId(230142), 0);
break;
case 12:
return setResponse(70030, 0);
default:
break;
}
}
if (processEntries(&_entries, _entryCount, roomScript, sentence) != 2) {
uint tagId = g_vm->_trueTalkManager->_quotes.find(sentence->_normalizedLine.c_str());
if (!tagId || chooseResponse(roomScript, sentence, tagId) != 2) {
addResponse(getDialogueId(230030));
applyResponse();
}
}
return 2;
}
ScriptChangedResult SuccUBusScript::scriptChanged(const TTroomScript *roomScript, uint id) {
if (g_language == Common::EN_ANY) {
if (id == 148)
CTrueTalkManager::setFlags(3, 1);
else if (id == 150)
CTrueTalkManager::setFlags(2, 1);
} else {
if (id == 70211 || id == 230013) {
addResponse(getDialogueId(230163));
applyResponse();
return SCR_2;
} else if (id < 70211) {
if (id == 148)
CTrueTalkManager::setFlags(3, 1);
else if (id == 150)
CTrueTalkManager::setFlags(2, 1);
}
}
if (id >= 230000 && id <= 230245) {
addResponse(getDialogueId(id));
applyResponse();
} else if (id >= 70000 && id <= (uint)TRANSLATE(70243, 70248)) {
addResponse(id);
applyResponse();
}
return SCR_2;
}
int SuccUBusScript::updateState(uint oldId, uint newId, int index) {
if (newId == 230199) {
return _isRoom101 ? 230148 : newId;
} else if (newId >= 230208 && newId <= 230235) {
addResponse(70158 - getRandomBit());
return newId;
} else if (newId >= 230061 && newId <= 230063) {
if (getValue(2))
return 230125;
}
static const uint UPDATE_STATES[][2] = {
{ 230078, 1 }, { 230106, 2 }, { 230112, 3 }, { 230115, 4 },
{ 230127, 5 }, { 230140, 6 }, { 230156, 7 }, { 230157, 8 },
{ 230159, 9 }, { 230160, 10 }, { 230161, 11 }, { 230072, 12 }
};
for (int idx = 0; idx < 12; ++idx) {
if (UPDATE_STATES[idx][0] == newId) {
setState(UPDATE_STATES[idx][1]);
break;
}
}
return newId;
}
int SuccUBusScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) {
if (val1 == 1 && roomScript && roomScript->_scriptId == 101) {
addResponse(getDialogueId(230239));
applyResponse();
return 2;
}
return 0;
}
int SuccUBusScript::setResponse(int dialogueId, int state) {
addResponse(dialogueId);
applyResponse();
if (state != -1)
setState(state);
return 2;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,74 @@
/* 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_SCRIPT_H
#define TITANIC_SUCCUBUS_SCRIPT_H
#include "titanic/true_talk/tt_npc_script.h"
namespace Titanic {
class SuccUBusScript : public TTnpcScript {
private:
bool _isRoom101;
private:
/**
* Setup sentence data
*/
void setupSentences();
/**
* Add a response and optionally set the state
*/
int setResponse(int dialogueId, int state = -1);
public:
SuccUBusScript(int val1, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4, int v5, int v6, int v7);
/**
* Chooses and adds a conversation response based on a specified tag Id.
*/
int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) override;
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override;
/**
* Handles updating NPC state based on specified dialogue Ids and dial positions
*/
int updateState(uint oldId, uint newId, int index) override;
/**
* Process a sentence fragment entry
*/
int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) override;
};
} // End of namespace Titanic
#endif /* TITANIC_SUCCUBUS_SCRIPT_H */

View 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/true_talk/title_engine.h"
#include "titanic/support/files_manager.h"
#include "titanic/titanic.h"
#include "titanic/translation.h"
namespace Titanic {
CTitleEngine::CTitleEngine() : _script(nullptr), _scriptHandler(nullptr) {
}
CTitleEngine::~CTitleEngine() {
delete _script;
delete _scriptHandler;
}
void CTitleEngine::setup(int val1, VocabMode vocabMode) {
_script = new TTTitleScript();
_scriptHandler = new CScriptHandler(this, val1, vocabMode);
}
/*------------------------------------------------------------------------*/
STtitleEngine::STtitleEngine(): CTitleEngine(),
_responseP(nullptr), _stream(nullptr) {
}
STtitleEngine::~STtitleEngine() {
delete _stream;
}
void STtitleEngine::reset() {
_indexes.clear();
}
void STtitleEngine::setup(int val1, VocabMode vocabMode) {
CTitleEngine::setup(val1, TRANSLATE(VOCAB_MODE_EN, VOCAB_MODE_DE));
}
int STtitleEngine::setResponse(TTscriptBase *script, TTresponse *response) {
_responseP = response;
_indexes.clear();
for (TTresponse *respP = response; respP; respP = respP->getNext()) {
_indexes.push_back(respP->getDialogueId());
}
return 0;
}
SimpleFile *STtitleEngine::open(const CString &name) {
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(
CString::format("TEXT/%s", name.c_str()));
assert(stream);
SimpleFile *file = new SimpleFile();
file->open(stream);
return file;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,96 @@
/* 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_TITLE_ENGINE_H
#define TITANIC_TITLE_ENGINE_H
#include "common/stream.h"
#include "titanic/support/string.h"
#include "titanic/true_talk/script_handler.h"
#include "titanic/true_talk/tt_response.h"
#include "titanic/true_talk/tt_script_base.h"
#include "titanic/true_talk/tt_title_script.h"
namespace Titanic {
class CTitleEngine;
class CTitleStream : public SimpleFile {
public:
CTitleStream() : SimpleFile() {}
};
class CTitleEngine {
public:
CScriptHandler *_scriptHandler;
TTscriptBase *_script;
public:
CTitleEngine();
virtual ~CTitleEngine();
/**
* Setup the engine
*/
virtual void setup(int val1, VocabMode vocabMode = VOCAB_MODE_NONE);
/**
* Sets a conversation response
*/
virtual int setResponse(TTscriptBase *script, TTresponse *response) { return SS_4; }
/**
* Open a designated file
*/
virtual SimpleFile *open(const CString &name) = 0;
};
class STtitleEngine : public CTitleEngine {
private:
Common::SeekableReadStream *_stream;
const TTresponse *_responseP;
public:
Common::Array<uint> _indexes;
Common::Array<byte> _data;
public:
STtitleEngine();
~STtitleEngine() override;
void reset();
/**
* Setup the engine
*/
void setup(int val1, VocabMode vocabMode = VOCAB_MODE_NONE) override;
/**
* Sets a conversation response
*/
int setResponse(TTscriptBase *script, TTresponse *response) override;
/**
* Open a designated file
*/
SimpleFile *open(const CString &name) override;
};
} // End of namespace Titanic
#endif /* TITANIC_TITLE_ENGINE_H */

View File

@@ -0,0 +1,598 @@
/* 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/true_talk/true_talk_manager.h"
#include "titanic/core/tree_item.h"
#include "titanic/game_manager.h"
#include "titanic/npcs/true_talk_npc.h"
#include "titanic/titanic.h"
#define MKTAG_BE(a3,a2,a1,a0) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24)))
namespace Titanic {
int CTrueTalkManager::_v1;
int CTrueTalkManager::_v2;
int CTrueTalkManager::_v3;
bool CTrueTalkManager::_v4;
bool CTrueTalkManager::_v5;
int CTrueTalkManager::_v6;
int CTrueTalkManager::_v7;
bool CTrueTalkManager::_v8;
int CTrueTalkManager::_v9;
bool CTrueTalkManager::_v10;
int CTrueTalkManager::_v11[41];
CTrueTalkNPC *CTrueTalkManager::_currentNPC;
/*------------------------------------------------------------------------*/
CTrueTalkManager::CTrueTalkManager(CGameManager *owner) :
_gameManager(owner), _scripts(), _currentCharId(0),
_dialogueFile(nullptr), _dialogueId(0) {
_titleEngine.setup(3, VOCAB_MODE_EN);
_quotes.load();
_quotesTree.load();
_currentNPC = nullptr;
g_vm->_trueTalkManager = this;
}
CTrueTalkManager::~CTrueTalkManager() {
clear();
g_vm->_trueTalkManager = nullptr;
}
void CTrueTalkManager::save(SimpleFile *file) const {
saveStatics(file);
saveNPC(file, 101);
saveNPC(file, 103);
saveNPC(file, 104);
saveNPC(file, 105);
saveNPC(file, 111);
saveNPC(file, 100);
saveNPC(file, 112);
saveNPC(file, 107);
file->writeNumber(0);
}
void CTrueTalkManager::load(SimpleFile *file) {
loadStatics(file);
// Iterate through loading characters
int charId = file->readNumber();
while (charId) {
loadNPC(file, charId);
int ident1 = file->readNumber();
int ident2 = file->readNumber();
if (ident1 != MKTAG_BE('U', 'R', 'A', 'H')) {
while (ident2 != MKTAG_BE('A', 'K', 'E', 'R')) {
ident1 = ident2;
ident2 = file->readNumber();
if (!ident1)
break;
}
}
// Get start of next character
charId = file->readNumber();
}
}
void CTrueTalkManager::loadStatics(SimpleFile *file) {
int count = file->readNumber();
_v1 = file->readNumber();
_v2 = file->readNumber();
_v3 = file->readNumber();
_v4 = file->readNumber() != 0;
_v5 = file->readNumber() != 0;
_v6 = file->readNumber();
_v7 = file->readNumber();
_v8 = file->readNumber() != 0;
_v9 = file->readNumber();
_v10 = file->readNumber() != 0;
for (int idx = count; idx > 10; --idx)
file->readNumber();
int count2 = file->readNumber();
for (int idx = 0; idx < count2; ++idx) {
int v = file->readNumber();
if (idx < 41)
_v11[idx] = v;
}
}
void CTrueTalkManager::saveStatics(SimpleFile *file) {
file->writeNumber(10);
file->writeNumber(_v1);
file->writeNumber(_v2);
file->writeNumber(_v3);
file->writeNumber(_v4 ? 1 : 0);
file->writeNumber(_v5 ? 1 : 0);
file->writeNumber(_v6);
file->writeNumber(_v7);
file->writeNumber(_v8 ? 1 : 0);
file->writeNumber(_v9);
file->writeNumber(_v10 ? 1 : 0);
file->writeNumber(41);
for (int idx = 0; idx < 41; ++idx)
file->writeNumber(_v11[idx]);
}
void CTrueTalkManager::clear() {
delete _dialogueFile;
_dialogueFile = nullptr;
_currentCharId = 0;
}
void CTrueTalkManager::setFlags(int index, int val) {
switch (index) {
case 1:
if (val >= 1 && val <= 3)
_v3 = val;
break;
case 2:
_v4 = !val;
break;
case 3:
_v5 = val != 0;
break;
case 4:
if (val >= 0 && val <= 3)
_v6 = val;
break;
case 5:
_v7 = val;
break;
case 6:
_v8 = val != 0;
break;
default:
if (index < 41)
_v11[index] = val;
break;
}
}
void CTrueTalkManager::loadNPC(SimpleFile *file, int charId) {
TTnpcScript *script = _scripts.getNpcScript(charId);
if (script)
script->load(file);
}
void CTrueTalkManager::saveNPC(SimpleFile *file, int charId) const {
TTnpcScript *script = _scripts.getNpcScript(charId);
if (script) {
script->save(file);
file->writeNumber(MKTAG_BE('U', 'R', 'A', 'H'));
file->writeNumber(MKTAG_BE('A', 'K', 'E', 'R'));
}
}
void CTrueTalkManager::preLoad() {
// Delete any previous talkers
for (TTtalkerList::iterator i = _talkers.begin(); i != _talkers.end(); ++i)
delete *i;
_talkers.clear();
}
void CTrueTalkManager::removeCompleted() {
for (TTtalkerList::iterator i = _talkers.begin(); i != _talkers.end(); ) {
TTtalker *talker = *i;
if (talker->_done) {
i = _talkers.erase(i);
talker->speechEnded();
delete talker;
} else {
++i;
}
}
}
void CTrueTalkManager::start(CTrueTalkNPC *npc, uint id, CViewItem *view) {
TTnpcScript *npcScript = getNpcScript(npc);
TTroomScript *roomScript = getRoomScript();
_titleEngine.reset();
uint charId = npcScript->charId();
loadAssets(npc, charId);
_currentNPC = npc;
_titleEngine._scriptHandler->scriptChanged(roomScript, npcScript, id);
_currentNPC = nullptr;
setDialogue(npc, roomScript, view);
}
void CTrueTalkManager::start3(CTrueTalkNPC *npc, CViewItem *view) {
start(npc, 3, view);
}
void CTrueTalkManager::start4(CTrueTalkNPC *npc, CViewItem *view) {
start(npc, 4, view);
}
TTnpcScript *CTrueTalkManager::getTalker(const CString &name) const {
if (name.containsIgnoreCase("Doorbot"))
return _scripts.getNpcScript(104);
else if (name.containsIgnoreCase("Deskbot"))
return _scripts.getNpcScript(103);
else if (name.containsIgnoreCase("LiftBot"))
return _scripts.getNpcScript(105);
else if (name.containsIgnoreCase("Parrot"))
return _scripts.getNpcScript(107);
else if (name.containsIgnoreCase("BarBot"))
return _scripts.getNpcScript(100);
else if (name.containsIgnoreCase("ChatterBot"))
return _scripts.getNpcScript(102);
else if (name.containsIgnoreCase("BellBot"))
return _scripts.getNpcScript(101);
else if (name.containsIgnoreCase("MaitreD"))
return _scripts.getNpcScript(112);
else if (name.containsIgnoreCase("Succubus") || name.containsIgnoreCase("Sub"))
return _scripts.getNpcScript(111);
return nullptr;
}
TTnpcScript *CTrueTalkManager::getNpcScript(CTrueTalkNPC *npc) const {
CString npcName = npc->getName();
TTnpcScript *script = getTalker(npcName);
if (!script) {
// Fall back on the default NPC script
script = _scripts.getNpcScript(101);
}
return script;
}
TTroomScript *CTrueTalkManager::getRoomScript() const {
CRoomItem *room = _gameManager->getRoom();
TTroomScript *script = nullptr;
if (room) {
int scriptId = room->getScriptId();
if (scriptId)
script = _scripts.getRoomScript(scriptId);
}
if (!script) {
// Fall back on the default Room script
script = _scripts.getRoomScript(110);
}
return script;
}
TTroomScript *CTrueTalkManager::getRoomScript(int roomId) const {
TTroomScript *script = nullptr;
if (roomId)
script = _scripts.getRoomScript(roomId);
if (!script)
// Fall back on the default Room script
script = _scripts.getRoomScript(110);
return script;
}
void CTrueTalkManager::loadAssets(CTrueTalkNPC *npc, int charId) {
// If assets for the character are already loaded, simply exit
if (_currentCharId == charId)
return;
// Clear any previously loaded data
clear();
// Signal the NPC to get the asset details
CTrueTalkGetAssetDetailsMsg detailsMsg;
detailsMsg.execute(npc);
if (!detailsMsg._filename.empty()) {
_dialogueFile = new CDialogueFile(detailsMsg._filename, 20);
_dialogueId = detailsMsg._numValue + 1;
}
}
void CTrueTalkManager::processInput(CTrueTalkNPC *npc, CTextInputMsg *msg, CViewItem *view) {
TTnpcScript *npcScript = getNpcScript(npc);
TTroomScript *roomScript = getRoomScript();
_titleEngine.reset();
if (npcScript && roomScript) {
_currentNPC = npc;
_titleEngine._scriptHandler->processInput(roomScript, npcScript, TTstring(msg->_input));
_currentNPC = nullptr;
loadAssets(npc, npcScript->charId());
setDialogue(npc, roomScript, view);
}
_currentNPC = nullptr;
}
void CTrueTalkManager::setDialogue(CTrueTalkNPC *npc, TTroomScript *roomScript, CViewItem *view) {
// Get the dialog text
CString dialogueStr = readDialogueString();
if (dialogueStr.empty())
return;
uint speechDuration = readDialogueSpeech();
TTtalker *talker = new TTtalker(this, npc);
_talkers.push_back(talker);
bool isParrot = npc->getName().containsIgnoreCase("parrot");
triggerNPC(npc);
playSpeech(talker, roomScript, view, isParrot);
talker->speechStarted(dialogueStr, _titleEngine._indexes[0], speechDuration);
}
#define STRING_BUFFER_SIZE 2048
CString CTrueTalkManager::readDialogueString() {
byte buffer[STRING_BUFFER_SIZE];
CString result;
for (uint idx = 0; idx < _titleEngine._indexes.size(); ++idx) {
if (idx != 0)
result += " ";
// Open a text entry from the dialogue file for access
DialogueResource *textRes = _dialogueFile->openTextEntry(
_titleEngine._indexes[idx] - _dialogueId);
if (!textRes)
continue;
size_t entrySize = textRes->size();
byte *tempBuffer = (entrySize < STRING_BUFFER_SIZE) ? buffer :
new byte[entrySize + 1];
_dialogueFile->read(textRes, tempBuffer, entrySize);
buffer[entrySize] = '\0';
// Close the resource
_dialogueFile->closeEntry(textRes);
// Strip off any non-printable characters
for (byte *p = buffer; *p != '\0'; ++p) {
if (*p < 32)
*p = ' ';
}
// Add string to result
result += CString((const char *)buffer);
// Free buffer if one was allocated
if (entrySize >= STRING_BUFFER_SIZE)
delete[] tempBuffer;
}
return result;
}
uint CTrueTalkManager::readDialogueSpeech() {
_speechDuration = 0;
for (uint idx = 0; idx < _titleEngine._indexes.size(); ++idx) {
CWaveFile *waveFile = _gameManager->_sound.getTrueTalkSound(
_dialogueFile, _titleEngine._indexes[idx] - _dialogueId);
if (waveFile) {
_speechDuration += waveFile->getDurationTicks();
}
}
return _speechDuration;
}
void CTrueTalkManager::triggerNPC(CTrueTalkNPC *npc) {
CTrueTalkSelfQueueAnimSetMsg queueSetMsg;
if (queueSetMsg.execute(npc)) {
if (_speechDuration > 300) {
CTrueTalkQueueUpAnimSetMsg upMsg(_speechDuration);
upMsg.execute(npc);
}
} else {
CTrueTalkGetAnimSetMsg getAnimMsg;
while (_speechDuration > 300) {
getAnimMsg.execute(npc);
if (!getAnimMsg._endFrame)
break;
npc->playMovie(getAnimMsg._startFrame, getAnimMsg._endFrame, 0);
getAnimMsg._endFrame = 0;
uint numFrames = getAnimMsg._endFrame - getAnimMsg._startFrame;
int diff = (numFrames * 1000) / 15 - 500;
_speechDuration += diff;
getAnimMsg._index++;
}
}
}
void CTrueTalkManager::playSpeech(TTtalker *talker, TTroomScript *roomScript, CViewItem *view, bool isParrot) {
uint milli, index;
switch (roomScript->_scriptId) {
case 101:
milli = 300;
index = 16;
break;
case 106:
case 107:
case 110:
case 114:
case 115:
case 122:
milli = 130;
index = 10;
break;
case 108:
case 109:
milli = 200;
index = 10;
break;
case 111:
case 116:
case 121:
milli = 80;
index = 12;
break;
case 112:
case 124:
case 128:
case 130:
milli = 80;
index = 4;
break;
case 132:
milli = 60;
index = 4;
break;
default:
milli = 0;
index = 4;
break;
}
// Setup proximities
CProximity p1, p2, p3;
if (isParrot) {
p1._soundType = Audio::Mixer::kSFXSoundType;
p1._channelMode = 3;
p2._channelMode = 5;
p3._channelMode = 4;
} else {
p1._channelMode = 0;
p2._channelMode = 1;
p3._channelMode = 2;
}
if (milli > 0) {
p3._channelVolume = (index * 3) / 2;
p3._positioningMode = POSMODE_POLAR;
p3._azimuth = -135.0;
p3._range = 1.0;
p3._elevation = 0;
p2._channelVolume = (index * 3) / 4;
p2._positioningMode = POSMODE_NONE;
p2._azimuth = 135.0;
p2._range = 1.0;
p2._elevation = 0;
}
_gameManager->_sound.stopChannel(p1._channelMode);
if (view) {
p1._positioningMode = POSMODE_VECTOR;
#ifdef SPATIAL_SOUND
view->getPosition(p1._posX, p1._posY, p1._posZ);
#endif
}
// Loop through adding each of the speech portions in. We use the
// _priorSoundHandle of CProximity to chain each successive speech
// to start when the prior one finishes
for (uint idx = 0; idx < _titleEngine._indexes.size(); ++idx) {
uint id = _titleEngine._indexes[idx];
if (id > 100000)
continue;
if (idx == (_titleEngine._indexes.size() - 1)) {
// Final iteration of speech segments to play
p1._endTalkerFn = &talkerEnd;
p1._talker = talker;
}
// Start the speech
p1._priorSoundHandle = _gameManager->_sound.playSpeech(_dialogueFile, id - _dialogueId, p1);
if (!milli)
continue;
#ifdef SPATIAL_SOUND
if (idx == 0)
g_vm->_events->sleep(milli);
// TODO: Figure out if these below are needed. It kinda looks like they were
// simply playing the same speech at different spatial co-ordinates. And since
// we don't support spatial processing in ScummVM yet, they're being left disabled
p3._priorSoundHandle = _gameManager->_sound.playSpeech(_dialogueFile, id - _dialogueId, p3);
if (idx == 0)
g_vm->_events->sleep(milli);
p2._priorSoundHandle = _gameManager->_sound.playSpeech(_dialogueFile, id - _dialogueId, p2);
#endif
}
}
int CTrueTalkManager::getStateValue(int stateNum) {
if (!_currentNPC)
return -1000;
CTrueTalkGetStateValueMsg msg(stateNum, -1000);
msg.execute(_currentNPC);
return msg._stateVal;
}
bool CTrueTalkManager::triggerAction(int action, int param) {
if (!_currentNPC)
return false;
CTrueTalkTriggerActionMsg msg(action, param, 0);
msg.execute(_currentNPC);
return true;
}
void CTrueTalkManager::talkerEnd(TTtalker *talker) {
if (talker)
talker->endSpeech(0);
}
CGameManager *CTrueTalkManager::getGameManager() const {
return _gameManager;
}
CGameState *CTrueTalkManager::getGameState() const {
return _gameManager ? &_gameManager->_gameState : nullptr;
}
int CTrueTalkManager::getPassengerClass() const {
CGameState *gameState = getGameState();
return gameState ? gameState->_passengerClass : 4;
}
Season CTrueTalkManager::getCurrentSeason() const {
CGameState *gameState = getGameState();
return gameState ? gameState->_seasonNum : SEASON_SUMMER;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,244 @@
/* 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_MANAGER_H
#define TITANIC_TRUE_TALK_MANAGER_H
#include "titanic/messages/messages.h"
#include "titanic/support/simple_file.h"
#include "titanic/true_talk/dialogue_file.h"
#include "titanic/true_talk/title_engine.h"
#include "titanic/true_talk/tt_quotes.h"
#include "titanic/true_talk/tt_quotes_tree.h"
#include "titanic/true_talk/tt_scripts.h"
#include "titanic/true_talk/tt_talker.h"
#include "titanic/game_state.h"
namespace Titanic {
class CGameManager;
class CGameState;
class CTreeItem;
class CViewItem;
class CTrueTalkManager;
class CTrueTalkNPC;
class CTrueTalkManager {
private:
CGameManager *_gameManager;
STtitleEngine _titleEngine;
TTscripts _scripts;
int _currentCharId;
CDialogueFile *_dialogueFile;
int _dialogueId;
int _speechDuration;
TTtalkerList _talkers;
private:
/**
* Loads the statics for the class
*/
static void loadStatics(SimpleFile *file);
/**
* Saves the statics associated with the class
*/
static void saveStatics(SimpleFile *file);
/**
* Loads an NPC from file
*/
void loadNPC(SimpleFile *file, int charId);
/**
* Saves the specified NPC to file
*/
void saveNPC(SimpleFile *file, int charId) const;
/**
* Gets the script associated with an NPC game object
*/
TTnpcScript *getNpcScript(CTrueTalkNPC *npc) const;
/**
* Gets the script associated with the current room
*/
TTroomScript *getRoomScript() const;
/**
* Loads assets for the current character, if it's changed
*/
void loadAssets(CTrueTalkNPC *npc, int charId);
void setDialogue(CTrueTalkNPC *npc, TTroomScript *roomScript, CViewItem *view);
/**
* Read in text from the dialogue file
*/
CString readDialogueString();
/**
* Read in the speech from the dialogue file
* @returns Duration of the speech in seconds
*/
uint readDialogueSpeech();
/**
* Triggers animation for the NPC
*/
void triggerNPC(CTrueTalkNPC *npc);
/**
* Plays speech specified by the manager's indexes array
*/
void playSpeech(TTtalker *talker, TTroomScript *roomScript, CViewItem *view, bool isParrot);
/**
* Called when a talker finishes
*/
static void talkerEnd(TTtalker *talker);
/**
* Return the game state
*/
CGameState *getGameState() const;
public:
static int _v1;
static int _v2;
static int _v3;
static bool _v4;
static bool _v5;
static int _v6;
static int _v7;
static bool _v8;
static int _v9;
static bool _v10;
static int _v11[41];
static CTrueTalkNPC *_currentNPC;
static void setFlags(int index, int val);
public:
TTquotes _quotes;
TTquotesTree _quotesTree;
public:
/**
* Get a specified state value from the currently set NPC
*/
static int getStateValue(int stateNum);
/**
* Trigger an NPC action
*/
static bool triggerAction(int action, int param);
public:
CTrueTalkManager(CGameManager *owner);
~CTrueTalkManager();
/**
* Save the data for the class to file
*/
void save(SimpleFile *file) const;
/**
* Load the data for the class from file
*/
void load(SimpleFile *file);
/**
* Clear the manager
*/
void clear();
/**
* Called when a game is about to be loaded
*/
void preLoad();
/**
* Called when loading a game is complete
*/
void postLoad() {}
/**
* Called when a game is about to be saved
*/
void preSave() {}
/**
* Called when a game has finished being saved
*/
void postSave() {}
/**
* Returns the scripts for the manager
*/
TTscripts &getScripts() { return _scripts; }
/**
* Remove any completed talkers
*/
void removeCompleted();
/**
* Return the game manager
*/
CGameManager *getGameManager() const;
/**
* Start a TrueTalk conversation
*/
void start(CTrueTalkNPC *npc, uint id, CViewItem *view);
/**
* Start a TrueTalk conversation
*/
void start3(CTrueTalkNPC *npc, CViewItem *view);
/**
* Start a TrueTalk conversation
*/
void start4(CTrueTalkNPC *npc, CViewItem *view);
/**
* Return a TrueTalk talker/script
*/
TTnpcScript *getTalker(const CString &name) const;
/**
* Process player's input
*/
void processInput(CTrueTalkNPC *npc, CTextInputMsg *msg, CViewItem *view);
/**
* Gets the script associated with a specific room
*/
TTroomScript *getRoomScript(int roomId) const;
/**
* Get the player's passenger class
*/
int getPassengerClass() const;
Season getCurrentSeason() const;
};
} // End of namespace Titanic
#endif /* TITANIC_TRUE_TALK_MANAGER_H */

View File

@@ -0,0 +1,68 @@
/* 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/true_talk/tt_action.h"
namespace Titanic {
bool TTaction::_staticFlag;
TTaction::TTaction(const TTstring &str, WordClass wordClass, int val2, int val3, int val4) :
TTmajorWord(str, wordClass, val2, val3), _field30(val4) {
}
TTaction::TTaction(const TTaction *src) : TTmajorWord(src) {
if (src->getStatus()) {
_field30 = 0;
_status = SS_5;
} else {
_field30 = src->_field30;
}
}
int TTaction::load(SimpleFile *file) {
int val;
if (!TTword::load(file, WC_ACTION) && file->scanf("%d", &val)) {
_field30 = val;
return 0;
} else {
return 8;
}
}
TTword *TTaction::copy() const {
TTaction *returnWordP = new TTaction(this);
returnWordP->_status = _status;
if (!_status) {
_staticFlag = false;
return returnWordP;
} else if (_status == SS_13 && !_staticFlag) {
_staticFlag = true;
delete returnWordP;
return copy();
} else {
delete returnWordP;
return nullptr;
}
}
} // End of namespace Titanic

View 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_TT_ACTION_H
#define TITANIC_TT_ACTION_H
#include "titanic/true_talk/tt_major_word.h"
namespace Titanic {
class TTaction : public TTmajorWord {
private:
static bool _staticFlag;
protected:
int _field30;
public:
TTaction(const TTstring &str, WordClass wordClass, int val2, int val3, int val4);
TTaction(const TTaction *src);
/**
* Load the word
*/
int load(SimpleFile *file);
void setVal(int val) { _field30 = val; }
int getVal() const { return _field30; }
/**
* Creates a copy of the word
*/
TTword *copy() const override;
bool proc12(int val) const override { return _field30 == val; }
};
} // End of namespace Titanic
#endif /* TITANIC_TT_ACTION_H */

View File

@@ -0,0 +1,83 @@
/* 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/true_talk/tt_adj.h"
namespace Titanic {
bool TTadj::_staticFlag;
TTadj::TTadj(TTstring &str, WordClass wordClass, int val2, int val3, int val4) :
TTmajorWord(str, wordClass, val2, val3) {
if (val4 >= 0 && val4 <= 9) {
_val = val4;
} else {
_val = 0;
_status = SS_5;
}
}
TTadj::TTadj(const TTadj *src) : TTmajorWord(src) {
if (src->getStatus()) {
_val = 0;
_status = SS_5;
} else {
_val = src->_val;
}
}
int TTadj::load(SimpleFile *file) {
int val;
if (!TTword::load(file, WC_ADJECTIVE) && file->scanf("%d", &val)) {
_val = val;
return 0;
} else {
return 8;
}
}
int TTadj::adjFn1(int val) {
if (_val < 0 || _val > 9) {
return SS_4;
} else {
_val = val;
return SS_VALID;
}
}
TTword *TTadj::copy() const {
TTadj *returnWordP = new TTadj(this);
returnWordP->_status = _status;
if (!_status) {
_staticFlag = false;
return returnWordP;
} else if (_status == SS_13 && !_staticFlag) {
_staticFlag = true;
delete returnWordP;
return copy();
} else {
delete returnWordP;
return nullptr;
}
}
} // End of namespace Titanic

View 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_TT_ADJ_H
#define TITANIC_TT_ADJ_H
#include "titanic/true_talk/tt_major_word.h"
namespace Titanic {
class TTadj : public TTmajorWord {
private:
static bool _staticFlag;
protected:
int _val;
public:
TTadj(TTstring &str, WordClass wordClass, int val2, int val3, int val4);
TTadj(const TTadj *src);
/**
* Load the word
*/
int load(SimpleFile *file);
int adjFn1(int val);
/**
* Creates a copy of the word
*/
TTword *copy() const override;
bool proc14(int val) const override { return _val == val; }
int proc15() const override { return _val; }
bool proc16() const override { return _val >= 7; }
bool proc17() const override { return _val <= 3; }
bool proc18() const override { return _val > 3 && _val < 7; }
/**
* Dumps data associated with the word to file
*/
int save(SimpleFile *file) const override {
return saveData(file, _val);
}
};
} // End of namespace Titanic
#endif /* TITANIC_TT_ADJ_H */

View File

@@ -0,0 +1,319 @@
/* 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/true_talk/tt_concept.h"
#include "titanic/true_talk/script_handler.h"
#include "titanic/true_talk/tt_script_base.h"
#include "titanic/true_talk/tt_word.h"
#include "titanic/titanic.h"
namespace Titanic {
TTconcept::TTconcept() : _string1(" "), _string2(" "),
_nextP(nullptr), _scriptP(nullptr), _wordP(nullptr), _word2P(nullptr), _status(SS_VALID),
_scriptType(ST_UNKNOWN_SCRIPT), _field14(0), _field1C(0), _field20(0), _field30(0), _field34(0) {
if (setStatus())
setScriptType(ST_UNKNOWN_SCRIPT);
else
reset();
}
TTconcept::TTconcept(TTscriptBase *script, ScriptType scriptType) :
_string1(" "), _string2(" "), _nextP(nullptr), _wordP(nullptr), _word2P(nullptr), _scriptP(nullptr),
_status(SS_VALID), _scriptType(ST_UNKNOWN_SCRIPT), _field14(0), _field1C(0), _field20(0), _field30(0),
_field34(0) {
if (!script->getStatus()) {
setScriptType(scriptType);
_scriptP = script;
if (scriptType == ST_UNKNOWN_SCRIPT && script->_id == 1)
_scriptType = ST_ROOM_SCRIPT;
}
if (_status)
reset();
}
TTconcept::TTconcept(TTword *word, ScriptType scriptType) :
_string1(" "), _string2(" "), _nextP(nullptr), _wordP(nullptr), _word2P(nullptr), _scriptP(nullptr),
_status(SS_VALID), _scriptType(ST_UNKNOWN_SCRIPT), _field14(0), _field1C(0), _field20(0),
_field30(0), _field34(0), _flag(false) {
if (!word || !setStatus() || word->getStatus()) {
_status = SS_5;
} else {
_status = initializeWordRef(word);
if (!_status)
setScriptType(scriptType);
}
if (_status)
reset();
}
TTconcept::TTconcept(TTconcept &src) :
_string1(src._string1), _string2(src._string2), _nextP(nullptr),
_wordP(nullptr), _word2P(nullptr), _scriptP(nullptr), _status(SS_VALID),
_scriptType(ST_UNKNOWN_SCRIPT), _field14(0), _field1C(0), _field20(0),
_field30(0), _field34(0), _flag(false) {
if (src.getStatus()) {
_status = SS_5;
} else {
if (setStatus()) {
_status = SS_VALID;
_scriptP = src._scriptP;
if (src._wordP) {
_status = initializeWordRef(src._wordP);
initialize(src);
}
}
}
if (_status)
reset();
}
TTconcept::~TTconcept() {
if (_word2P) {
_word2P->deleteSiblings();
delete _word2P;
}
delete _wordP;
if (_flag)
g_vm->_exeResources._owner->setParserConcept(this, nullptr);
}
void TTconcept::deleteSiblings() {
for (TTconcept *currP = _nextP, *nextP; currP; currP = nextP) {
nextP = currP->_nextP;
delete currP;
}
_nextP = nullptr;
}
bool TTconcept::setStatus() {
if (_string1.isValid() && _string2.isValid()) {
_status = SS_VALID;
return true;
} else {
_status = SS_11;
return false;
}
}
void TTconcept::setScriptType(ScriptType scriptType) {
_nextP = nullptr;
_field14 = 0;
_scriptType = scriptType;
_field1C = -1;
_field20 = 0;
_word2P = nullptr;
_field30 = 0;
_field34 = 0;
_flag = false;
_status = 0;
}
int TTconcept::initializeWordRef(TTword *word) {
delete _wordP;
_wordP = word->copy();
return 0;
}
void TTconcept::reset() {
delete _wordP;
_wordP = nullptr;
_scriptP = nullptr;
int oldStatus = _status;
setScriptType(ST_UNKNOWN_SCRIPT);
_status = oldStatus;
}
bool TTconcept::compareTo(const char *str) const {
return _wordP != nullptr &&
_wordP->compareTo(str);
}
bool TTconcept::compareTo(TTword *word) const {
if (_wordP && _wordP->compareTo(word->_text))
return true;
if (_scriptP && _scriptP->getId() == 1 && word->comparePronounTo(1))
return true;
return false;
}
void TTconcept::initialize(TTconcept &src) {
_nextP = src._nextP;
_field14 = src._field14;
_scriptType = src._scriptType;
_field1C = src._field1C;
_field20 = src._field20;
if (src._word2P) {
_word2P = src._word2P->copyWords();
if (src._word2P->getChainStatus())
_status = 11;
} else {
_word2P = nullptr;
}
_field30 = src._field30;
_field34 = src._field34;
if (src._flag) {
g_vm->_exeResources._owner->setParserConcept(this, &src);
src.setFlag(true);
_flag = true;
}
_status = src._status;
}
void TTconcept::copyFrom(TTconcept *src) {
if (this != src) {
if (src->getStatus()) {
_status = SS_5;
} else {
_string1 = src->_string1;
_string2 = src->_string2;
if (setStatus()) {
_scriptP = src->_scriptP;
if (src->_wordP) {
_status = initializeWordRef(src->_wordP);
initialize(*src);
} else {
_wordP = nullptr;
initialize(*src);
}
}
}
}
if (_status)
reset();
}
int TTconcept::setOwner(TTconcept *src) {
if (src->_wordP) {
TTword *newWord = src->_wordP->copy();
return setOwner(newWord, 1);
}
return 0;
}
int TTconcept::setOwner(TTword *src, bool dontDup) {
TTword *word = dontDup ? src : src->copy();
if (word) {
if (!_word2P) {
_word2P = word;
} else {
// Add word to end of word list
TTword *tailP = _word2P;
while (tailP->_nextP)
tailP = tailP->_nextP;
tailP->_nextP = word;
}
}
return 0;
}
bool TTconcept::checkWordId1() const {
return (_wordP && (_wordP->_id == 200 || _wordP->_id == 201 ||
_wordP->_id == 602 || _wordP->_id == 607)) ||
(_scriptP && _scriptP->_id <= 2);
}
bool TTconcept::checkWordId2() const {
return (_wordP && _wordP->_id == 204) || (_scriptP && _scriptP->getId() == 3);
}
bool TTconcept::checkWordId3() const {
return isWordClass(WC_ABSTRACT) || isWordClass(WC_ADJECTIVE) ||
(isWordClass(WC_ADVERB) && getTheWordId() != 910);
}
bool TTconcept::checkWordClass() const {
return _scriptP || (_wordP && (_wordP->_wordClass == WC_THING || _wordP->_wordClass == WC_PRONOUN));
}
const TTstring TTconcept::getText() {
if (_scriptP)
return _scriptP->getText();
else if (_wordP)
return _wordP->getText();
else
return TTstring();
}
TTconcept *TTconcept::findByWordId(int id) {
for (TTconcept *conceptP = this; conceptP; conceptP = conceptP->_nextP) {
if (conceptP->_wordP && conceptP->_wordP->_id == id)
return conceptP;
}
return nullptr;
}
TTconcept *TTconcept::findByWordClass(TTconcept *conceptP, WordClass wordClass) {
for (; conceptP; conceptP = conceptP->_nextP) {
if (conceptP->_wordP && conceptP->_wordP->_wordClass == wordClass)
return conceptP;
}
return nullptr;
}
TTconcept *TTconcept::findBy20(int val) {
for (TTconcept *conceptP = this; conceptP; conceptP = conceptP->_nextP) {
if (conceptP->_field20 == val)
return conceptP;
}
return nullptr;
}
bool TTconcept::isTheWordId(int id) const {
return _wordP && _wordP->_id == id;
}
int TTconcept::getTheWordId() const {
return _wordP ? _wordP->_id : 0;
}
bool isWordId(const TTconcept *conceptP, int id) {
return conceptP ? conceptP->isTheWordId(id) : 0;
}
int getWordId(const TTconcept *conceptP) {
return conceptP ? conceptP->getTheWordId() : 0;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,175 @@
/* 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_TT_CONCEPT_H
#define TITANIC_TT_CONCEPT_H
#include "titanic/true_talk/tt_string.h"
#include "titanic/true_talk/tt_word.h"
namespace Titanic {
enum ScriptType { ST_UNKNOWN_SCRIPT = 0, ST_ROOM_SCRIPT = 1, ST_NPC_SCRIPT = 2 };
class TTscriptBase;
class TTword;
class TTconcept {
private:
TTstring _string1;
int _field1C;
TTword *_word2P;
int _field30;
bool _flag;
int _status;
private:
/**
* Sets the status of the concept
*/
bool setStatus();
/**
* Sets the script type and resets other fields
*/
void setScriptType(ScriptType scriptType);
/**
* Sets up the concept for a word reference
*/
int initializeWordRef(TTword *word);
/**
* Resets the concept
*/
void reset();
/**
* Initialize inner data for the concept from a given source concept
*/
void initialize(TTconcept &src);
public:
TTconcept *_nextP;
TTscriptBase *_scriptP;
TTword *_wordP;
int _scriptType;
int _field14;
int _field20;
int _field34;
TTstring _string2;
public:
TTconcept();
TTconcept(TTscriptBase *script, ScriptType scriptType);
TTconcept(TTword *word, ScriptType scriptType = ST_UNKNOWN_SCRIPT);
TTconcept(TTconcept &src);
~TTconcept();
/**
* Destroys any attached sibling concepts to the given concept
*/
void deleteSiblings();
/**
* Copies data from a source concept
*/
void copyFrom(TTconcept *src);
/**
* Compares the name of the associated word, if any, to the passed string
*/
bool compareTo(const char *str) const;
/**
* Compares the concept to the specified word
*/
bool compareTo(TTword *word) const;
/**
* Set an owner for the concept
*/
int setOwner(TTconcept *src);
/**
* Set an owner for the concept
*/
int setOwner(TTword *src, bool dontDup);
/**
* Return the status of the concept
*/
int getStatus() const { return _status; }
/**
* True true if the concept is valid
*/
bool isValid() const { return _status == SS_VALID; }
/**
* Returns true if the word is of the specified class
*/
bool isWordClass(WordClass wordClass) const {
return _wordP && _wordP->isClass(wordClass);
}
void setFlag(bool val) { _flag = val; }
void set1C(int val) { _field1C = val; }
int get20() const { return _field20; }
int getState() const { return _field34; }
bool checkWordId1() const;
bool checkWordId2() const;
bool checkWordId3() const;
bool checkWordClass() const;
/**
* Return text assocaited with the concept's word or script
*/
const TTstring getText();
/**
* Find a word by Id
*/
TTconcept *findByWordId(int id);
/**
* Find a word by it's class
*/
static TTconcept *findByWordClass(TTconcept *conceptP, WordClass wordClass);
TTconcept *findBy20(int val);
/**
* Returns true if the concept has a word with a given Id
*/
bool isTheWordId(int id) const;
/**
* If a word is associated, return it's Id
*/
int getTheWordId() const;
};
extern bool isWordId(const TTconcept *conceptP, int id);
extern int getWordId(const TTconcept *conceptP);
} // End of namespace Titanic
#endif /* TITANIC_TT_CONCEPT_H */

View File

@@ -0,0 +1,151 @@
/* 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/true_talk/tt_concept_node.h"
#include "titanic/true_talk/script_handler.h"
#include "titanic/titanic.h"
namespace Titanic {
TTconceptNode::TTconceptNode() : _concept0P(_concepts[0]), _concept1P(_concepts[1]),
_concept2P(_concepts[2]), _concept3P(_concepts[3]), _concept4P(_concepts[4]),
_concept5P(_concepts[5]), _field18(0), _field1C(0), _nextP(nullptr), _status(0) {
Common::fill(&_concepts[0], &_concepts[6], (TTconcept *)nullptr);
}
TTconceptNode::TTconceptNode(const TTconceptNode &src) : _concept0P(_concepts[0]), _concept1P(_concepts[1]),
_concept2P(_concepts[2]), _concept3P(_concepts[3]), _concept4P(_concepts[4]),
_concept5P(_concepts[5]), _field18(0), _field1C(0), _nextP(nullptr), _status(0) {
Common::fill(&_concepts[0], &_concepts[6], (TTconcept *)nullptr);
if (src._status) {
_status = SS_5;
} else {
for (int idx = 0; idx < 6; ++idx) {
if (src._concepts[idx]) {
_concepts[idx] = new TTconcept(*src._concepts[idx]);
if (!_concepts[idx]->isValid())
_status = SS_11;
}
}
_field18 = src._field18;
_field1C = src._field1C;
_nextP = src._nextP;
}
}
void TTconceptNode::deleteSiblings() {
// Iterate through the linked chain of nodes, deleting each in turn
for (TTconceptNode *curP = _nextP, *nextP = nullptr; nextP; curP = nextP) {
nextP = curP->_nextP;
delete curP;
}
_nextP = nullptr;
}
TTconcept **TTconceptNode::setConcept(int conceptIndex, TTconcept *src) {
assert(conceptIndex >= 0 && conceptIndex <= 5);
TTconcept **conceptPP = &_concepts[conceptIndex];
if (src) {
bool isPronoun = false;
StringArray &pronouns = g_vm->_scriptHandler->_parser._pronouns;
for (uint idx = 0; idx < pronouns.size() && !isPronoun; ++idx) {
isPronoun = pronouns[idx] == src->getText();
}
CScriptHandler &scrHandler = *g_vm->_exeResources._owner;
if (!isPronoun) {
switch (conceptIndex) {
case 0:
delete scrHandler._concept2P;
scrHandler._concept2P = new TTconcept(*src);
break;
case 1:
delete scrHandler._concept4P;
scrHandler._concept4P = new TTconcept(*src);
break;
case 2:
delete scrHandler._concept1P;
scrHandler._concept1P = new TTconcept(*src);
break;
default:
break;
}
}
}
return conceptPP;
}
int TTconceptNode::replaceConcept(int mode, int conceptIndex, TTconcept *conceptP) {
TTconcept **conceptPP = setConcept(conceptIndex, conceptP);
if (mode == 0 || (mode == 1 && !*conceptPP)) {
if (!conceptP || !conceptP->isValid())
return SS_5;
if (mode == 0 && *conceptPP) {
delete *conceptPP;
}
*conceptPP = new TTconcept(*conceptP);
return (*conceptPP)->isValid() ? SS_VALID : SS_11;
} else {
return SS_1;
}
}
int TTconceptNode::changeConcept(int mode, TTconcept **conceptPP, int conceptIndex) {
TTconcept **newConceptPP = setConcept(conceptIndex, *conceptPP);
if (mode == 0 || (mode == 1 && !*newConceptPP)) {
if (!*conceptPP)
return SS_5;
delete *newConceptPP;
*newConceptPP = new TTconcept(**conceptPP);
return SS_VALID;
} else {
return SS_1;
}
}
bool TTconceptNode::createConcept(int mode, int conceptIndex, TTword *word) {
TTconcept *newConcept = new TTconcept(word, ST_UNKNOWN_SCRIPT);
TTconcept **conceptPP = setConcept(conceptIndex, newConcept);
if (mode == 0 || (mode == 1 && !*conceptPP)) {
delete *conceptPP;
*conceptPP = newConcept;
return false;
} else {
delete newConcept;
return true;
}
}
} // End of namespace Titanic

View File

@@ -0,0 +1,75 @@
/* 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_TT_CONCEPT_NODE_H
#define TITANIC_TT_CONCEPT_NODE_H
#include "titanic/true_talk/tt_concept.h"
namespace Titanic {
class TTconceptNode {
public:
TTconcept *_concepts[6];
TTconcept *&_concept0P;
TTconcept *&_concept1P;
TTconcept *&_concept2P;
TTconcept *&_concept3P;
TTconcept *&_concept4P;
TTconcept *&_concept5P;
int _field18;
int _field1C;
TTconceptNode *_nextP;
int _status;
public:
TTconceptNode();
TTconceptNode(const TTconceptNode &src);
virtual ~TTconceptNode() {}
/**
* Delete any sibling chain attached to this node
*/
void deleteSiblings();
void set18(int val) { _field18 = val; }
int get18() const { return _field18; }
/**
* Returns true if the node is valid
*/
bool isValid() const { return _status == SS_VALID; }
TTconcept **setConcept(int conceptIndex, TTconcept *src);
int replaceConcept(int mode, int conceptIndex, TTconcept *conceptP);
int changeConcept(int mode, TTconcept **conceptPP, int conceptIndex);
bool createConcept(int mode, int conceptIndex, TTword *word);
int concept1WordId() const {
return getWordId(_concept1P);
}
int concept5WordId() const {
return getWordId(_concept5P);
}
};
} // End of namespace Titanic
#endif /* TITANIC_TT_CONCEPT_NODE_H */

View File

@@ -0,0 +1,35 @@
/* 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/true_talk/tt_hist.h"
#include "titanic/true_talk/tt_sentence.h"
namespace Titanic {
TThist::TThist(TTsentence *sentence) : _status(0) {
_sentence = new TTsentence(sentence);
}
TThist::~TThist() {
delete _sentence;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,46 @@
/* 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_TT_HIST_H
#define TITANIC_TT_HIST_H
namespace Titanic {
class TTsentence;
class TThist {
protected:
int _field0;
TTsentence *_sentence;
int _status;
public:
TThist(TTsentence *sentence);
virtual ~TThist();
};
class TTscriptHist : public TThist {
public:
TTscriptHist(TTsentence *sentence) : TThist(sentence) {}
};
} // End of namespace Titanic
#endif /* TITANIC_TT_HIST_H */

View File

@@ -0,0 +1,69 @@
/* 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/true_talk/tt_major_word.h"
namespace Titanic {
bool TTmajorWord::_staticFlag;
TTmajorWord::TTmajorWord(const TTstring &str, WordClass wordClass, int val2, int val3) :
TTword(str, wordClass, val2), _field2C(val3) {
}
TTmajorWord::TTmajorWord(const TTmajorWord *src) : TTword(src) {
if (src->getStatus()) {
_field2C = 0;
_status = SS_5;
} else {
_field2C = src->_field2C;
}
}
int TTmajorWord::saveData(SimpleFile *file, int val) const {
int result = TTword::save(file);
if (!result) {
file->writeFormat("%1.0d", val);
file->writeFormat("%c", '\n');
if (_synP)
result = _synP->save(file);
}
return result;
}
TTword *TTmajorWord::copy() const {
TTmajorWord *returnWordP = new TTmajorWord(this);
returnWordP->_status = _status;
if (!_status) {
_staticFlag = false;
return returnWordP;
} else if (_status == SS_13 && !_staticFlag) {
_staticFlag = true;
delete returnWordP;
return copy();
} else {
delete returnWordP;
return nullptr;
}
}
} // End of namespace Titanic

View 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_TT_MAJOR_WORD_H
#define TITANIC_TT_MAJOR_WORD_H
#include "titanic/true_talk/tt_word.h"
namespace Titanic {
class TTmajorWord : public TTword {
private:
static bool _staticFlag;
protected:
int _field2C;
protected:
/**
* Dumps data for the word to a file
*/
int saveData(SimpleFile *file, int val) const;
public:
TTmajorWord(const TTstring &str, WordClass wordClass, int val2, int val3);
TTmajorWord(const TTmajorWord *src);
/**
* Creates a copy of the word
*/
TTword *copy() const override;
bool proc2(int val) const override { return _field2C == val; }
};
} // End of namespace Titanic
#endif /* TITANIC_TT_MAJOR_WORD_H */

View File

@@ -0,0 +1,89 @@
/* 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 "common/textconsole.h"
#include "titanic/true_talk/tt_node.h"
namespace Titanic {
TTnode::TTnode() : _priorP(nullptr), _nextP(nullptr) {
}
TTnode::~TTnode() {
detach();
}
void TTnode::addToTail(TTnode *newNode) {
TTnode *tail = getTail();
tail->_nextP = newNode;
newNode->_priorP = this;
}
void TTnode::addToHead(TTnode *newNode) {
TTnode *head = getHead();
head->_priorP = newNode;
newNode->_nextP = head;
}
void TTnode::detach() {
if (_priorP)
_priorP->_nextP = _nextP;
if (_nextP)
_nextP->_priorP = _priorP;
}
void TTnode::deleteSiblings() {
// Detach current node from prior one, if there is one
if (_priorP)
_priorP->_nextP = nullptr;
// Iterate through the linked chain of nodes, deleting each in turn
while (_nextP) {
TTnode *next = _nextP;
_nextP = next->_nextP;
delete next;
}
}
TTnode *TTnode::getHead() {
if (_priorP == nullptr)
return this;
TTnode *node = _priorP;
while (node->_priorP)
node = node->_priorP;
return node;
}
TTnode *TTnode::getTail() {
if (_nextP == nullptr)
return this;
TTnode *node = _nextP;
while (node->_nextP)
node = node->_nextP;
return node;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,68 @@
/* 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_TT_NODE_H
#define TITANIC_TT_NODE_H
namespace Titanic {
class TTnode {
public:
TTnode *_priorP;
TTnode *_nextP;
public:
TTnode();
virtual ~TTnode();
/**
* Adds a new node at the beginning of the linked list
*/
void addToHead(TTnode *newNode);
/**
* Links the passed node to this node as a linked list
*/
void addToTail(TTnode *newNode);
/**
* Detaches a node from any predecessor and/or successor
*/
void detach();
/**
* Delete any sibling chain attached to this node
*/
void deleteSiblings();
/**
* Returns the first node at the beginning of a linked list of nodes
*/
TTnode *getHead();
/**
* Returns the final node at the end of the linked list of nodes
*/
TTnode *getTail();
};
} // End of namespace Titanic
#endif /* TITANIC_TT_NODE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,365 @@
/* 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_TT_NPC_SCRIPT_H
#define TITANIC_TT_NPC_SCRIPT_H
#include "titanic/support/simple_file.h"
#include "titanic/true_talk/tt_script_base.h"
#include "titanic/true_talk/script_support.h"
namespace Titanic {
#define DIALS_ARRAY_COUNT 10
class CGameManager;
class CPetControl;
class TTroomScript;
struct TTnpcData {
private:
int _array[136];
public:
TTnpcData();
int &operator[](int idx) { return _array[idx]; }
int *getSlot(int idx) { return &_array[16 + idx * 4]; }
void resetFlags();
void copyData();
};
class TTnpcScriptBase : public TTscriptBase {
protected:
int _field54;
int _val2;
public:
int _charId;
public:
TTnpcScriptBase(int charId, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4,
int v5, int v6, int v7);
/**
* Chooses and adds a conversation response based on a specified tag Id.
*/
virtual int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) = 0;
/**
* Does NPC specific processing of the parsed sentence
*/
virtual int process(const TTroomScript *roomScript, const TTsentence *sentence) = 0;
virtual int proc8() const = 0;
/**
* Called when the script/id changes
*/
virtual ScriptChangedResult scriptChanged(uint id) = 0;
/**
* Called when the script/id changes
*/
virtual ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) = 0;
virtual int proc11() const = 0;
virtual int proc12() const = 0;
int charId() const { return _charId; }
};
class TTnpcScript : public TTnpcScriptBase {
private:
int translateByArray(int id);
protected:
static TTsentenceEntries *_defaultEntries;
protected:
Common::Array<TTnpcScriptResponse> _responses;
int _valuesPerResponse;
Common::Array<TTscriptRange> _ranges;
TTscriptMappings _mappings;
TTsentenceEntries _entries;
TTtagMappings _tagMappings;
TTwordEntries _words;
TThandleQuoteEntries _quotes;
int _entryCount;
int _field68;
int _field6C;
int _rangeResetCtr;
int _currentDialNum;
int _dialDelta;
int _field7C;
const char *_itemStringP;
int _dialValues[DIALS_ARRAY_COUNT];
TTnpcData _data;
bool _field2CC;
protected:
/**
* Loads response data for the NPC from the given resource
*/
void loadResponses(const char *name, int valuesPerResponse = 1);
/**
* Load ranges data for the NPC from the given resource
*/
void loadRanges(const char *name);
/**
* Reset script flags
*/
void resetFlags();
/**
* Setup dials
*/
void setupDials(int dial1, int dial2, int dial3);
static int getRoom54(int roomId);
/**
* Perform test on various state values
*/
int getValue(int testNum) const;
/**
* Gets a random number between 1 and a given max
*/
uint getRandomNumber(int max) const;
/**
* Gets a random number of 0 or 1
*/
uint getRandomBit() const {
return getRandomNumber(2) - 1;
}
/**
* Returns a dialogue Id by script tag value Id
*/
uint getDialogueId(uint tagId);
/**
* Returns a pointer to the PET control
*/
static CPetControl *getPetControl(CGameManager *gameManager);
/**
* Adds a new item to the list of number ranges
*/
void addRange(uint id, const Common::Array<uint> &values, bool isRandom, bool isSequential);
/**
* Finds an entry in the list of prevoiusly registered number ranges
*/
TTscriptRange *findRange(uint id);
/**
* Scans through a list of sentence entries for a matching standardized response
*/
int processEntries(const TTsentenceEntries *entries, uint entryCount, const TTroomScript *roomScript, const TTsentence *sentence);
/**
* Scans through a list of sentence entries for a matching standardized response
*/
int processEntries(const TTroomScript *roomScript, const TTsentence *sentence) {
return processEntries(&_entries, _entryCount, roomScript, sentence);
}
bool defaultProcess(const TTroomScript *roomScript, const TTsentence *sentence);
void checkItems(const TTroomScript *roomScript, const TTsentence *sentence);
/**
* Adds a random conversation response
*/
bool addRandomResponse(bool flag);
/**
* Updates the current dial with the given delta
*/
void updateCurrentDial(bool changeDial);
bool fn10(bool flag);
static bool sentence2C(const TTsentence *sentence);
/**
* Gets the True Talk state value
*/
bool getStateValue() const;
/**
* Gets the assigned room's room, floor, and elevator number
*/
void getAssignedRoom(int *roomNum, int *floorNum, int *elevatorNum) const;
/**
* Uses a porition of the state _array to set up a new response
*/
void setResponseFromArray(int index, int id);
public:
static void init();
static void deinit();
public:
TTnpcScript(int charId, const char *charClass, int v2,
const char *charName, int v3, int val2, int v4,
int v5, int v6, int v7);
void addResponse(int id) override;
/**
* Chooses and adds a conversation response based on a specified tag Id.
* This default implementation does a lookup into a list of known tags,
* and chooses a random dialogue Id from the available ones for that tag
*/
int chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) override;
/**
* Does NPC specific processing of the parsed sentence
*/
int process(const TTroomScript *roomScript, const TTsentence *sentence) override;
int proc8() const override;
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(uint id) override {
return SCR_2;
}
/**
* Called when the script/id changes
*/
ScriptChangedResult scriptChanged(const TTroomScript *roomScript, uint id) override {
return SCR_2;
}
int proc11() const override;
int proc12() const override;
/**
* Translate a passed Id to a dialogue Id if necessary,
* and adds it to the response
*/
virtual void selectResponse(int id);
/**
* Handles scanning the word list for a given Id, and if
* found adds it to the sentence concept list
*/
virtual bool handleWord(uint id) const;
virtual int handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
uint tag1, uint tag2, uint remainder);
/**
* Returns true if the NPC's dial region affects quote responses
*/
virtual bool isQuoteDialled() const { return false; }
/**
* Given an Id for a previously registered set of random number values,
* picks one of the array values and returns it.. depending on flags,
* either a random value, or each value in turn
*/
virtual uint getRangeValue(uint id);
/**
* Resets the prior used index for the specified range
*/
virtual void resetRange(int id);
/**
* Handles updating NPC state based on specified dialogue Ids and dial positions
*/
virtual int updateState(uint oldId, uint newId, int index);
/**
* Handles getting a pre-response
*/
virtual int preResponse(uint id);
/**
* Returns a bitset of the dials being off or not
*/
virtual uint getDialsBitset() const { return 0; }
virtual const TTscriptMapping *getMapping(int index);
virtual int doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence);
/**
* Handles any post-response NPC processing
*/
virtual void postResponse(int v1, const TTsentenceEntry *entry, const TTroomScript *roomScript, const TTsentence *sentence) {}
virtual void save(SimpleFile *file);
virtual void load(SimpleFile *file);
virtual void saveBody(SimpleFile *file);
virtual void loadBody(SimpleFile *file);
/**
* Returns the number of range records that are non-random
*/
virtual int getRangesCount() const;
/**
* Sets a given dial to be pointing in a specified region (0 to 2)
*/
virtual void setDialRegion(int dialNum, int region);
/**
* Sets the value for an NPC's dial
*/
virtual void setDial(int dialNum, int value);
/**
* Returns a dial's region number
*/
virtual int getDialRegion(int dialNum) const;
/**
* Gets the value for a dial
* @param dialNum Dial number
* @param randomizeFlag If set, introduces a slight random variance so that
* the displayed dial will oscillate randomly around it's real level
*/
virtual int getDialLevel(uint dialNum, bool randomizeFlag = true);
/**
* Handles a randomzied response
*/
virtual bool randomResponse(uint index);
virtual uint translateId(uint id) const;
void preLoad();
/**
* Called with the script and id changes
*/
ScriptChangedResult notifyScript(TTroomScript *roomScript, int id) {
return scriptChanged(roomScript, id);
}
};
} // End of namespace Titanic
#endif /* TITANIC_TT_NPC_SCRIPT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,219 @@
/* 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_TT_PARSER_H
#define TITANIC_TT_PARSER_H
#include "titanic/true_talk/tt_node.h"
#include "titanic/true_talk/tt_pronoun.h"
#include "titanic/true_talk/tt_sentence.h"
#include "titanic/true_talk/tt_string.h"
namespace Titanic {
enum NumberFlag { NF_1 = 1, NF_2 = 2, NF_4 = 4, NF_8 = 8, NF_10 = 0x10 };
enum ParserAction {
NO_ACTION = 0, CHECK_COMMAND_FORM, EXPECT_THING, OBJECT_IS_TO,
SEEK_ACTOR, SEEK_OBJECT, SEEK_OBJECT_OVERRIDE, SEEK_TO,
SEEK_FROM, SEEK_TO_OVERRIDE, SEEK_FROM_OVERRIDE, SEEK_LOCATION,
SEEK_OWNERSHIP, SEEK_STATE, SEEK_MODIFIERS, SEEK_NEW_FRAME,
SEEK_STATE_OBJECT, SET_ACTION, SET_COLOR, ACTOR_IS_TO,
ACTOR_IS_FROM, ACTOR_IS_OBJECT, STATE_IDENTITY,
WORD_TYPE_IS_SENTENCE_TYPE, COMPLEX_VERB
};
class CScriptHandler;
class TTconcept;
struct NumberEntry {
CString _text;
int _value;
int _flags;
NumberEntry() : _value(0), _flags(0) {}
NumberEntry(const CString &text, int value, int flags) :
_text(text), _value(value), _flags(flags) {}
};
typedef Common::Array<NumberEntry> NumberArray;
class TTparserNode : public TTnode {
public:
uint _tag;
public:
TTparserNode() : TTnode(), _tag(0) {}
TTparserNode(uint tag) : TTnode(), _tag(tag) {}
};
class TTparser {
private:
StringArray _replacements1;
StringArray _replacements2;
StringArray _replacements3;
StringArray _replacements4;
StringArray _phrases;
NumberArray _numbers;
TTparserNode *_nodesP;
TTconcept *_conceptP;
TTconcept *_currentConceptP;
private:
/**
* Clear the parser
*/
void clear();
/**
* Load the data for a given array resource
*/
void loadArray(StringArray &arr, const CString &name);
/**
* Loads the various replacement string data arrays
*/
void loadArrays();
/**
* Normalizes a passed input, taking care of things like removing extra
* spaces and lowercasing everything
*/
int normalize(TTsentence *sentence);
/**
* Submethod called by normalize to handle expanding contacted word pairs
* like can't, should've, and so on.
*/
bool normalizeContraction(const TTstring &srcLine, int &srcIndex, TTstring &destLine);
/**
* Checks for what is likely special developer cheat codes
*/
static int isEmoticon(const TTstring &str, int &index);
/**
* Checks if any word within a passed line has an entry in the list of replacements,
* and if found, replaces it with it's equivalent replacement string
* @param line Line to check
* @param strings List of strings to check for. Strings come in pairs, with the
* first being the string to match, and the second the replacement
*/
static void searchAndReplace(TTstring &line, const StringArray &strings);
/**
* Checks the string starting at a given index for any word in the passed string array,
* and if found, replaces it in the line with it's replacement
* @param line Line to check
* @param startIndex Starting index in the start to check
* @param strings List of strings to check for. Strings come in pairs, with the
* first being the string to match, and the second the replacement
* @returns Index of the start of the following word
*/
static int searchAndReplace(TTstring &line, int startIndex, const StringArray &strings);
/**
* Checks the string starting at a given index for a number representation
* such as roman numericals, spelled out numbers, etc. and replaces it with
* a plain decimal representation.
* @param line Line to check
* @param startIndex Starting index in the start to check
* @returns Index of the start of the following word, or -1 if at end of line
*/
int replaceNumbers(TTstring &line, int startIndex);
/**
* Checks the string starting at a given index for a number representation
* such as roman numericals, spelled out numbers, etc. and replaces it with
* a plain decimal representation.
* @param line Line to check
* @param startIndex Starting index in the start to check
* @returns Pointer to matching number entry, if match occurred
*/
const NumberEntry *replaceNumbers2(TTstring &line, int *startIndex);
int loadRequests(TTword *word);
int considerRequests(TTword *word);
int processRequests(TTword *word);
int addToConceptList(TTword *word);
int checkReferent(TTpronoun *pronoun);
/**
* Creates a new parser node, and adds it to the parser's list
*/
void addNode(uint tag);
/**
* Add a concept node
*/
int addConcept(TTconcept *c);
/**
* Detaches a concept from the main concept list if prseent, then deletes it
*/
void removeConcept(TTconcept *c);
/**
* Detaches a node from the main node list
*/
void removeNode(TTparserNode *node);
/**
* Handles any preprocessing for the German version
* @param line Line to check and update
*/
void preprocessGerman(TTstring &line);
int processModifiers(int modifier, TTword *word);
int checkForAction();
int fn2(TTword *word);
bool checkConcept2(TTconcept *conceptP, int conceptMode);
int filterConcepts(int conceptMode, int conceptIndex);
bool resetConcept(TTconcept **conceptPP, int conceptIndex);
public:
CScriptHandler *_owner;
TTsentenceConcept *_sentenceConcept;
TTsentence *_sentence;
int _fieldC;
int _field10;
int _field14;
TTword *_currentWordP;
StringArray _pronouns;
public:
TTparser(CScriptHandler *owner);
~TTparser();
/**
* Preprocesses the passed input text, to handle things like lowercasing
* all the words, and replcaing common slang with their full equivalents
*/
int preprocess(TTsentence *sentence);
int findFrames(TTsentence *sentence);
/**
* Called when a concept is copied from one to another
*/
void conceptChanged(TTconcept *newConcept, TTconcept *oldConcept);
};
} // End of namespace Titanic
#endif /* TITANIC_TT_PARSER_H */

View 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/>.
*
*/
#include "titanic/true_talk/tt_picture.h"
namespace Titanic {
bool TTpicture::_staticFlag;
TTpicture::TTpicture(const TTstring &str, WordClass wordClass, int val2, int val3, int val4, int val5, int val6) :
TTmajorWord(str, wordClass, val2, val4), _tag(val3), _field30(val5), _field3C(val6),
_field38(0) {
}
TTpicture::TTpicture(const TTpicture *src) : TTmajorWord(src) {
if (getStatus()) {
_tag = 0;
_field30 = 0;
_field38 = 0;
_field3C = 0;
_status = SS_5;
} else {
_tag = src->_tag;
_field30 = src->_field30;
_field38 = src->_field38;
_field3C = src->_field3C;
}
}
int TTpicture::load(SimpleFile *file) {
CString str;
int val1, val2;
if (!TTword::load(file, WC_THING) && file->scanf("%s %d %d", &str, &val1, &val2)) {
_tag = readNumber(str.c_str());
_field30 = val1;
_field3C = val2;
return 0;
} else {
return 3;
}
}
TTword *TTpicture::copy() const {
TTpicture *returnWordP = new TTpicture(this);
returnWordP->_status = _status;
if (!_status) {
_staticFlag = false;
return returnWordP;
} else if (_status == SS_13 && !_staticFlag) {
_staticFlag = true;
delete returnWordP;
return copy();
} else {
delete returnWordP;
return nullptr;
}
}
bool TTpicture::checkTag() const {
return _tag == MKTAG('S', 'E', 'X', 'X') ||
_tag == MKTAG('E', 'X', 'C', 'R') ||
_tag == MKTAG('P', 'P', 'R', 'T') ||
_tag == MKTAG('B', 'L', 'A', 'S');
}
bool TTpicture::compareTagTo(uint tag) const {
return _tag == tag;
}
uint TTpicture::getTag() const {
return _tag;
}
bool TTpicture::proc9(int val) const {
return _field3C == val;
}
int TTpicture::proc10() const {
return _field3C;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,73 @@
/* 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_TT_PICTURE_H
#define TITANIC_TT_PICTURE_H
#include "titanic/true_talk/tt_major_word.h"
namespace Titanic {
class TTpicture : public TTmajorWord {
private:
static bool _staticFlag;
protected:
int _field30;
uint _tag;
int _field38;
int _field3C;
public:
TTpicture(const TTstring &str, WordClass wordClass, int val2, int val3, int val4, int val5, int val6);
TTpicture(const TTpicture *src);
/**
* Load the word
*/
int load(SimpleFile *file);
/**
* Creates a copy of the word
*/
TTword *copy() const override;
/**
* Checks whether the word's tag is a known type
*/
bool checkTag() const override;
/**
* Compare the word's tag to a given tag value
*/
bool compareTagTo(uint tag) const override;
/**
* Return the tag associated with the word
*/
uint getTag() const override;
bool proc9(int val) const override;
int proc10() const override;
};
} // End of namespace Titanic
#endif /* TITANIC_TT_PICTURE_H */

View 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/>.
*
*/
#include "titanic/true_talk/tt_pronoun.h"
namespace Titanic {
bool TTpronoun::_staticFlag;
TTpronoun::TTpronoun(TTstring &str, WordClass wordClass, int val2, int val3, int val4) :
TTmajorWord(str, wordClass, val2, val3), _field30(val4) {
}
TTpronoun::TTpronoun(const TTpronoun *src) : TTmajorWord(src) {
if (src->getStatus()) {
_field30 = 0;
_status = SS_5;
} else {
_field30 = src->_field30;
}
}
int TTpronoun::load(SimpleFile *file) {
int val;
if (!TTword::load(file, WC_PRONOUN) && file->scanf("%d", &val)) {
if (val >= 0 && val <= 12) {
_field30 = val;
return 0;
} else {
return 5;
}
} else {
return 8;
}
}
TTword *TTpronoun::copy() const {
TTpronoun *returnWordP = new TTpronoun(this);
returnWordP->_status = _status;
if (!_status) {
_staticFlag = false;
return returnWordP;
} else if (_status == SS_13 && !_staticFlag) {
_staticFlag = true;
delete returnWordP;
return copy();
} else {
delete returnWordP;
return nullptr;
}
}
} // End of namespace Titanic

View 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_TT_PRONOUN_H
#define TITANIC_TT_PRONOUN_H
#include "titanic/true_talk/tt_major_word.h"
namespace Titanic {
class TTpronoun : public TTmajorWord {
private:
static bool _staticFlag;
protected:
int _field30;
public:
TTpronoun(TTstring &str, WordClass wordClass, int val2, int val3, int val4);
TTpronoun(const TTpronoun *src);
/**
* Load the word
*/
int load(SimpleFile *file);
int getVal() const { return _field30; }
/**
* Creates a copy of the word
*/
TTword *copy() const override;
bool comparePronounTo(int val) const override {
return _field30 == val;
}
/**
* Dumps data associated with the word to file
*/
int save(SimpleFile *file) const override {
return saveData(file, _field30);
}
};
} // End of namespace Titanic
#endif /* TITANIC_TT_WORD_H */

View File

@@ -0,0 +1,145 @@
/* 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/true_talk/tt_quotes.h"
#include "titanic/support/files_manager.h"
#include "titanic/titanic.h"
#include "common/algorithm.h"
namespace Titanic {
TTquotes::TTquotes() : _loaded(false), _dataP(nullptr), _dataSize(0),
_field544(0) {
Common::fill(&_tags[0], &_tags[256], 0);
}
TTquotes::~TTquotes() {
delete[] _dataP;
}
void TTquotes::load() {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/JRQUOTES");
size_t size = r->readUint32LE();
_loaded = true;
_dataSize = _field544 = size;
_dataP = new char[size + 0x10];
for (int idx = 0; idx < 256; ++idx)
_tags[idx] = r->readUint32LE();
for (int charIdx = 0; charIdx < 26; ++charIdx) {
TTquotesLetter &letter = _alphabet[charIdx];
int count = r->readUint32LE();
// Load the list of entries for the given letter
letter._entries.resize(count);
for (int idx = 0; idx < count; ++idx) {
letter._entries[idx]._tagIndex = r->readByte();
letter._entries[idx]._maxSize = r->readByte();
letter._entries[idx]._strP = _dataP + r->readUint32LE();
}
}
// Read in buffer and then decode it
r->read((byte *)_dataP, _dataSize);
for (size_t idx = 0; idx < _dataSize; idx += 4)
WRITE_LE_UINT32((byte *)_dataP + idx, READ_LE_UINT32((const byte *)_dataP + idx) ^ 0xA55A5AA5);
delete r;
}
int TTquotes::find(const char *str) const {
if (!str || !*str)
return 0;
// Find start and end of string
const char *startP = str, *endP = str;
while (*endP)
++endP;
do {
int tagId = find(startP, endP);
if (tagId)
return tagId;
// Move to next following space or end of string
while (*startP && *startP != ' ')
++startP;
// If it's a space, then move past it to start of next word
while (*startP && *startP == ' ')
++startP;
} while (*startP);
// No match
return 0;
}
int TTquotes::find(const char *startP, const char *endP) const {
int size = endP - startP;
if (size < 3)
return 0;
uint index = MIN((uint)(*startP - 'a'), (uint)25);
const TTquotesLetter &letter = _alphabet[index];
if (letter._entries.empty())
// No entries for the letter, so exit immediately
return 0;
int maxSize = size + 4;
for (uint idx = 0; idx < letter._entries.size(); ++idx) {
const TTquotesEntry &entry = letter._entries[idx];
if (entry._maxSize > maxSize)
continue;
const char *srcP = startP;
const char *destP = entry._strP;
int srcIndex = index != 25 ? 1 : 0, destIndex = 0;
if (*destP) {
do {
if (!srcP[srcIndex]) {
break;
} else if (srcP[srcIndex] == '*') {
++srcIndex;
} else if (destP[destIndex] == '-') {
++destIndex;
if (srcP[srcIndex] == ' ')
++srcIndex;
} else if (srcP[srcIndex] != destP[destIndex]) {
break;
} else {
++destIndex;
++srcIndex;
}
} while (destP[destIndex]);
if (!destP[destIndex] && (srcP[srcIndex] <= '*' ||
(srcP[srcIndex] == 's' && srcP[srcIndex + 1] <= '*')))
return _tags[entry._tagIndex];
}
}
return 0;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,76 @@
/* 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_TT_QUOTES_H
#define TITANIC_TT_QUOTES_H
#include "common/scummsys.h"
#include "common/stream.h"
#include "titanic/support/string.h"
namespace Titanic {
class TTquotes {
struct TTquotesEntry {
byte _tagIndex, _maxSize;
const char *_strP;
TTquotesEntry() : _tagIndex(0), _maxSize(0), _strP(nullptr) {}
};
struct TTquotesLetter {
Common::Array<TTquotesEntry> _entries;
int _field4;
int _field8;
TTquotesLetter() : _field4(0), _field8(0) {}
};
private:
TTquotesLetter _alphabet[26];
uint _tags[256];
char *_dataP;
size_t _dataSize;
int _field544;
private:
/**
* Test whether a substring contains one of the quotes,
* and if so, returns the 4-character tag Id associated with it
*/
int find(const char *startP, const char *endP) const;
public:
bool _loaded;
public:
TTquotes();
~TTquotes();
/**
* Load quotes data resource
*/
void load();
/**
* Test whether a passed string contains one of the quotes,
* and if so, returns the 4-character tag Id associated with it
*/
int find(const char *str) const;
};
} // End of namespace Titanic
#endif /* TITANIC_TT_QUOTES_H */

View File

@@ -0,0 +1,214 @@
/* 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/true_talk/tt_quotes_tree.h"
#include "titanic/support/files_manager.h"
#include "titanic/titanic.h"
#include "common/algorithm.h"
namespace Titanic {
/**
* Specifies the starting index for each of the three main trees
*/
static uint TABLE_INDEXES[3] = { 922, 1015, 1018 };
void TTquotesTree::load() {
Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/TREE");
for (int idx = 0; idx < QUOTES_TREE_COUNT; ++idx) {
TTquotesTreeEntry &rec = _entries[idx];
assert(r->pos() < r->size());
rec._id = r->readUint32LE();
if (rec._id == 0) {
// Nothing needed
} else {
byte type = r->readByte();
if (type == 0) {
// Index to sub-table
rec._subTable = &_entries[0] + r->readUint32LE();
} else {
// Read in string for entry
char c;
while ((c = r->readByte()) != '\0')
rec._string += c;
}
}
}
assert(r->pos() == r->size());
delete r;
}
int TTquotesTree::search(const char *str, QuoteTreeNum treeNum,
TTtreeResult *buffer, uint tagId, uint *remainder) {
const TTquotesTreeEntry *bTree = &_entries[TABLE_INDEXES[treeNum]];
if (!search1(&str, bTree, buffer, tagId) || !buffer->_treeItemP)
return -1;
if (remainder) {
for (; *str; ++str) {
if (*str >= 'a' && *str != 's')
*remainder += *str;
}
}
return buffer->_treeItemP->_id & 0xffffff;
}
bool TTquotesTree::search1(const char **str, const TTquotesTreeEntry *bTree,
TTtreeResult *buffer, uint tagId) {
buffer->_treeItemP = nullptr;
(buffer + 1)->_treeItemP = nullptr;
const char *strP = *str;
bool flag = false;
for (uint mode = bTree->_id >> 24; mode != 0;
++bTree, mode = bTree->_id >> 24) {
switch (mode) {
case 1:
if (compareWord(str, bTree->_string.c_str()))
flag = true;
break;
case 2:
compareWord(str, bTree->_string.c_str());
break;
case 5:
if (READ_LE_UINT32(bTree->_string.c_str()) == tagId)
flag = true;
break;
case 7:
if (search1(str, bTree->_subTable, buffer + 1, tagId))
flag = true;
break;
case 8:
if (search2(str, bTree->_subTable, buffer + 1, tagId))
flag = true;
break;
default:
break;
}
if (flag) {
buffer->_treeItemP = bTree;
return true;
}
}
*str = strP;
return false;
}
bool TTquotesTree::search2(const char **str, const TTquotesTreeEntry *bTree,
TTtreeResult *buffer, uint tagId) {
buffer->_treeItemP = bTree;
(buffer + 1)->_treeItemP = nullptr;
const char *strP = *str;
bool flag = false;
for (uint mode = bTree->_id >> 24; mode != 0;
++bTree, mode = bTree->_id >> 24) {
switch (mode) {
case 0:
return true;
case 1:
if (compareWord(str, bTree->_string.c_str()))
flag = true;
break;
case 2:
compareWord(str, bTree->_string.c_str());
break;
case 5:
if (READ_LE_UINT32(bTree->_string.c_str()) == tagId)
flag = true;
break;
case 7:
if (search1(str, bTree->_subTable, buffer + 1, tagId))
flag = true;
break;
case 8:
if (search2(str, bTree->_subTable, buffer + 1, tagId))
flag = true;
break;
default:
break;
}
if (flag) {
buffer->_treeItemP = nullptr;
*str = strP;
return false;
}
}
return true;
}
bool TTquotesTree::compareWord(const char **str, const char *refStr) {
// Skip over any spaces
const char *strP = *str;
while (*strP && *strP == ' ')
++strP;
*str = strP;
// Compare against the reference string
while (*strP && *refStr && *refStr != '*') {
if (*refStr == '-') {
if (*strP == ' ')
++strP;
} else if (*strP == *refStr) {
++strP;
} else {
return false;
}
}
if (*refStr && *refStr != '*')
return false;
if (!*refStr && *strP && *strP != ' ')
return false;
if (*refStr == '*') {
// Skip over to the end of the word
while (*strP && *strP != ' ')
++strP;
}
// Pass out the new updated string position
*str = strP;
return true;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,83 @@
/* 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_TT_QUOTES_TREE_H
#define TITANIC_TT_QUOTES_TREE_H
#include "common/scummsys.h"
#include "common/stream.h"
#include "titanic/support/string.h"
namespace Titanic {
#define QUOTES_TREE_COUNT 1022
enum QuoteTreeNum { TREE_1 = 0, TREE_2 = 1, TREE_3 = 2 };
struct TTquotesTreeEntry {
uint _id;
TTquotesTreeEntry *_subTable;
CString _string;
TTquotesTreeEntry() : _id(0), _subTable(nullptr) {}
};
class TTtreeResult {
public:
int _id;
const TTquotesTreeEntry *_treeItemP;
public:
TTtreeResult() : _id(0), _treeItemP(nullptr) {}
};
class TTquotesTree {
private:
TTquotesTreeEntry _entries[QUOTES_TREE_COUNT];
private:
/**
* First inner search method
*/
bool search1(const char **str, const TTquotesTreeEntry *bTree,
TTtreeResult *buffer, uint tagId);
/**
* Second inner search method
*/
bool search2(const char **str, const TTquotesTreeEntry *bTree,
TTtreeResult *buffer, uint tagId);
/**
* Compare the current word in the string against a specified word
*/
bool compareWord(const char **str, const char *refStr);
public:
/**
* Load data for the quotes tree
*/
void load();
int search(const char *str, QuoteTreeNum treeNum,
TTtreeResult *buffer, uint tagId, uint *remainder);
};
} // End of namespace Titanic
#endif /* TITANIC_TT_QUOTES_TREE_H */

View File

@@ -0,0 +1,76 @@
/* 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/true_talk/tt_response.h"
namespace Titanic {
TTresponse::TTresponse(const TTstring &src) : _field0(0), _text(src),
_dialogueId(0), _nextP(nullptr), _linkP(nullptr) {
}
TTresponse::TTresponse(int dialogueId, int val2) : _field0(val2), _text(" "),
_dialogueId(dialogueId), _nextP(nullptr), _linkP(nullptr) {
}
TTresponse::TTresponse(const TTresponse *src) : _field0(src->_field0),
_text(src->_text), _dialogueId(src->_dialogueId), _nextP(src->_nextP),
_linkP(src->_linkP) {
}
TTresponse::~TTresponse() {
// Iterate through destroying any successive linked response items
TTresponse *nextP;
for (TTresponse *currP = _nextP; currP; currP = nextP) {
// Get the following response and detach it from the current one,
// so that when the current is destroyed, it will only destroy itself
nextP = currP->_nextP;
currP->_nextP = nullptr;
delete currP;
}
}
TTresponse *TTresponse::appendResponse(int id) {
TTresponse *resp = new TTresponse(id, 3);
_nextP = resp;
return resp;
}
TTresponse *TTresponse::copyChain() const {
TTresponse *returnResponseP = new TTresponse(this);
for (TTresponse *srcP = _nextP, *destP = returnResponseP;
srcP; srcP = srcP->_nextP, destP = destP->_nextP) {
destP->_nextP = new TTresponse(*srcP);
}
return returnResponseP;
}
void TTresponse::addLink(TTresponse *item) {
TTresponse *currP = this;
while (currP->_linkP)
currP = currP->_linkP;
currP->_linkP = item;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,71 @@
/* 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_TT_RESPONSE_H
#define TITANIC_TT_RESPONSE_H
#include "titanic/true_talk/tt_string.h"
namespace Titanic {
class TTsentence;
class TTresponse {
private:
int _field0;
TTstring _text;
int _dialogueId;
TTresponse *_nextP;
TTresponse *_linkP;
public:
TTresponse(const TTstring &src);
TTresponse(int val1, int val2);
TTresponse(const TTresponse *src);
virtual ~TTresponse();
/**
* Creates a new response and adds it as the current
* response's next response
*/
TTresponse *appendResponse(int id);
/**
* Makes a copy of the chain of responses
*/
TTresponse *copyChain() const;
TTresponse *getLink() const { return _linkP; }
void addLink(TTresponse *item);
/**
* Get the dialogue Id for the response
*/
int getDialogueId() const { return _dialogueId; }
/**
* Return the next response item, if present
*/
TTresponse *getNext() const { return _nextP; }
};
} // End of namespace Titanic
#endif /* TITANIC_TT_RESPONSE_H */

View 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 "common/textconsole.h"
#include "titanic/true_talk/tt_room_script.h"
namespace Titanic {
TTroomScriptBase::TTroomScriptBase(int scriptId,
const char *charClass, const char *charName,
int v3, int v4, int v5, int v6, int v2, int v7) : _scriptId(scriptId),
TTscriptBase(3, charClass, v2, charName, v3, v4, v5, v6, v7) {
}
/*------------------------------------------------------------------------*/
TTroomScript::TTroomScript(int scriptId) :
TTroomScriptBase(scriptId, "", "", 0, -1, -1, -1, 0, 0), _field54(0) {
}
bool TTroomScript::proc8() const {
return false;
}
void TTroomScript::proc9(int v) {
if (v == 1)
_field54 = 1;
}
ScriptChangedResult TTroomScript::scriptChanged(TTscriptBase *npcScript, int id) {
if (id == 1)
_field54 = 1;
return SCR_1;
}
bool TTroomScript::proc11() const {
return true;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,102 @@
/* 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_TT_ROOM_SCRIPT_H
#define TITANIC_TT_ROOM_SCRIPT_H
#include "titanic/true_talk/tt_script_base.h"
namespace Titanic {
class TTnpcScript;
class TTsentence;
class TTroomScriptBase : public TTscriptBase {
public:
uint _scriptId;
public:
TTroomScriptBase(int scriptId, const char *charClass, const char *charName,
int v3, int v4, int v5, int v6, int v2, int v7);
/**
* Returns true if a response can be made
*/
virtual bool canRespond(TTnpcScript *npcScript, TTsentence *sentence, int val) const = 0;
/**
* Returns true if further sentence processing is allowed
*/
virtual bool canProcess(TTnpcScript *npcScript, TTsentence *sentence) const = 0;
virtual bool proc8() const = 0;
virtual void proc9(int v) = 0;
/**
* Called when the script changes
*/
virtual ScriptChangedResult scriptChanged(TTscriptBase *npcScript, int id) = 0;
virtual bool proc11() const = 0;
};
class TTroomScript : public TTroomScriptBase {
public:
int _field54;
public:
TTroomScript(int scriptId);
/**
* Returns true if a response can be made
*/
bool canRespond(TTnpcScript *npcScript, TTsentence *sentence, int val) const override {
return true;
}
/**
* Returns true if further sentence processing is allowed
*/
bool canProcess(TTnpcScript *npcScript, TTsentence *sentence) const override {
return true;
}
bool proc8() const override;
void proc9(int v) override;
/**
* Called when the script changes
*/
ScriptChangedResult scriptChanged(TTscriptBase *npcScript, int id) override;
bool proc11() const override;
/**
* Called with the new script and id
*/
ScriptChangedResult notifyScript(TTscriptBase *npcScript, int id) {
return scriptChanged(npcScript, id);
}
};
} // End of namespace Titanic
#endif /* TITANIC_TT_ROOM_SCRIPT_H */

View File

@@ -0,0 +1,159 @@
/* 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/true_talk/tt_script_base.h"
#include "titanic/true_talk/script_handler.h"
#include "titanic/titanic.h"
#include "common/textconsole.h"
namespace Titanic {
TTscriptBase::TTscriptBase(int scriptId, const char *charClass, int state,
const char *charName, int v3, int v4, int v5, int v6, int v7) :
_charName(charName), _charClass(charClass), _status(0),
_nodesP(nullptr), _id(0), _hist1P(nullptr),
_field20(0), _field24(0), _field28(0), _field2C(0),
_field30(0), _state(0), _hist2P(nullptr), _field3C(0),
_respHeadP(nullptr), _respTailP(nullptr), _oldResponseP(nullptr) {
if (isValid()) {
if (!v7 || !getStatus()) {
_id = scriptId;
_field20 = v3;
_field24 = v4;
_field28 = v5;
_field2C = v6;
_field30 = v7;
_state = state;
} else {
_status = SS_5;
}
}
if (_status)
reset();
}
TTscriptBase::~TTscriptBase() {
deleteResponses();
delete _oldResponseP;
delete _hist1P;
delete _hist2P;
if (_nodesP) {
_nodesP->deleteSiblings();
delete _nodesP;
}
}
bool TTscriptBase::isValid() {
_status = SS_VALID;
return true;
}
void TTscriptBase::reset() {
_nodesP = nullptr;
_id = 4;
_hist1P = nullptr;
_field20 = 0;
_field24 = -1;
_field28 = -1;
_field2C = -1;
_field30 = 0;
_state = 0;
_hist2P = nullptr;
_field3C = 0;
_respHeadP = nullptr;
_respTailP = nullptr;
_oldResponseP = nullptr;
}
int TTscriptBase::scriptPreprocess(TTsentence *sentence) {
delete _hist1P;
_hist1P = new TTscriptHist(sentence);
return _hist1P ? SS_VALID : SS_7;
}
void TTscriptBase::addResponse(const TTstring &str) {
appendResponse2(-1, nullptr, str);
}
void TTscriptBase::addResponse(int id) {
appendResponse(-1, nullptr, id);
}
void TTscriptBase::applyResponse() {
delete _oldResponseP;
_oldResponseP = nullptr;
if (_respHeadP) {
g_vm->_scriptHandler->setResponse(this, _respHeadP);
_oldResponseP = _respHeadP->copyChain();
TTresponse *oldRespP = _respHeadP;
_respHeadP = _respHeadP->getLink();
_respTailP = nullptr;
delete oldRespP;
}
}
void TTscriptBase::deleteResponses() {
while (_respHeadP) {
_respTailP = _respHeadP;
_respHeadP = _respTailP->getLink();
delete _respTailP;
}
}
void TTscriptBase::appendResponse(int index, int *maxP, int id) {
if (id && (!maxP || index <= *maxP)) {
if (_respTailP) {
// Prior fragments already exist, so append to end of chain
_respTailP = _respTailP->appendResponse(id);
} else {
// Currently no tail
_respTailP = new TTresponse(id, 3);
if (_respHeadP)
_respHeadP->addLink(_respTailP);
else
_respHeadP = _respTailP;
}
}
}
void TTscriptBase::appendResponse(int index, int *maxP, const TTstring &str) {
if (!maxP || index <= *maxP) {
if (_respTailP) {
// Prior fragments already exist, so append to end of chain
_respTailP = new TTresponse(str);
} else {
// Currently no tail
_respTailP = new TTresponse(str);
if (_respHeadP)
_respHeadP->addLink(_respTailP);
else
_respHeadP = _respTailP;
}
}
}
} // End of namespace Titanic

View File

@@ -0,0 +1,137 @@
/* 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_TT_SCRIPT_BASE_H
#define TITANIC_TT_SCRIPT_BASE_H
#include "titanic/true_talk/tt_string.h"
#include "titanic/true_talk/tt_hist.h"
#include "titanic/true_talk/tt_node.h"
#include "titanic/true_talk/tt_response.h"
namespace Titanic {
enum ScriptChangedResult {
SCR_0 = 0, SCR_1 = 1, SCR_2 = 2, SCR_3 = 3, SCR_4 = 4, SCR_5 = 5
};
class TTsentence;
class TTscriptBase {
private:
void reset();
protected:
TTnode *_nodesP;
TThist *_hist1P;
TTstring _charName, _charClass;
int _field20;
int _field24;
int _field28;
int _field2C;
int _field30;
int _state;
TThist *_hist2P;
int _field3C;
TTresponse *_respTailP;
TTresponse *_respHeadP;
TTresponse *_oldResponseP;
int _status;
protected:
/**
* Delete any responses set up for the script
*/
void deleteResponses();
/**
* Creates and appends a new response fragment to the script specified by
* the given conversation Id
*/
void appendResponse(int index, int *maxP, int id);
/**
* Creates and appends a new response fragment string to the script
*/
void appendResponse(int index, int *maxP, const TTstring &str);
/**
* Creates and appends a new response fragment string to the script
*/
void appendResponse2(int index, int *maxP, const TTstring &str) {
appendResponse(index, maxP, str);
}
/**
* Set the script state
*/
void setState(int state) { _state = state; }
/**
* Get the current state
*/
int getState() const { return _state; }
public:
int _id;
public:
TTscriptBase(int scriptId, const char *charClass, int v2, const char *charName,
int v3, int v4, int v5, int v6, int v7);
virtual ~TTscriptBase();
virtual void addResponse(const TTstring &str);
virtual void addResponse(int id);
/**
* Passes on the list of dialogue Ids stored in the response(s)
* to the title engine for later display in the PET
*/
virtual void applyResponse();
/**
* Returns true if the script is in a valid state
*/
bool isValid();
/**
* Return the Id of the script
*/
int getId() const { return _id; }
/**
* Return the status
*/
int getStatus() const { return _status; }
/**
* Return the script text
*/
const TTstring getText() { return _charClass; }
/**
* Gets passed a newly created input wrapper during conversation text processing
*/
int scriptPreprocess(TTsentence *sentence);
};
} // End of namespace Titanic
#endif /* TITANIC_TT_SCRIPT_BASE_H */

View File

@@ -0,0 +1,96 @@
/* 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/true_talk/tt_scripts.h"
#include "titanic/true_talk/title_engine.h"
#include "titanic/true_talk/barbot_script.h"
#include "titanic/true_talk/bellbot_script.h"
#include "titanic/true_talk/deskbot_script.h"
#include "titanic/true_talk/doorbot_script.h"
#include "titanic/true_talk/liftbot_script.h"
#include "titanic/true_talk/maitred_script.h"
#include "titanic/true_talk/parrot_script.h"
#include "titanic/true_talk/succubus_script.h"
#include "titanic/translation.h"
namespace Titanic {
TTnpcScript *TTnpcScriptList::findById(int charId) const {
for (TTnpcScriptList::const_iterator i = begin(); i != end(); ++i) {
const TTnpcScriptListItem *item = *i;
if (item->_npcScript->_charId == charId)
return item->_npcScript;
}
return nullptr;
}
/*------------------------------------------------------------------------*/
TTroomScript *TTroomScriptList::findById(uint scriptId) const {
for (TTroomScriptList::const_iterator i = begin(); i != end(); ++i) {
const TTroomScriptListItem *item = *i;
if (item->_item->_scriptId == scriptId)
return item->_item;
}
return nullptr;
}
/*------------------------------------------------------------------------*/
TTscripts::TTscripts() {
// Load room scripts
for (int scriptNum = 100; scriptNum < 133; ++scriptNum)
addScript(new TTroomScript(scriptNum));
// Load npc scripts
addScript(new BarbotScript(100, "Barbot", 0, "Fortillian", 9, 1, -1, -1, -1, 0), 112);
addScript(new BellbotScript(101, "Bellbot", 0, "Krage", 8, 1), 110);
addScript(new DeskbotScript(103, "DeskBot", 0, "Marsinta", 11, 2), 110);
addScript(new DoorbotScript(104, "Doorbot", 0, "Fentible", 11, 1, -1, -1, -1, 0), 100);
addScript(new LiftbotScript(105, "LiftBot", 0, "Nobby", 11, 1, -1, -1, -1, 0), 103);
addScript(new ParrotScript(107, "Parrot", 0, "The Parrot", 5, 1, -1, -1, -1, 0), 111);
addScript(new SuccUBusScript(111, "Succubus", 0, "Shorbert", 9, 1, -1, -1, -1, 0), 110);
addScript(new MaitreDScript(112, "MaitreDBot", 0, "Dastrogaaar", 8, 1), 132);
}
void TTscripts::addScript(TTnpcScript *script, int scriptId) {
// Find the room script this is associated with
TTroomScript *roomScript = getRoomScript(scriptId);
assert(roomScript);
_npcScripts.push_back(new TTnpcScriptListItem(script, roomScript));
}
void TTscripts::addScript(TTroomScript *script) {
_roomScripts.push_back(new TTroomScriptListItem(script));
}
TTroomScript *TTscripts::getRoomScript(int scriptId) const {
return _roomScripts.findById(scriptId);
}
TTnpcScript *TTscripts::getNpcScript(int charId) const {
return _npcScripts.findById(charId);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,86 @@
/* 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_TT_SCRIPTS_H
#define TITANIC_TT_SCRIPTS_H
#include "titanic/core/list.h"
#include "titanic/true_talk/tt_npc_script.h"
#include "titanic/true_talk/tt_room_script.h"
namespace Titanic {
class CTitleEngine;
class TTnpcScriptListItem : public ListItem {
public:
TTnpcScript *_npcScript;
TTroomScript *_roomScript;
public:
TTnpcScriptListItem() : _npcScript(nullptr), _roomScript(nullptr) {}
TTnpcScriptListItem(TTnpcScript *script, TTroomScript *roomScript) :
_npcScript(script), _roomScript(roomScript) {}
~TTnpcScriptListItem() override { delete _npcScript; }
};
PTR_LIST_ITEM(TTroomScript);
class TTnpcScriptList : public List<TTnpcScriptListItem> {
public:
TTnpcScript *findById(int charId) const;
};
class TTroomScriptList : public List<TTroomScriptListItem> {
public:
TTroomScript *findById(uint scriptId) const;
};
class TTscripts {
private:
TTnpcScriptList _npcScripts;
TTroomScriptList _roomScripts;
private:
/**
* Add a named script to the named scripts list
*/
void addScript(TTnpcScript *script, int charId);
/**
* Add an unnamed script to the unnamed scripts list
*/
void addScript(TTroomScript *script);
public:
TTscripts();
/**
* Return a pointer to the specified room script
*/
TTroomScript *getRoomScript(int scriptId) const;
/**
* Return a pointer to the specified character script
*/
TTnpcScript *getNpcScript(int charId) const;
};
} // End of namespace Titanic
#endif /* TITANIC_TT_CHARACTERS_H */

View File

@@ -0,0 +1,360 @@
/* 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/true_talk/tt_sentence.h"
#include "titanic/true_talk/tt_concept.h"
#include "titanic/true_talk/script_handler.h"
#include "titanic/titanic.h"
#include "titanic/translation.h"
namespace Titanic {
TTsentenceConcept::~TTsentenceConcept() {
for (int idx = 0; idx <= 5; ++idx)
delete _concepts[idx];
}
TTsentenceConcept *TTsentenceConcept::addSibling() {
if (_nextP != nullptr)
// This should never happen
return nullptr;
TTsentenceConcept *nextP = new TTsentenceConcept();
_nextP = nextP;
return nextP;
}
/*------------------------------------------------------------------------*/
TTsentence::TTsentence(int inputCtr, const TTstring &line, CScriptHandler *owner,
TTroomScript *roomScript, TTnpcScript *npcScript) :
_owner(owner), _category(1), _inputCtr(inputCtr), _field34(0),
_field38(0), _initialLine(line), _nodesP(nullptr), _roomScript(roomScript),
_npcScript(npcScript), _field58(5), _field5C(5) {
_status = _initialLine.isValid() && _normalizedLine.isValid() ? SS_11: SS_VALID;
}
TTsentence::TTsentence(const TTsentence *src) : _sentenceConcept(src->_sentenceConcept),
_initialLine(src->_initialLine), _normalizedLine(src->_normalizedLine) {
copyFrom(*src);
}
TTsentence::~TTsentence() {
_sentenceConcept.deleteSiblings();
if (_nodesP) {
_nodesP->deleteSiblings();
delete _nodesP;
}
}
void TTsentence::copyFrom(const TTsentence &src) {
if (!src.getStatus())
_status = SS_5;
else if (!src._initialLine.isValid() || !src._normalizedLine.isValid())
_status = SS_11;
else
_status = SS_VALID;
_inputCtr = src._inputCtr;
_owner = src._owner;
_roomScript = src._roomScript;
_npcScript = src._npcScript;
_field58 = src._field58;
_field5C = src._field5C;
_field34 = src._field34;
_field38 = src._field38;
_category = src._category;
_nodesP = nullptr;
if (src._nodesP) {
// Source has processed nodes, so duplicate them
for (TTsentenceNode *node = src._nodesP; node;
node = dynamic_cast<TTsentenceNode *>(node->_nextP)) {
TTsentenceNode *newNode = new TTsentenceNode(node->_wordP);
if (_nodesP)
_nodesP->addToTail(newNode);
else
_nodesP = newNode;
}
}
}
int TTsentence::storeVocabHit(TTword *word) {
if (!word)
return 0;
TTsentenceNode *node = new TTsentenceNode(word);
if (_nodesP) {
_nodesP->addToTail(node);
} else {
_nodesP = node;
}
return 0;
}
bool TTsentence::fn1(const CString &str, int wordId1, const CString &str1, const CString &str2,
const CString &str3, int wordId2, int val1, int val2, const TTconceptNode *node) const {
if (!node)
node = &_sentenceConcept;
if (!node)
return false;
if (val1 && !is18(val1, node))
return false;
if (!str.empty() && !fn2(0, str, node))
return false;
if (wordId1 && !fn4(1, wordId1, node))
return false;
if (!str1.empty() && !fn2(2, str1, node))
return false;
if (!str2.empty() && !fn2(3, str2, node))
return false;
if (!str3.empty() && !fn2(4, str3, node))
return false;
if (wordId2 && !fn4(5, wordId2, node))
return false;
if (val2 && !is1C(val2, node))
return false;
return true;
}
bool TTsentence::fn3(const CString &str1, const CString &str2, const CString &str3,
const CString &str4, const CString &str5, const CString &str6,
int val1, int val2, const TTconceptNode *node) const {
if (!node)
node = &_sentenceConcept;
if (val1 && !is18(val1, node))
return false;
if (!str1.empty() && !fn2(0, str1, node))
return false;
if (!str2.empty() && !fn2(1, str2, node))
return false;
if (!str3.empty() && !fn2(2, str3, node))
return false;
if (!str4.empty() && !fn2(3, str4, node))
return false;
if (!str5.empty() && !fn2(4, str5, node))
return false;
if (!str6.empty() && !fn2(5, str6, node))
return false;
if (!val2 && !is1C(val2, node))
return false;
return true;
}
bool TTsentence::fn2(int slotIndex, const TTstring &str, const TTconceptNode *node) const {
if (!node)
node = &_sentenceConcept;
TTconcept *conceptP = getFrameSlot(slotIndex, node);
if (!conceptP)
return str == "isEmpty";
bool abortFlag = false;
switch (conceptP->_scriptType) {
case 1:
if (str == "thePlayer")
abortFlag = 1;
break;
case 2:
if (str == "targetNpc")
abortFlag = 1;
break;
case 3:
if (str == "otherNpc")
abortFlag = 1;
break;
default:
break;
}
TTstring conceptText = conceptP->getText();
if (abortFlag || str == conceptText || conceptP->compareTo(str)) {
delete conceptP;
return true;
}
if (slotIndex == 1 && g_vm->_exeResources._owner->_concept4P) {
if (str == g_vm->_exeResources._owner->_concept4P->getText() &&
conceptText == "do")
goto exit;
}
if (g_vm->_exeResources._owner->_concept2P && (slotIndex == 0 ||
slotIndex == 3 || slotIndex == 4)) {
if (str == g_vm->_exeResources._owner->_concept2P->getText() &&
(conceptText == "it" || conceptText == "he" || conceptText == "she" ||
conceptText == "him" || conceptText == "her" || conceptText == "them" ||
conceptText == "they"))
goto exit;
}
if (g_vm->_exeResources._owner->_concept1P && (slotIndex == 0 ||
slotIndex == 2 || slotIndex == 3 || slotIndex == 4 || slotIndex == 5)) {
if (str == g_vm->_exeResources._owner->_concept1P->getText() &&
(conceptText == "it" || conceptText == "that" || conceptText == "he" ||
conceptText == "she" || conceptText == "him" || conceptText == "her" ||
conceptText == "them" || conceptText == "they" || conceptText == "those" ||
conceptText == "1" || conceptText == "thing"))
goto exit;
}
if (g_vm->_exeResources._owner->_concept1P && (slotIndex == 0 || slotIndex == 2)) {
if (conceptText == "?" && str == g_vm->_exeResources._owner->_concept1P->getText()) {
delete conceptP;
conceptP = getFrameSlot(5, node);
conceptText = conceptP->getText();
if (conceptText == "it" || conceptText == "that" || conceptText == "he" ||
conceptText == "she" || conceptText == "him" || conceptText == "her" ||
conceptText == "them" || conceptText == "they" || conceptText == "those" ||
conceptText == "1" || conceptText == "thing")
abortFlag = true;
}
}
exit:
delete conceptP;
return abortFlag;
}
bool TTsentence::fn4(int mode, int wordId, const TTconceptNode *node) const {
if (!node)
node = &_sentenceConcept;
switch (mode) {
case 1:
return node->_concept1P && getWordId(node->_concept1P) == wordId;
case 5:
return node->_concept5P && getWordId(node->_concept5P) == wordId;
default:
return false;
}
}
TTconcept *TTsentence::getFrameEntry(int slotIndex, const TTconceptNode *conceptNode) const {
if (!conceptNode)
conceptNode = &_sentenceConcept;
return conceptNode->_concepts[slotIndex];
}
TTconcept *TTsentence::getFrameSlot(int slotIndex, const TTconceptNode *conceptNode) const {
TTconcept *newConcept = new TTconcept();
TTconcept *conceptP = getFrameEntry(slotIndex, conceptNode);
if (conceptP)
newConcept->copyFrom(conceptP);
if (!newConcept->isValid()) {
delete newConcept;
newConcept = nullptr;
}
return newConcept;
}
bool TTsentence::isFrameSlotClass(int slotIndex, WordClass wordClass, const TTconceptNode *conceptNode) const {
TTconcept *conceptP = getFrameEntry(slotIndex, conceptNode);
if (conceptP && conceptP->_wordP) {
return conceptP->_wordP->isClass(wordClass);
} else {
return false;
}
}
int TTsentence::is18(int val, const TTconceptNode *node) const {
if (!node)
node = &_sentenceConcept;
return node->_field18 == val;
}
int TTsentence::is1C(int val, const TTconceptNode *node) const {
if (!node)
node = &_sentenceConcept;
return node->_field1C == val;
}
bool TTsentence::isConcept34(int slotIndex, const TTconceptNode *node) const {
TTconcept *conceptP = getFrameEntry(slotIndex, node);
return conceptP && conceptP->getState();
}
bool TTsentence::localWord(const char *str) const {
CScriptHandler &scriptHandler = *g_vm->_exeResources._owner;
bool foundMatch = false;
static const char *const ARTICLES_EN[11] = {
"it", "that", "he", "she", "him", "her", "them", "they", "those", "1", "thing"
};
static const char *const ARTICLES_DE[9] = {
"es", "das", "er", "ihn", "ihm", "ihnen", "diese", "man", "ding"
};
if (scriptHandler._concept1P) {
TTstring s = scriptHandler._concept1P->getText();
if (s == str)
foundMatch = true;
} else if (scriptHandler._concept2P) {
TTstring s = scriptHandler._concept2P->getText();
if (s == str)
foundMatch = true;
}
VocabMode mode = g_vm->_exeResources.getVocabMode();
bool result = false;
for (TTsentenceNode *nodeP = _nodesP; nodeP && !result;
nodeP = dynamic_cast<TTsentenceNode *>(nodeP->_nextP)) {
TTsynonym syn;
if (!nodeP->_wordP)
continue;
const TTstring wordStr = nodeP->_wordP->_text;
if ((g_language == Common::DE_DEU || mode == VOCAB_MODE_EN) && wordStr == str) {
result = true;
} else if (nodeP->_wordP->findSynByName(str, &syn, mode)) {
result = true;
} else if (foundMatch) {
result = false;
for (int idx = 0; idx < TRANSLATE(11, 9) && !result; ++idx) {
result = wordStr == TRANSLATE(ARTICLES_EN[idx], ARTICLES_DE[idx]);
}
}
}
return result;
}
bool TTsentence::contains(const char *str) const {
return _initialLine.contains(str) || _normalizedLine.contains(str);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,136 @@
/* 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_TT_SENTENCE_H
#define TITANIC_TT_SENTENCE_H
#include "common/array.h"
#include "titanic/true_talk/tt_concept_node.h"
#include "titanic/true_talk/tt_npc_script.h"
#include "titanic/true_talk/tt_room_script.h"
#include "titanic/true_talk/tt_sentence_node.h"
#include "titanic/true_talk/tt_string.h"
namespace Titanic {
class CScriptHandler;
class TTword;
class TTsentenceConcept : public TTconceptNode {
public:
TTsentenceConcept() : TTconceptNode() {}
TTsentenceConcept(const TTsentenceConcept &src) : TTconceptNode(src) {}
~TTsentenceConcept() override;
/**
* Adds a new sibling instance
*/
TTsentenceConcept *addSibling();
};
class TTsentence {
private:
CScriptHandler *_owner;
int _inputCtr;
int _field34;
TTsentenceNode *_nodesP;
int _field5C;
int _status;
private:
/**
* Copy sentence data from a given source
*/
void copyFrom(const TTsentence &src);
public:
TTsentenceConcept _sentenceConcept;
TTstring _initialLine;
TTstring _normalizedLine;
int _field38;
int _field58;
TTroomScript *_roomScript;
TTnpcScript *_npcScript;
int _category;
public:
TTsentence(int inputCtr, const TTstring &line, CScriptHandler *owner,
TTroomScript *roomScript, TTnpcScript *npcScript);
TTsentence(const TTsentence *src);
~TTsentence();
void setState(int v) { _field34 = v; }
void set38(int v) { _field38 = v; }
bool checkCategory() const { return _category > 1 && _category <= 10; }
int concept18(TTconceptNode *conceptNode) {
return conceptNode ? conceptNode->get18() : 0;
}
int get58() const { return _field58; }
int is18(int val, const TTconceptNode *node) const;
int is1C(int val, const TTconceptNode *node) const;
int getStatus() const { return _status; }
/**
* Gets a concept slot
*/
TTconcept *getFrameEntry(int slotIndex, const TTconceptNode *conceptNode = nullptr) const;
/**
* Gets a conecpt slot and returns a duplicate of it
*/
TTconcept *getFrameSlot(int slotIndex, const TTconceptNode *conceptNode = nullptr) const;
/**
* Returns true if the specified slot has an attached word with a given class
*/
bool isFrameSlotClass(int slotIndex, WordClass wordClass, const TTconceptNode *conceptNode = nullptr) const;
/**
* Adds a found vocab word to the list of words representing
* the player's input
* @param word Word to node
*/
int storeVocabHit(TTword *word);
bool fn1(const CString &str, int wordId1, const CString &str1, const CString &str2,
const CString &str3, int wordId2, int val1, int val2, const TTconceptNode *node) const;
bool fn3(const CString &str1, const CString &str2, const CString &str3,
const CString &str4, const CString &str5, const CString &str6,
int val1, int val2, const TTconceptNode *node) const;
bool fn2(int slotIndex, const TTstring &str, const TTconceptNode *node = nullptr) const;
bool fn4(int mode, int wordId, const TTconceptNode *node = nullptr) const;
bool isConcept34(int slotIndex, const TTconceptNode *node = nullptr) const;
/**
* Returns true if the sentence contains the specified word,
* allowing for common synonyms of the desired word
*/
bool localWord(const char *str) const;
/**
* Returns true if the sentence (either the original or normalized lines)
* contain the specified substring
*/
bool contains(const char *str) const;
};
} // End of namespace Titanic
#endif /* TITANIC_TT_SENTENCE_H */

View File

@@ -0,0 +1,33 @@
/* 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 "common/textconsole.h"
#include "titanic/true_talk/tt_sentence_node.h"
namespace Titanic {
TTsentenceNode::TTsentenceNode() : TTnode(), _wordP(nullptr) {
}
TTsentenceNode::TTsentenceNode(TTword *word) : TTnode(), _wordP(word) {
}
} // End of namespace Titanic

View File

@@ -0,0 +1,40 @@
/* 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_TT_SENTENCE_NODE_H
#define TITANIC_TT_SENTENCE_NODE_H
#include "titanic/true_talk/tt_node.h"
#include "titanic/true_talk/tt_word.h"
namespace Titanic {
class TTsentenceNode : public TTnode {
public:
TTword *_wordP;
public:
TTsentenceNode();
TTsentenceNode(TTword *word);
};
} // End of namespace Titanic
#endif /* TITANIC_TT_SENTENCE_NODE_H */

View File

@@ -0,0 +1,169 @@
/* 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/true_talk/tt_string.h"
#include "titanic/support/simple_file.h"
namespace Titanic {
TTstring::TTstring() : _status(SS_VALID) {
_data = new TTstringData();
}
TTstring::TTstring(const char *str) : _status(SS_VALID) {
_data = new TTstringData(str);
}
TTstring::TTstring(const CString &str) {
_status = SS_VALID;
_data = new TTstringData(str);
}
TTstring::TTstring(const TTstring &str) {
if (str._status != SS_VALID) {
_status = SS_5;
_data = nullptr;
} else {
_status = SS_VALID;
_data = str._data;
_data->_referenceCount++;
}
}
TTstring::~TTstring() {
if (_data && --_data->_referenceCount == 0)
delete _data;
}
void TTstring::operator=(const TTstring &str) {
if (&str == this)
// Trying to assign string to itself
return;
// Delete old string reference, if any
if (_data && --_data->_referenceCount == 0)
delete _data;
// Copy source string data
_status = str._status;
_data = str._data;
if (_data)
_data->_referenceCount++;
}
void TTstring::operator=(const CString &str) {
operator=(str.c_str());
}
void TTstring::operator=(const char *str) {
// Delete old string reference, if any
if (_data && --_data->_referenceCount == 0)
delete _data;
// Create new string data
_data = new TTstringData(str);
_status = SS_VALID;
}
TTstring &TTstring::operator+=(const char *str) {
_data->_string += str;
return *this;
}
TTstring &TTstring::operator+=(const TTstring &str) {
_data->_string += str;
return *this;
}
TTstring &TTstring::operator+=(char c) {
_data->_string += c;
return *this;
}
bool TTstring::operator==(const TTstring &str) const {
return _data && str._data && _data->_string == str._data->_string;
}
bool TTstring::operator==(const char *str) const {
return _data && _data->_string == str;
}
void TTstring::save(SimpleFile *file) const {
file->writeFormat("%s", c_str());
}
TTstring TTstring::tokenize(const char *delim) {
const char *strP = _data->_string.c_str();
const char *splitP = nullptr, *chP;
for (const char *d = delim; *d; ++d) {
chP = strchr(strP, *d);
if (chP && (splitP == nullptr || chP < splitP))
splitP = chP;
}
if (splitP) {
TTstring result(CString(strP, splitP));
_data->_string = CString(splitP + 1);
return result;
} else {
TTstring result(strP);
_data->_string = CString();
return result;
}
}
int TTstring::deletePrefix(int count) {
int strSize = size();
if (count > strSize)
count = strSize;
if (_data->_referenceCount == 1) {
// No other references to this string, so we can just directly modify it
_data->_string = CString(_data->_string.c_str() + count);
} else {
// Detach string from current shared data, and create a new one with the substring
_data->_referenceCount--;
_data = new TTstringData(_data->_string.c_str() + count);
}
return 1;
}
int TTstring::deleteSuffix(int count) {
int strSize = size();
if (count > strSize)
count = strSize;
CString newStr(_data->_string.c_str(), _data->_string.c_str() + strSize - count);
if (_data->_referenceCount == 1) {
// No other references to this string, so we can just directly modify it
_data->_string = newStr;
} else {
// Detach string from current shared data, and create a new one with the substring
_data->_referenceCount--;
_data = new TTstringData(newStr);
}
return 1;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,172 @@
/* 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_TT_STRING_H
#define TITANIC_TT_STRING_H
#include "titanic/support/string.h"
namespace Titanic {
class SimpleFile;
struct TTstringData {
CString _string;
int _referenceCount;
TTstringData() : _referenceCount(1) {}
TTstringData(const char *str) : _string(str), _referenceCount(1) {}
TTstringData(const CString &str) : _string(str), _referenceCount(1) {}
};
enum TTstringStatus {
SS_VALID = 0, SS_1 = 1, SS_2 = 2, SS_3 = 3, SS_4 = 4,
SS_5 = 5, SS_7 = 7, SS_8 = 8, SS_11 = 11, SS_13 = 13
};
class TTstring {
private:
TTstringData *_data;
TTstringStatus _status;
public:
TTstring();
TTstring(const char *str);
TTstring(const CString &str);
TTstring(const TTstring &str);
virtual ~TTstring();
void operator=(const TTstring &str);
void operator=(const CString &str);
void operator=(const char *str);
TTstring &operator+=(const char *str);
TTstring &operator+=(const TTstring &str);
TTstring &operator+=(char c);
bool operator==(const TTstring &str) const;
bool operator==(const char *str) const;
const char &operator[](int index) {
return *(c_str() + index);
}
bool empty() const {
return _data->_string.empty();
}
char firstChar() const {
return _data->_string.firstChar();
}
char lastChar() const {
return _data->_string.lastChar();
}
int size() const {
return _data->_string.size();
}
void deleteLastChar() {
_data->_string.deleteLastChar();
}
bool hasPrefix(const CString &str) const {
return _data->_string.hasPrefix(str);
}
bool hasPrefix(const char *str) const {
return _data->_string.hasPrefix(str);
}
bool hasSuffix(const CString &str) const {
return _data->_string.hasSuffix(str);
}
bool hasSuffix(const char *str) const {
return _data->_string.hasSuffix(str);
}
bool contains(const char *s) const {
return _data->_string.contains(s);
}
/**
* Create a new copy of the string
*/
TTstring *copy() const {
return new TTstring(c_str());
}
/**
* Returns true if the string is valid
*/
bool isValid() const {
return _status == SS_VALID;
}
/**
* Get the status of the string
*/
TTstringStatus getStatus() const { return _status; }
/**
* Get a char * pointer to the string data
*/
const char *c_str() const { return _data->_string.c_str(); }
/**
* Automatic operator to convert to a const char *
*/
operator const char *() const { return c_str(); }
/**
* Get a character at a specified index
*/
char charAt(int index) const { return *(c_str() + index); }
/**
* Save the sring to a passed file
*/
void save(SimpleFile *file) const;
/**
* Compare a substring within the string at the specified index
*/
bool compareAt(int index, const char *str) const {
return !strncmp(c_str() + index, str, strlen(str));
}
/**
* Split off everything in the string until the first occurrence
* of any specified delimiter character
*/
TTstring tokenize(const char *delim);
/**
* Delets a specififed number of characters from the start of the string
*/
int deletePrefix(int count);
/**
* Delets a specififed number of characters from the end of the string
*/
int deleteSuffix(int count);
};
} // End of namespace Titanic
#endif /* TITANIC_TT_STRING_H */

View File

@@ -0,0 +1,68 @@
/* 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 "common/textconsole.h"
#include "titanic/true_talk/tt_string_node.h"
namespace Titanic {
TTstringNode::TTstringNode() : TTnode(), _file(HANDLE_STDIN),
_mode(0), _field1C(0) {
}
void TTstringNode::initialize(int mode) {
_mode = mode;
_file = HANDLE_STDIN;
if (_string.isValid()) {
_field1C = 0;
} else {
_field1C = 11;
warning("TTstringNode::initialize has bad subobj");
}
}
void TTstringNode::initialize(TTstringNode *oldNode) {
_mode = oldNode->_mode;
_file = oldNode->_file;
if (_string.isValid()) {
_field1C = 0;
} else {
_field1C = 11;
warning("TTstringNode::initialize has bad subobj");
}
delete oldNode;
}
TTstringNode *TTstringNode::findByName(const TTstring &str, VocabMode mode) {
for (TTstringNode *nodeP = this; nodeP; nodeP = dynamic_cast<TTstringNode *>(nodeP->_nextP)) {
if (nodeP->_mode == mode || (mode == VOCAB_MODE_EN && nodeP->_mode < 3)) {
if (nodeP->_string == str)
return nodeP;
}
}
return nullptr;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,58 @@
/* 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_TT_STRING_NODE_H
#define TITANIC_TT_STRING_NODE_H
#include "titanic/true_talk/tt_node.h"
#include "titanic/true_talk/tt_string.h"
#include "titanic/support/exe_resources.h"
namespace Titanic {
class TTstringNode : public TTnode {
protected:
/**
* Initializes state for the node
*/
void initialize(int mode);
/**
* Initializes state for the node
*/
void initialize(TTstringNode *oldNode);
public:
TTstring _string;
FileHandle _file;
int _mode;
int _field1C;
public:
TTstringNode();
/**
* Find a string node in the linked chain by name
*/
TTstringNode *findByName(const TTstring &str, VocabMode mode);
};
} // End of namespace Titanic
#endif /* TITANIC_TT_STRING_NODE_H */

View File

@@ -0,0 +1,84 @@
/* 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/true_talk/tt_synonym.h"
namespace Titanic {
TTsynonym::TTsynonym() : TTstringNode() {
}
TTsynonym::TTsynonym(const TTsynonym *src) : TTstringNode() {
_string = src->_string;
initialize(src->_mode);
_file = src->_file;
}
TTsynonym::TTsynonym(int mode, const char *str, FileHandle file) :
TTstringNode() {
_string = str;
initialize(mode);
_file = file;
}
TTsynonym::TTsynonym(int mode, const TTstring &str) : TTstringNode() {
_string = str;
initialize(mode);
}
TTsynonym *TTsynonym::copyFrom(const TTsynonym *src) {
if (src->_field1C) {
_field1C = 5;
} else {
_field1C = 0;
if (src != this)
_string = src->_string;
}
return this;
}
int TTsynonym::save(SimpleFile *file) {
for (TTstringNode *synP = this; synP; synP = dynamic_cast<TTstringNode *>(synP->_nextP)) {
file->writeFormat("%s", " 0 ");
synP->_string.save(file);
file->writeFormat("%c", ' ');
if (synP->_mode) {
file->writeFormat("%1.0d", synP->_mode);
} else {
file->writeFormat("%c", '0');
}
file->writeFormat("%c", ' ');
if (synP->_file) {
file->writeFormat("%2.0d", synP->_file);
} else {
file->writeFormat("%c", ' ');
}
file->writeFormat("%c", '\n');
}
return 0;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,50 @@
/* 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_TT_SYNONYM_H
#define TITANIC_TT_SYNONYM_H
#include "titanic/true_talk/tt_string_node.h"
#include "titanic/support/simple_file.h"
namespace Titanic {
class TTsynonym : public TTstringNode {
public:
TTsynonym();
TTsynonym(const TTsynonym *src);
TTsynonym(int mode, const char *str, FileHandle file);
TTsynonym(int mode, const TTstring &str);
/**
* Copies data from one synonym to another
*/
TTsynonym *copyFrom(const TTsynonym *src);
/**
* Save data for the synonym to file
*/
int save(SimpleFile *file);
};
} // End of namespace Titanic
#endif /* TITANIC_TT_SYNONYM_H */

View 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/>.
*
*/
#include "titanic/true_talk/tt_talker.h"
#include "titanic/messages/messages.h"
#include "titanic/pet_control/pet_control.h"
namespace Titanic {
void TTtalker::speechStarted(const CString &dialogueStr, uint dialogueId, uint speechDuration) {
_line = dialogueStr;
_dialogueId = dialogueId;
CTrueTalkNotifySpeechStartedMsg msg(speechDuration, dialogueId, 0);
msg.execute(_npc, nullptr, MSGFLAG_BREAK_IF_HANDLED);
}
void TTtalker::endSpeech(int val) {
_done = true;
_talkEndState = val;
}
void TTtalker::speechEnded() {
CPetControl *petControl = _npc->getPetControl();
if (petControl)
// Add in final line
petControl->convAddLine(_line);
// Notify the end of the speech
CTrueTalkNotifySpeechEndedMsg endedMsg(_talkEndState, _dialogueId);
endedMsg.execute(_npc, nullptr, MSGFLAG_BREAK_IF_HANDLED);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,69 @@
/* 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_TT_TALKER_H
#define TITANIC_TT_TALKER_H
#include "titanic/core/list.h"
#include "titanic/npcs/true_talk_npc.h"
#include "titanic/support/string.h"
namespace Titanic {
class CTrueTalkManager;
class TTtalker : public ListItem {
public:
CTrueTalkManager *_owner;
CTrueTalkNPC *_npc;
CString _line;
int _dialogueId;
int _talkEndState;
int _done;
public:
TTtalker() : _owner(nullptr), _npc(nullptr),
_dialogueId(0), _talkEndState(0), _done(0) {}
TTtalker(CTrueTalkManager *owner, CTrueTalkNPC *npc) :
_owner(owner), _npc(npc), _dialogueId(0), _talkEndState(0), _done(0) {}
/**
* Start a new speech
*/
void speechStarted(const CString &dialogueStr, uint dialogueId, uint speechDuration);
/**
* End the speech
*/
void endSpeech(int val);
/**
* Called when a speech is finished, to signal to the associated character
* that the speech is over
*/
void speechEnded();
};
class TTtalkerList : public List<TTtalker> {
};
} // End of namespace Titanic
#endif /* TITANIC_TT_TALKER_H */

View File

@@ -0,0 +1,29 @@
/* 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/true_talk/tt_title_script.h"
namespace Titanic {
TTTitleScript::TTTitleScript() : TTscriptBase(1, "", 0, "", 0, -1, -1, -1, 0) {
}
} // End of namespace Titanic

View File

@@ -0,0 +1,37 @@
/* 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_TT_TITLE_SCRIPT_H
#define TITANIC_TT_TITLE_SCRIPT_H
#include "titanic/true_talk/tt_script_base.h"
#include "titanic/true_talk/tt_string.h"
namespace Titanic {
class TTTitleScript : public TTscriptBase {
public:
TTTitleScript();
};
} // End of namespace Titanic
#endif /* TITANIC_TT_TITLE_SCRIPT_H */

View File

@@ -0,0 +1,584 @@
/* 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/true_talk/tt_vocab.h"
#include "titanic/true_talk/script_handler.h"
#include "titanic/true_talk/tt_action.h"
#include "titanic/true_talk/tt_adj.h"
#include "titanic/true_talk/tt_major_word.h"
#include "titanic/true_talk/tt_picture.h"
#include "titanic/true_talk/tt_pronoun.h"
#include "titanic/titanic.h"
#include "titanic/translation.h"
#include "common/file.h"
namespace Titanic {
TTvocab::TTvocab(VocabMode vocabMode): _headP(nullptr), _tailP(nullptr),
_word(nullptr), _vocabMode(vocabMode) {
load("STVOCAB");
}
TTvocab::~TTvocab() {
if (_headP) {
_headP->deleteSiblings();
delete _headP;
_headP = _tailP = nullptr;
}
}
int TTvocab::load(const CString &name) {
SimpleFile *file = g_vm->_exeResources._owner->openResource(name);
int result = 0;
bool skipFlag;
while (!result && !file->eos()) {
skipFlag = false;
WordClass wordClass = (WordClass)file->readNumber();
TTstring space(" ");
switch (wordClass) {
case WC_UNKNOWN: {
if (_word)
result = _word->readSyn(file);
skipFlag = true;
break;
}
case WC_ACTION: {
TTaction *word = new TTaction(space, WC_UNKNOWN, 0, 0, 0);
result = word->load(file);
_word = word;
break;
}
case WC_THING: {
TTpicture *word = new TTpicture(space, WC_UNKNOWN, 0, 0, 0, 0, 0);
result = word->load(file);
_word = word;
break;
}
case WC_ABSTRACT:
case WC_ADVERB: {
TTmajorWord *word = new TTmajorWord(space, WC_UNKNOWN, 0, 0);
result = word->load(file, wordClass);
_word = word;
break;
}
case WC_ARTICLE:
case WC_CONJUNCTION:
case WC_PREPOSITION: {
TTword *word = new TTword(space, WC_UNKNOWN, 0);
result = word->load(file, wordClass);
_word = word;
break;
}
case WC_ADJECTIVE: {
TTadj *word = new TTadj(space, WC_UNKNOWN, 0, 0, 0);
result = word->load(file);
_word = word;
break;
}
case WC_PRONOUN: {
TTpronoun *word = new TTpronoun(space, WC_UNKNOWN, 0, 0, 0);
result = word->load(file);
_word = word;
break;
}
default:
result = 4;
break;
}
if (!skipFlag && _word) {
if (result) {
// Something wrong occurred, so delete word
delete _word;
_word = nullptr;
} else {
// Add the word to the master vocab list
addWord(_word);
}
}
}
// Close resource and return result
delete file;
return result;
}
void TTvocab::addWord(TTword *word) {
TTword *existingWord = g_language == Common::DE_DEU ? nullptr :
findWord(word->_text);
if (existingWord) {
if (word->_synP) {
// Move over the synonym
existingWord->appendNode(word->_synP);
word->_synP = nullptr;
}
_word = nullptr;
if (word)
delete word;
} else if (_tailP) {
_tailP->_nextP = word;
_tailP = word;
} else {
if (!_headP)
_headP = word;
_tailP = word;
}
}
TTword *TTvocab::findWord(const TTstring &str) {
TTsynonym *tempNode = new TTsynonym();
bool flag = false;
TTword *word = _headP;
while (word && !flag) {
if (_vocabMode != VOCAB_MODE_EN || strcmp(word->c_str(), str)) {
if (word->findSynByName(str, tempNode, _vocabMode))
flag = true;
else
word = word->_nextP;
} else {
flag = true;
}
}
delete tempNode;
return word;
}
TTword *TTvocab::getWord(TTstring &str, TTword **srcWord) const {
TTword *word = getPrimeWord(str, srcWord);
if (!word) {
TTstring tempStr(str);
if (tempStr.size() > 2) {
word = getSuffixedWord(tempStr, srcWord);
if (!word)
word = getPrefixedWord(tempStr, srcWord);
}
}
return word;
}
TTword *TTvocab::getPrimeWord(TTstring &str, TTword **srcWord) const {
TTsynonym tempSyn;
char c = str.charAt(0);
TTword *newWord = nullptr;
TTword *vocabP;
if (Common::isDigit(c)) {
// Number
vocabP = _headP;
newWord = new TTword(str, WC_ABSTRACT, 300);
} else {
// Standard word
for (vocabP = _headP; vocabP; vocabP = vocabP->_nextP) {
if (_vocabMode == VOCAB_MODE_EN && !strcmp(str.c_str(), vocabP->c_str())) {
newWord = vocabP->copy();
newWord->_nextP = nullptr;
newWord->setSyn(nullptr);
break;
} else if (vocabP->findSynByName(str, &tempSyn, _vocabMode)) {
// Create a copy of the word and the found synonym
TTsynonym *newSyn = new TTsynonym(tempSyn);
newSyn->_nextP = newSyn->_priorP = nullptr;
newWord = vocabP->copy();
newWord->_nextP = nullptr;
newWord->setSyn(newSyn);
break;
}
}
}
if (srcWord)
// Pass out the pointer to the original word
*srcWord = vocabP;
// Return the new copy of the word
return newWord;
}
TTword *TTvocab::getSuffixedWord(TTstring &str, TTword **srcWord) const {
TTstring tempStr(str);
TTword *word = nullptr;
if (g_language == Common::DE_DEU) {
static const char *const SUFFIXES[11] = {
"est", "em", "en", "er", "es", "et", "st",
"s", "e", "n", "t"
};
for (int idx = 0; idx < 11; ++idx) {
if (tempStr.hasSuffix(SUFFIXES[idx])) {
tempStr.deleteSuffix(strlen(SUFFIXES[idx]));
word = getPrimeWord(tempStr, srcWord);
if (word)
break;
tempStr = str;
}
}
if (word)
word->setSynStr(str);
return word;
}
if (tempStr.hasSuffix("s")) {
tempStr.deleteSuffix(1);
word = getPrimeWord(tempStr);
if (!word) {
if (!tempStr.hasSuffix("e")) {
tempStr = str;
} else {
tempStr.deleteLastChar();
word = getPrimeWord(tempStr);
}
}
} else if (tempStr.hasSuffix("ing")) {
tempStr.deleteSuffix(3);
word = getPrimeWord(tempStr);
if (word) {
if (word->_wordClass == 1) {
delete word;
word = nullptr;
} else {
delete word;
word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
}
} else {
tempStr += "e";
word = getPrimeWord(tempStr);
if (word) {
if (word->_wordClass != 1) {
delete word;
word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
}
} else {
tempStr.deleteSuffix(2);
word = getPrimeWord(tempStr);
if (word) {
if (word->_wordClass != 1) {
delete word;
word = new TTadj(str, WC_ADJECTIVE, 0, 0, 0);
}
} else {
tempStr = str;
}
}
}
} else if (tempStr.hasSuffix("ed")) {
tempStr.deleteSuffix(1);
word = getPrimeWord(tempStr);
if (!word) {
tempStr.deleteSuffix(1);
word = getPrimeWord(tempStr);
}
if (word) {
if (word->_wordClass == WC_ACTION) {
TTaction *action = dynamic_cast<TTaction *>(word);
assert(action);
action->setVal(1);
}
} else {
tempStr = str;
}
} else if (tempStr.hasSuffix("ly")) {
tempStr.deleteSuffix(2);
word = getPrimeWord(tempStr);
if (word) {
delete word;
word = new TTword(str, WC_ADVERB, 0);
} else {
tempStr = str;
}
} else if (tempStr.hasSuffix("er")) {
tempStr.deleteSuffix(1);
word = getPrimeWord(tempStr);
if (word) {
if (word->_wordClass == WC_ADJECTIVE) {
TTadj *adj = static_cast<TTadj *>(word);
int val1 = word->proc15();
int val2 = word->proc15();
if (val2 < 5) {
if (--val1 > 0) {
adj->adjFn1(val1);
}
} else {
if (++val1 < 11) {
adj->adjFn1(val1);
}
}
}
} else {
tempStr.deleteSuffix(1);
word = getPrimeWord(tempStr);
if (word) {
if (word->_wordClass == WC_ADJECTIVE) {
TTadj *adj = dynamic_cast<TTadj *>(word);
int val1 = word->proc15();
int val2 = word->proc15();
if (val2 < 5) {
if (--val1 > 0) {
adj->adjFn1(val1);
}
} else {
if (++val1 < 11) {
adj->adjFn1(val1);
}
}
}
} else {
tempStr.deleteSuffix(1);
word = getPrimeWord(tempStr);
if (word && word->_wordClass == WC_ADJECTIVE) {
TTadj *adj = dynamic_cast<TTadj *>(word);
int val1 = word->proc15();
int val2 = word->proc15();
if (val2 < 5) {
if (--val1 > 0) {
adj->adjFn1(val1);
}
} else {
if (++val1 < 11) {
adj->adjFn1(val1);
}
}
}
}
}
} else if (tempStr.hasSuffix("est")) {
tempStr.deleteSuffix(2);
word = getPrimeWord(tempStr);
if (word) {
if (word->_wordClass == WC_ADJECTIVE) {
TTadj *adj = static_cast<TTadj *>(word);
int val1 = word->proc15();
int val2 = word->proc15();
if (val2 < 5) {
if (--val1 > 0) {
adj->adjFn1(val1);
}
} else {
if (++val1 < 11) {
adj->adjFn1(val1);
}
}
}
} else {
tempStr.deleteSuffix(1);
word = getPrimeWord(tempStr);
if (word) {
if (word->_wordClass == WC_ADJECTIVE) {
TTadj *adj = dynamic_cast<TTadj *>(word);
int val1 = word->proc15();
int val2 = word->proc15();
if (val2 < 5) {
if (--val1 > 0) {
adj->adjFn1(val1);
}
} else {
if (++val1 < 11) {
adj->adjFn1(val1);
}
}
}
} else {
tempStr.deleteSuffix(1);
word = getPrimeWord(tempStr);
if (word) {
TTadj *adj = dynamic_cast<TTadj *>(word);
int val1 = word->proc15();
int val2 = word->proc15();
if (val2 < 5) {
if (--val1 > 0) {
adj->adjFn1(val1);
}
} else {
if (++val1 < 11) {
adj->adjFn1(val1);
}
}
}
}
}
} else if (tempStr.hasSuffix("s*")) {
tempStr.deleteSuffix(2);
word = getPrimeWord(tempStr);
if (word) {
if (word->_wordClass == WC_PRONOUN || word->_wordClass == WC_ADVERB) {
delete word;
TTstring isStr("is");
word = getPrimeWord(isStr);
} else {
switch (word->_id) {
case 200:
if (word->proc10() == 2) {
delete word;
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
} else if (word->proc10() == 1) {
delete word;
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 4);
}
break;
case 201:
delete word;
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
break;
case 202:
case 203:
if (word->proc10() == 2) {
delete word;
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 5);
} else {
int val = word->proc10() == 1 ? 0 : 4;
delete word;
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, val);
}
break;
case 204:
delete word;
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 6);
break;
default:
delete word;
word = new TTpronoun(tempStr, WC_PRONOUN, 601, 0, 0);
break;
}
}
}
}
if (word)
word->setSynStr(str);
return word;
}
TTword *TTvocab::getPrefixedWord(TTstring &str, TTword **srcWord) const {
TTstring tempStr(str);
TTword *word = nullptr;
int prefixLen = 0;
if (tempStr.hasPrefix("pre")) {
prefixLen = 3;
} else if (tempStr.hasPrefix("re") || tempStr.hasPrefix("co")) {
prefixLen = 2;
} else if (tempStr.hasPrefix("inter") || tempStr.hasPrefix("multi")) {
prefixLen = 5;
} else if (tempStr.hasPrefix("over") || tempStr.hasPrefix("post") || tempStr.hasPrefix("self")) {
prefixLen = 4;
}
if (prefixLen) {
// Known prefix found, so scan for word without prefix
tempStr.deletePrefix(prefixLen);
word = getPrimeWord(tempStr);
if (word)
tempStr = str;
} else if (tempStr.hasPrefix("anti") || tempStr.hasPrefix("counter")) {
prefixLen = tempStr[0] == 'a' ? 4 : 7;
tempStr.deletePrefix(prefixLen);
word = getPrimeWord(tempStr);
if (!word)
tempStr = str;
else if (word->_wordClass == 8) {
delete word;
word = nullptr;
}
} else if (tempStr.hasPrefix("hyper") || tempStr.hasPrefix("super") ||
tempStr.hasPrefix("ultra")) {
tempStr.deletePrefix(5);
word = getPrimeWord(tempStr);
if (!word)
tempStr = str;
else if (word->_wordClass == WC_ADJECTIVE) {
TTadj *adj = static_cast<TTadj *>(word);
int val1 = word->proc15();
int val2 = word->proc15();
if (val2 < 5) {
if (--val1 > 0)
adj->adjFn1(val1);
} else if (++val1 < 11) {
adj->adjFn1(val1);
}
}
}
if (word) {
// Set the original word on either the found word or synonym
if (word->hasSynonyms())
word->setSynStr(str);
else
word->_text = str;
}
return word;
}
} // End of namespace Titanic

View 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_ST_VOCAB_H
#define TITANIC_ST_VOCAB_H
#include "titanic/support/exe_resources.h"
#include "titanic/support/string.h"
#include "titanic/true_talk/tt_string.h"
#include "titanic/true_talk/tt_word.h"
namespace Titanic {
class TTvocab {
private:
TTword *_headP;
TTword *_tailP;
TTword *_word;
VocabMode _vocabMode;
private:
/**
* Load the vocab data
*/
int load(const CString &name);
/**
* Adds a specified word to the vocab list
*/
void addWord(TTword *word);
/**
* Scans the vocab list for an existing word match
*/
TTword *findWord(const TTstring &str);
/**
* Scans the vocab list for a word with a synonym matching the passed string.
* If found, creates a new word instance that only has the matching synonym
* linked to it.
* @param str Word text to scan for
* @param srcWord Optional pointer to store the original word match was found on
* @returns A new word instance if a match if found, or null if not
*/
TTword *getPrimeWord(TTstring &str, TTword **srcWord = nullptr) const;
/**
* Checks the passed word for common suffixes, like 's', 'ing', etc. and, if found,
* checks for a word match for the base word without the suffix.
* @param str Word to check
* @returns New word instance for found match, or nullptr otherwise
*/
TTword *getSuffixedWord(TTstring &str, TTword **srcWord = nullptr) const;
/**
* Checks the passed word for common prefixes, and checks for a word
* match for the word without the given prefix
* @param str Word to check
* @returns New word instance for found match, or nullptr otherwise
*/
TTword *getPrefixedWord(TTstring &str, TTword **srcWord = nullptr) const;
public:
TTvocab(VocabMode vocabMode);
~TTvocab();
/**
* Gets a matching word from the vocab list given a passed string
* @param str Word text to scan for
* @param srcWord Optional pointer to store the original word match was found on
* @returns A new word instance if a match if found, or null if not
*/
TTword *getWord(TTstring &str, TTword **srcWord = nullptr) const;
};
} // End of namespace Titanic
#endif /* TITANIC_ST_VOCAB_H */

View File

@@ -0,0 +1,226 @@
/* 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/true_talk/tt_word.h"
#include "titanic/true_talk/tt_string_node.h"
#include "titanic/titanic.h"
namespace Titanic {
TTword::TTword(const TTstring &str, WordClass wordClass, int id) : _text(str),
_wordClass(wordClass), _id(id), _tag(0), _field24(0),
_field28(0), _synP(nullptr), _nextP(nullptr) {
_status = str.getStatus() == SS_VALID ? SS_VALID : SS_5;
}
TTword::TTword(const TTword *src) {
if (src->getStatus() != SS_VALID) {
_status = SS_5;
return;
}
_text = src->_text;
_wordClass = src->_wordClass;
_id = src->_id;
_tag = src->_tag;
_synP = nullptr;
_status = SS_VALID;
TTsynonym *priorSyn = nullptr;
for (TTsynonym *synP = _synP; synP && !_status;) {
TTsynonym *newSyn = new TTsynonym(synP);
if (!newSyn) {
_status = SS_7;
} else {
newSyn->_priorP = priorSyn;
newSyn->_nextP = nullptr;
if (priorSyn) {
priorSyn->_nextP = newSyn;
} else {
_synP = newSyn;
}
priorSyn = newSyn;
}
}
_nextP = src->_nextP;
_field24 = src->_field24;
_field28 = src->_field28;
}
TTword::~TTword() {
if (_synP) {
_synP->deleteSiblings();
delete _synP;
}
}
void TTword::deleteSiblings() {
while (_nextP) {
TTword *next = _nextP;
_nextP = next->_nextP;
delete next;
}
}
int TTword::readSyn(SimpleFile *file) {
CString str;
int mode, val1;
if (!file->scanf("%s %d %d", &str, &mode, &val1))
return 8;
if (!testFileHandle(file))
return 5;
// Create new synanym node
TTsynonym *synNode = new TTsynonym(mode, str.c_str(), (FileHandle)val1);
if (_synP) {
// A synonym already exists, so add new one as a tail
// at the end of the linked list of synonyms
_synP->addToTail(synNode);
} else {
// Very first synonym, so set it
_synP = synNode;
}
return 0;
}
void TTword::setSyn(TTsynonym *synP) {
if (_synP) {
_synP->deleteSiblings();
delete _synP;
}
_synP = synP;
}
int TTword::setSynStr(TTstring &str) {
if (str.empty())
return 4;
TTsynonym *newSyn = new TTsynonym(4, str);
setSyn(newSyn);
return 0;
}
void TTword::appendNode(TTsynonym *node) {
if (_synP)
_synP->addToTail(node);
else
_synP = node;
}
int TTword::load(SimpleFile *file, WordClass wordClass) {
CString str1, str2;
int id;
if (file->scanf("%d %s %s", &id, &str1, &str2)) {
_text = str1;
_id = id;
_tag = readNumber(str2.c_str());
_wordClass = wordClass;
return 0;
} else {
return 3;
}
}
uint TTword::readNumber(const char *str) {
uint numValue = *str;
if (*str == '0') {
numValue = MKTAG('Z', 'Z', 'Z', '[');
} else {
++str;
for (int idx = 0; idx < 3; ++idx, ++str)
numValue = (numValue << 8) + *str;
}
return numValue;
}
bool TTword::testFileHandle(FileHandle file) const {
if (g_vm->_exeResources.isVocabMode(VOCAB_MODE_EN))
return true;
// TODO: Figure out why original compares passed file handle against specific values
return true;
}
bool TTword::findSynByName(const TTstring &str, TTsynonym *dest, VocabMode mode) const {
if (!_synP)
return false;
const TTsynonym *synP = dynamic_cast<const TTsynonym *>(_synP->findByName(str, mode));
if (synP) {
dest->copyFrom(synP);
dest->_priorP = nullptr;
dest->_nextP = nullptr;
return true;
} else {
return false;
}
}
bool TTword::compareTo(const char *str) const {
return _text == str;
}
TTword *TTword::copy() const {
return new TTword(this);
}
FileHandle TTword::getSynFile() const {
return _synP ? _synP->_file : HANDLE_STDIN;
}
bool TTword::checkSynFile(FileHandle file) const {
return _synP && _synP->_file == file;
}
void TTword::setSynFile(FileHandle file) {
if (_synP && testFileHandle(file))
_synP->_file = file;
}
TTstringStatus TTword::getChainStatus() const {
for (const TTword *word = this; word; word = word->_nextP) {
if (word->getStatus())
return word->getStatus();
}
return SS_VALID;
}
TTword *TTword::copyWords() {
// Replicate the word and all following words it's linked to
TTword *result = copy();
for (TTword *word = result; word->_nextP; word = word->_nextP)
word->_nextP = word->_nextP->copy();
return result;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,217 @@
/* 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_TT_WORD_H
#define TITANIC_TT_WORD_H
#include "titanic/support/exe_resources.h"
#include "titanic/support/simple_file.h"
#include "titanic/true_talk/tt_string.h"
#include "titanic/true_talk/tt_synonym.h"
namespace Titanic {
/**
* Types of words
*/
enum WordClass {
WC_UNKNOWN = 0, WC_ACTION = 1, WC_THING = 2, WC_ABSTRACT = 3,
WC_ARTICLE = 4, WC_CONJUNCTION = 5, WC_PRONOUN = 6,
WC_PREPOSITION = 7, WC_ADJECTIVE = 8, WC_ADVERB = 9
};
class TTword {
protected:
TTstringStatus _status;
int _field24;
int _field28;
protected:
/**
* Read in a number
*/
uint readNumber(const char *str);
bool testFileHandle(SimpleFile *file) const { return true; }
bool testFileHandle(FileHandle resHandle) const;
public:
TTword *_nextP;
TTsynonym *_synP;
TTstring _text;
WordClass _wordClass;
int _id;
uint _tag;
public:
TTword(const TTstring &str, WordClass wordClass, int val2);
TTword(const TTword *src);
virtual ~TTword();
/**
* Delete any following words chained to the word
*/
void deleteSiblings();
/**
* Read in a synonym for the given word
*/
int readSyn(SimpleFile *file);
/**
* Set a new synonym for the word
*/
void setSyn(TTsynonym *synP);
/**
* Set a new synonym string
*/
int setSynStr(TTstring &str);
/**
* Returns true if synonyms have been set for the word
*/
bool hasSynonyms() const { return _synP != nullptr; }
/**
* Either sets the first synonym for a word, or adds it to an existing one
*/
void appendNode(TTsynonym *node);
/**
* Load the word
*/
int load(SimpleFile *file, WordClass wordClass);
/**
* Finds a synonym in the word by name, if one exists
* @param str Name to search for
* @param dest Destination synonym instance to copy match into
* @param mode Specifies English or German vocab mode
* @returns Returns true if a match was found
*/
bool findSynByName(const TTstring &str, TTsynonym *dest, VocabMode mode) const;
const char *c_str() const { return _text.c_str(); }
operator const char *() const { return c_str(); }
/**
* Return the text of the word
*/
const TTstring getText() { return _text; }
/**
* Compares the word's text to a passed string
*/
bool compareTo(const char *str) const;
/**
* Compares the word's text to a passed string
*/
bool compareTo(TTstring *str) const {
return compareTo(str->c_str());
}
/**
* Return the status of the word
*/
TTstringStatus getStatus() const { return _status; }
/**
* Returns true if the word is in a valid state
*/
bool isValid() const { return _status == SS_VALID; }
/**
* Return the status of the entire word chain
*/
TTstringStatus getChainStatus() const;
/**
* Returns true if the word is of the specified class
*/
bool isClass(WordClass wordClass) const { return _wordClass == wordClass; }
/**
* Copy the word and any attached to it
*/
TTword *copyWords();
/**
* Creates a copy of the word
*/
virtual TTword *copy() const;
virtual bool proc2(int val) const { return false; }
virtual int proc3() const { return -1; }
virtual void proc4() {}
virtual void proc5() {}
/**
* Checks whether the word's tag is a known type
*/
virtual bool checkTag() const { return false; }
/**
* Compare the word's tag to a given tag value
*/
virtual bool compareTagTo(uint tag) const { return false; }
/**
* Return the tag associated with the word
*/
virtual uint getTag() const { return 0; }
virtual bool proc9(int val) const { return false; }
virtual int proc10() const { return 0; }
virtual void proc11() {}
virtual bool proc12(int val) const { return false; }
virtual int proc13() const { return 0; }
virtual bool proc14(int val) const { return false; }
virtual int proc15() const { return -1; }
virtual bool proc16() const { return false; }
virtual bool proc17() const { return false; }
virtual bool proc18() const { return false; }
virtual bool comparePronounTo(int val) const { return false; }
virtual int proc20() const { return 0; }
/**
* Returns the file associated with the word's first synonym
*/
virtual FileHandle getSynFile() const;
/**
* Checks whether the file associated with the word's first
* synonym matches the specified file
*/
virtual bool checkSynFile(FileHandle file) const;
/**
* Sets the file associated with a synonym
*/
virtual void setSynFile(FileHandle file);
/**
* Dumps data associated with the word to file
*/
virtual int save(SimpleFile *file) const { return 0; }
};
} // End of namespace Titanic
#endif /* TITANIC_TT_WORD_H */