1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/textconsole.h"
24 #include "titanic/true_talk/succubus_script.h"
25 #include "titanic/true_talk/true_talk_manager.h"
26 #include "titanic/titanic.h"
27 #include "titanic/translation.h"
28 
29 namespace Titanic {
30 
SuccUBusScript(int val1,const char * charClass,int v2,const char * charName,int v3,int val2,int v4,int v5,int v6,int v7)31 SuccUBusScript::SuccUBusScript(int val1, const char *charClass, int v2,
32 		const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) :
33 		TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7),
34 		_isRoom101(false) {
35 
36 	loadRanges("Ranges/SuccUBus");
37 	setupSentences();
38 }
39 
setupSentences()40 void SuccUBusScript::setupSentences() {
41 	_mappings.load("Mappings/SuccUBus", 1);
42 	_entries.load("Sentences/SuccUBus");
43 	_field68 = 0;
44 	_entryCount = 0;
45 }
46 
chooseResponse(const TTroomScript * roomScript,const TTsentence * sentence,uint tag)47 int SuccUBusScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) {
48 	uint dialogueId = tag;
49 
50 	switch (tag) {
51 	case MKTAG('S', 'L', 'O', 'W'):
52 	case MKTAG('T', 'H', 'R', 'T'):
53 		dialogueId = 70021;
54 		break;
55 
56 	case MKTAG('S', 'U', 'C', '1'):
57 		dialogueId = getDialogueId(230009);
58 		break;
59 
60 	case MKTAG('S', 'U', 'C', '2'):
61 		dialogueId = 70117;
62 		break;
63 
64 	case MKTAG('S', 'W', 'E', 'R'):
65 		dialogueId = getRandomNumber(100) > 40 ? 70103 : getDialogueId(230030);
66 		break;
67 
68 	default:
69 		break;
70 	}
71 
72 	if (dialogueId) {
73 		addResponse(dialogueId);
74 		applyResponse();
75 		return 2;
76 	} else {
77 		return 1;
78 	}
79 }
80 
process(const TTroomScript * roomScript,const TTsentence * sentence)81 int SuccUBusScript::process(const TTroomScript *roomScript, const TTsentence *sentence) {
82 	if (!CTrueTalkManager::getStateValue(1))
83 		return 2;
84 
85 	if (roomScript && roomScript->_scriptId == 101)
86 		_isRoom101 = true;
87 
88 	int currState = getState();
89 	if (currState) {
90 		int currMode = sentence->_category;
91 		bool modeFlag1 = currMode == 11 || currMode == 13;
92 		bool modeFlag2 = currMode == 12;
93 		setState(0);
94 
95 		switch (currState) {
96 		case 1:
97 			if (currMode == 3 || currMode == 10)
98 				return setResponse(70050, 0);
99 			break;
100 
101 		case 2:
102 			if (modeFlag1 || modeFlag2)
103 				return setResponse(70070 + (getRandomBit() ? 254 : 0), 0);
104 			break;
105 
106 		case 3:
107 			if (currMode == 3 || currMode == 10)
108 				return setResponse(70074, 0);
109 			break;
110 
111 		case 4:
112 			if (currMode == 4)
113 				return setResponse(70077, 0);
114 			if (currMode == 3)
115 				return setResponse(getDialogueId(230117), 0);
116 			break;
117 
118 		case 5:
119 			if (currMode == 3 || currMode == 10)
120 				return setResponse(70089, 0);
121 			break;
122 
123 		case 6:
124 			if (modeFlag1)
125 				return setResponse(70103, 0);
126 			if (modeFlag2)
127 				return setResponse(70102, 0);
128 			break;
129 
130 		case 7:
131 			if (modeFlag1)
132 				return setResponse(getDialogueId(230157), 0);
133 			break;
134 
135 		case 8:
136 			if (modeFlag1)
137 				return setResponse(getDialogueId(230159), 0);
138 			break;
139 
140 		case 9:
141 			if (modeFlag1)
142 				return setResponse(getDialogueId(230160), 0);
143 			break;
144 
145 		case 10:
146 			if (modeFlag1)
147 				return setResponse(getDialogueId(230161), 0);
148 			break;
149 
150 		case 11:
151 			if (modeFlag1)
152 				return setResponse(getDialogueId(230142), 0);
153 			break;
154 
155 		case 12:
156 			return setResponse(70030, 0);
157 
158 		default:
159 			break;
160 		}
161 	}
162 
163 	if (processEntries(&_entries, _entryCount, roomScript, sentence) != 2) {
164 		uint tagId = g_vm->_trueTalkManager->_quotes.find(sentence->_normalizedLine.c_str());
165 		if (!tagId || chooseResponse(roomScript, sentence, tagId) != 2) {
166 			addResponse(getDialogueId(230030));
167 			applyResponse();
168 		}
169 	}
170 
171 	return 2;
172 }
173 
scriptChanged(const TTroomScript * roomScript,uint id)174 ScriptChangedResult SuccUBusScript::scriptChanged(const TTroomScript *roomScript, uint id) {
175 	if (g_language == Common::EN_ANY) {
176 		if (id == 148)
177 			CTrueTalkManager::setFlags(3, 1);
178 		else if (id == 150)
179 			CTrueTalkManager::setFlags(2, 1);
180 	} else {
181 		if (id == 70211 || id == 230013) {
182 			addResponse(getDialogueId(230163));
183 			applyResponse();
184 			return SCR_2;
185 		} else if (id < 70211) {
186 			if (id == 148)
187 				CTrueTalkManager::setFlags(3, 1);
188 			else if (id == 150)
189 				CTrueTalkManager::setFlags(2, 1);
190 		}
191 	}
192 
193 	if (id >= 230000 && id <= 230245) {
194 		addResponse(getDialogueId(id));
195 		applyResponse();
196 	} else if (id >= 70000 && id <= (uint)TRANSLATE(70243, 70248)) {
197 		addResponse(id);
198 		applyResponse();
199 	}
200 
201 	return SCR_2;
202 }
203 
updateState(uint oldId,uint newId,int index)204 int SuccUBusScript::updateState(uint oldId, uint newId, int index) {
205 	if (newId == 230199) {
206 		return _isRoom101 ? 230148 : newId;
207 	} else if (newId >= 230208 && newId <= 230235) {
208 		addResponse(70158 - getRandomBit());
209 		return newId;
210 	} else if (newId >= 230061 && newId <= 230063) {
211 		if (getValue(2))
212 			return 230125;
213 	}
214 
215 	static const uint UPDATE_STATES[][2] = {
216 		{ 230078, 1 }, { 230106, 2 }, { 230112, 3 }, { 230115, 4 },
217 		{ 230127, 5 }, { 230140, 6 }, { 230156, 7 }, { 230157, 8 },
218 		{ 230159, 9 }, { 230160, 10 }, { 230161, 11 }, { 230072, 12 }
219 	};
220 
221 	for (int idx = 0; idx < 12; ++idx) {
222 		if (UPDATE_STATES[idx][0] == newId) {
223 			setState(UPDATE_STATES[idx][1]);
224 			break;
225 		}
226 	}
227 
228 	return newId;
229 }
230 
doSentenceEntry(int val1,const int * srcIdP,const TTroomScript * roomScript,const TTsentence * sentence)231 int SuccUBusScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) {
232 	if (val1 == 1 && roomScript && roomScript->_scriptId == 101) {
233 		addResponse(getDialogueId(230239));
234 		applyResponse();
235 		return 2;
236 	}
237 
238 	return 0;
239 }
240 
setResponse(int dialogueId,int state)241 int SuccUBusScript::setResponse(int dialogueId, int state) {
242 	addResponse(dialogueId);
243 	applyResponse();
244 
245 	if (state != -1)
246 		setState(state);
247 
248 	return 2;
249 }
250 
251 } // End of namespace Titanic
252