diff options
Diffstat (limited to 'engines/titanic/true_talk/tt_sentence.cpp')
-rw-r--r-- | engines/titanic/true_talk/tt_sentence.cpp | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/engines/titanic/true_talk/tt_sentence.cpp b/engines/titanic/true_talk/tt_sentence.cpp new file mode 100644 index 0000000000..9588ee021e --- /dev/null +++ b/engines/titanic/true_talk/tt_sentence.cpp @@ -0,0 +1,347 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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" + +namespace Titanic { + +TTsentenceConcept *TTsentenceConcept::addSibling() { + if (this == nullptr || _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), _field2C(1), _inputCtr(inputCtr), _field34(0), + _field38(0), _initialLine(line), _nodesP(nullptr), _roomScript(roomScript), + _npcScript(npcScript), _field58(0), _field5C(0) { + _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; + _field2C = src._field2C; + _nodesP = nullptr; + + if (src._nodesP) { + // Source has processed nodes, so duplicate them + for (TTsentenceNode *node = src._nodesP; node; + node = static_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 && !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 *concept = getFrameSlot(slotIndex, node); + + if (!concept) + return str == "isEmpty"; + + bool abortFlag = false; + switch (concept->_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 = concept->getText(); + if (abortFlag || str == conceptText || concept->compareTo(str)) { + delete concept; + 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->_concept2P->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->_concept2P->getText()) { + delete concept; + concept = getFrameSlot(5, node); + conceptText = concept->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 concept; + return abortFlag; +} + +bool TTsentence::fn4(int mode, int wordId, const TTconceptNode *node) const { + if (!node) + node = &_sentenceConcept; + + switch (mode) { + case 1: + return node->_concept1P && node->_concept1P->getWordId() == wordId; + + case 5: + return node->_concept5P && node->_concept5P->getWordId() == 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 *concept = getFrameEntry(slotIndex, conceptNode); + newConcept->copyFrom(concept); + + if (!newConcept->isValid()) { + delete newConcept; + newConcept = nullptr; + } + + return newConcept; +} + +bool TTsentence::isFrameSlotClass(int slotIndex, WordClass wordClass, const TTconceptNode *conceptNode) const { + TTconcept *concept = getFrameEntry(slotIndex, conceptNode); + if (concept && concept->_wordP) { + return concept->_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 *concept = getFrameEntry(slotIndex, node); + return concept && concept->getState(); +} + +bool TTsentence::localWord(const char *str) const { + CScriptHandler &scriptHandler = *g_vm->_exeResources._owner; + bool foundMatch = false; + + 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; + } + + int val = g_vm->_exeResources.get18(); + bool result = false; + + for (TTsentenceNode *nodeP = _nodesP; nodeP && !result; + nodeP = static_cast<TTsentenceNode *>(nodeP->_nextP)) { + TTsynonym syn; + if (!nodeP->_wordP) + continue; + + const TTstring wordStr = nodeP->_wordP->_text; + if (val == 3 && wordStr == str) { + result = true; + } else if (nodeP->_wordP->findSynByName(str, &syn, val)) { + result = true; + } else if (foundMatch) { + result = wordStr == "it" || wordStr == "that" || wordStr == "he" + || wordStr == "she" || wordStr == "him" || wordStr == "her" + || wordStr == "them" || wordStr == "they" || wordStr == "those" + || wordStr == "1" || wordStr == "thing"; + } + } + + return result; +} + +bool TTsentence::contains(const char *str) const { + return _initialLine.contains(str) || _normalizedLine.contains(str); +} + +} // End of namespace Titanic |