aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/true_talk/tt_sentence.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/titanic/true_talk/tt_sentence.cpp')
-rw-r--r--engines/titanic/true_talk/tt_sentence.cpp347
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