1 //Copyright Paul Reiche, Fred Ford. 1992-2002
2 
3 /*
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 #include "../commall.h"
20 #include <stdlib.h>
21 #include "resinst.h"
22 #include "strings.h"
23 
24 #include "options.h"
25 #include "uqm/battle.h"
26 #include "uqm/setup.h"
27 
28 
29 static const NUMBER_SPEECH_DESC probe_numbers_english;
30 
31 static LOCDATA slylandro_desc =
32 {
33 	NULL, /* init_encounter_func */
34 	NULL, /* post_encounter_func */
35 	NULL, /* uninit_encounter_func */
36 	SLYLAND_PMAP_ANIM, /* AlienFrame */
37 	SLYLAND_FONT, /* AlienFont */
38 	WHITE_COLOR_INIT, /* AlienTextFColor */
39 	BLACK_COLOR_INIT, /* AlienTextBColor */
40 	{0, 0}, /* AlienTextBaseline */
41 	0, /* SIS_TEXT_WIDTH - 16, */ /* AlienTextWidth */
42 	ALIGN_CENTER, /* AlienTextAlign */
43 	VALIGN_TOP, /* AlienTextValign */
44 	SLYLAND_COLOR_MAP, /* AlienColorMap */
45 	SLYLAND_MUSIC, /* AlienSong */
46 	NULL_RESOURCE, /* AlienAltSong */
47 	0, /* AlienSongFlags */
48 	SLYLAND_CONVERSATION_PHRASES, /* PlayerPhrases */
49 	6, /* NumAnimations */
50 	{ /* AlienAmbientArray (ambient animations) */
51 		{
52 			1, /* StartIndex */
53 			9, /* NumFrames */
54 			CIRCULAR_ANIM, /* AnimFlags */
55 			ONE_SECOND / 40, 0, /* FrameRate */
56 			0, ONE_SECOND * 3, /* RestartRate */
57 			(1 << 3) /* BlockMask */
58 		},
59 		{
60 			10, /* StartIndex */
61 			8, /* NumFrames */
62 			CIRCULAR_ANIM, /* AnimFlags */
63 			ONE_SECOND / 40, 0, /* FrameRate */
64 			0, ONE_SECOND * 3, /* RestartRate */
65 			(1 << 4) /* BlockMask */
66 		},
67 		{
68 			18, /* StartIndex */
69 			8, /* NumFrames */
70 			CIRCULAR_ANIM, /* AnimFlags */
71 			ONE_SECOND / 40, 0, /* FrameRate */
72 			0, ONE_SECOND * 3, /* RestartRate */
73 			(1 << 5) /* BlockMask */
74 		},
75 		{
76 			26, /* StartIndex */
77 			8, /* NumFrames */
78 			CIRCULAR_ANIM, /* AnimFlags */
79 			ONE_SECOND / 40, 0, /* FrameRate */
80 			0, ONE_SECOND * 3, /* RestartRate */
81 			(1 << 0) /* BlockMask */
82 		},
83 		{
84 			34, /* StartIndex */
85 			8, /* NumFrames */
86 			CIRCULAR_ANIM, /* AnimFlags */
87 			ONE_SECOND / 40, 0, /* FrameRate */
88 			0, ONE_SECOND * 3, /* RestartRate */
89 			(1 << 1) /* BlockMask */
90 		},
91 		{
92 			42, /* StartIndex */
93 			9, /* NumFrames */
94 			CIRCULAR_ANIM, /* AnimFlags */
95 			ONE_SECOND / 40, 0, /* FrameRate */
96 			0, ONE_SECOND * 3, /* RestartRate */
97 			(1 << 2) /* BlockMask */
98 		},
99 	},
100 	{ /* AlienTransitionDesc - empty */
101 		0, /* StartIndex */
102 		0, /* NumFrames */
103 		0, /* AnimFlags */
104 		0, 0, /* FrameRate */
105 		0, 0, /* RestartRate */
106 		0, /* BlockMask */
107 	},
108 	{ /* AlienTalkDesc - empty */
109 		0, /* StartIndex */
110 		0, /* NumFrames */
111 		0, /* AnimFlags */
112 		0, 0, /* FrameRate */
113 		0, 0, /* RestartRate */
114 		0, /* BlockMask */
115 	},
116 	&probe_numbers_english, /* AlienNumberSpeech - default */
117 	/* Filler for loaded resources */
118 	NULL, NULL, NULL,
119 	NULL,
120 	NULL,
121 };
122 
123 static COUNT probe_digit_names[] =
124 {
125 	ENUMERATE_ZERO,
126 	ENUMERATE_ONE,
127 	ENUMERATE_TWO,
128 	ENUMERATE_THREE,
129 	ENUMERATE_FOUR,
130 	ENUMERATE_FIVE,
131 	ENUMERATE_SIX,
132 	ENUMERATE_SEVEN,
133 	ENUMERATE_EIGHT,
134 	ENUMERATE_NINE,
135 };
136 
137 static COUNT probe_teen_names[] =
138 {
139 	ENUMERATE_TEN,
140 	ENUMERATE_ELEVEN,
141 	ENUMERATE_TWELVE,
142 	ENUMERATE_THIRTEEN,
143 	ENUMERATE_FOURTEEN,
144 	ENUMERATE_FIFTEEN,
145 	ENUMERATE_SIXTEEN,
146 	ENUMERATE_SEVENTEEN,
147 	ENUMERATE_EIGHTEEN,
148 	ENUMERATE_NINETEEN,
149 };
150 
151 static COUNT probe_tens_names[] =
152 {
153 	0, /* invalid */
154 	0, /* skip digit */
155 	ENUMERATE_TWENTY,
156 	ENUMERATE_THIRTY,
157 	ENUMERATE_FOURTY,
158 	ENUMERATE_FIFTY,
159 	ENUMERATE_SIXTY,
160 	ENUMERATE_SEVENTY,
161 	ENUMERATE_EIGHTY,
162 	ENUMERATE_NINETY,
163 };
164 
165 static const NUMBER_SPEECH_DESC probe_numbers_english =
166 {
167 	5, /* NumDigits */
168 	{
169 		{ /* 1000-999999 */
170 			1000, /* Divider */
171 			0, /* Subtrahend */
172 			NULL, /* StrDigits - recurse */
173 			NULL, /* Names - not used */
174 			ENUMERATE_THOUSAND /* CommonIndex */
175 		},
176 		{ /* 100-999 */
177 			100, /* Divider */
178 			0, /* Subtrahend */
179 			probe_digit_names, /* StrDigits */
180 			NULL, /* Names - not used */
181 			ENUMERATE_HUNDRED /* CommonIndex */
182 		},
183 		{ /* 20-99 */
184 			10, /* Divider */
185 			0, /* Subtrahend */
186 			probe_tens_names, /* StrDigits */
187 			NULL, /* Names - not used */
188 			0 /* CommonIndex - not used */
189 		},
190 		{ /* 10-19 */
191 			1, /* Divider */
192 			10, /* Subtrahend */
193 			probe_teen_names, /* StrDigits */
194 			NULL, /* Names - not used */
195 			0 /* CommonIndex - not used */
196 		},
197 		{ /* 0-9 */
198 			1, /* Divider */
199 			0, /* Subtrahend */
200 			probe_digit_names, /* StrDigits */
201 			NULL, /* Names - not used */
202 			0 /* CommonIndex - not used */
203 		}
204 	}
205 };
206 
207 static RESPONSE_REF threat,
208 			something_wrong,
209 			we_are_us,
210 			why_attack,
211 			bye;
212 
213 static void
sayCoord(int coord)214 sayCoord (int coord)
215 {
216 	int ac;
217 
218 	ac = abs (coord);
219 
220 	NPCPhrase_splice (coord < 0 ? COORD_MINUS : COORD_PLUS);
221 	NPCNumber (ac / 10, "%03d");
222 	NPCPhrase_splice (COORD_POINT);
223 	NPCNumber (ac % 10, NULL);
224 }
225 
226 static void
CombatIsInevitable(RESPONSE_REF R)227 CombatIsInevitable (RESPONSE_REF R)
228 {
229 	if (R == 0)
230 	{
231 		if (GET_GAME_STATE (DESTRUCT_CODE_ON_SHIP))
232 			Response (destruct_code, CombatIsInevitable);
233 		switch (GET_GAME_STATE (SLYLANDRO_PROBE_THREAT))
234 		{
235 			case 0:
236 				threat = threat_1;
237 				break;
238 			case 1:
239 				threat = threat_2;
240 				break;
241 			case 2:
242 				threat = threat_3;
243 				break;
244 			default:
245 				threat = threat_4;
246 				break;
247 		}
248 		Response (threat, CombatIsInevitable);
249 		switch (GET_GAME_STATE (SLYLANDRO_PROBE_WRONG))
250 		{
251 			case 0:
252 				something_wrong = something_wrong_1;
253 				break;
254 			case 1:
255 				something_wrong = something_wrong_2;
256 				break;
257 			case 2:
258 				something_wrong = something_wrong_3;
259 				break;
260 			default:
261 				something_wrong = something_wrong_4;
262 				break;
263 		}
264 		Response (something_wrong, CombatIsInevitable);
265 		switch (GET_GAME_STATE (SLYLANDRO_PROBE_ID))
266 		{
267 			case 0:
268 				we_are_us = we_are_us_1;
269 				break;
270 			case 1:
271 				we_are_us = we_are_us_2;
272 				break;
273 			case 2:
274 				we_are_us = we_are_us_3;
275 				break;
276 			default:
277 				we_are_us = we_are_us_4;
278 				break;
279 		}
280 		Response (we_are_us, CombatIsInevitable);
281 		switch (GET_GAME_STATE (SLYLANDRO_PROBE_INFO))
282 		{
283 			case 0:
284 				why_attack = why_attack_1;
285 				break;
286 			case 1:
287 				why_attack = why_attack_2;
288 				break;
289 			case 2:
290 				why_attack = why_attack_3;
291 				break;
292 			default:
293 				why_attack = why_attack_4;
294 				break;
295 		}
296 		Response (why_attack, CombatIsInevitable);
297 		switch (GET_GAME_STATE (SLYLANDRO_PROBE_EXIT))
298 		{
299 			case 0:
300 				bye = bye_1;
301 				break;
302 			case 1:
303 				bye = bye_2;
304 				break;
305 			case 2:
306 				bye = bye_3;
307 				break;
308 			default:
309 				bye = bye_4;
310 				break;
311 		}
312 		Response (bye, CombatIsInevitable);
313 	}
314 	else if (PLAYER_SAID (R, destruct_code))
315 	{
316 		NPCPhrase (DESTRUCT_SEQUENCE);
317 		setSegue (Segue_victory);
318 	}
319 	else
320 	{
321 		BYTE NumVisits;
322 
323 		if (PLAYER_SAID (R, threat))
324 		{
325 			NumVisits = GET_GAME_STATE (SLYLANDRO_PROBE_THREAT);
326 			switch (NumVisits++)
327 			{
328 				case 0:
329 					NPCPhrase (PROGRAMMED_TO_DEFEND_1);
330 					break;
331 				case 1:
332 					NPCPhrase (PROGRAMMED_TO_DEFEND_2);
333 					break;
334 				case 2:
335 					NPCPhrase (PROGRAMMED_TO_DEFEND_3);
336 					break;
337 				case 3:
338 					NPCPhrase (PROGRAMMED_TO_DEFEND_4);
339 					--NumVisits;
340 					break;
341 			}
342 			SET_GAME_STATE (SLYLANDRO_PROBE_THREAT, NumVisits);
343 		}
344 		else if (PLAYER_SAID (R, something_wrong))
345 		{
346 			NumVisits = GET_GAME_STATE (SLYLANDRO_PROBE_WRONG);
347 			switch (NumVisits++)
348 			{
349 				case 0:
350 					NPCPhrase (NOMINAL_FUNCTION_1);
351 					break;
352 				case 1:
353 					NPCPhrase (NOMINAL_FUNCTION_2);
354 					break;
355 				case 2:
356 					NPCPhrase (NOMINAL_FUNCTION_3);
357 					break;
358 				case 3:
359 					NPCPhrase (NOMINAL_FUNCTION_4);
360 					--NumVisits;
361 					break;
362 			}
363 			SET_GAME_STATE (SLYLANDRO_PROBE_WRONG, NumVisits);
364 		}
365 		else if (PLAYER_SAID (R, we_are_us))
366 		{
367 			NumVisits = GET_GAME_STATE (SLYLANDRO_PROBE_ID);
368 			switch (NumVisits++)
369 			{
370 				case 0:
371 					NPCPhrase (THIS_IS_PROBE_1);
372 					break;
373 				case 1:
374 					NPCPhrase (THIS_IS_PROBE_2);
375 					break;
376 				case 2:
377 					NPCPhrase (THIS_IS_PROBE_3);
378 					break;
379 				case 3:
380 				{
381 					SIZE dx, dy;
382 
383 					// Probe's coordinate system is {-Y,X} relative to B Corvi
384 					dx = LOGX_TO_UNIVERSE (GLOBAL_SIS (log_x)) - 333;
385 					dy = 9812 - LOGY_TO_UNIVERSE (GLOBAL_SIS (log_y));
386 
387 					NPCPhrase (THIS_IS_PROBE_40);
388 					sayCoord (dy);
389 					NPCPhrase_splice (THIS_IS_PROBE_41);
390 					sayCoord (dx);
391 					NPCPhrase (THIS_IS_PROBE_42);
392 
393 					--NumVisits;
394 					break;
395 				}
396 			}
397 			SET_GAME_STATE (SLYLANDRO_PROBE_ID, NumVisits);
398 		}
399 		else if (PLAYER_SAID (R, why_attack))
400 		{
401 			NumVisits = GET_GAME_STATE (SLYLANDRO_PROBE_INFO);
402 			switch (NumVisits++)
403 			{
404 				case 0:
405 					NPCPhrase (PEACEFUL_MISSION_1);
406 					break;
407 				case 1:
408 					NPCPhrase (PEACEFUL_MISSION_2);
409 					break;
410 				case 2:
411 					NPCPhrase (PEACEFUL_MISSION_3);
412 					break;
413 				case 3:
414 					NPCPhrase (PEACEFUL_MISSION_4);
415 					--NumVisits;
416 					break;
417 			}
418 			SET_GAME_STATE (SLYLANDRO_PROBE_INFO, NumVisits);
419 		}
420 		else if (PLAYER_SAID (R, bye))
421 		{
422 			NumVisits = GET_GAME_STATE (SLYLANDRO_PROBE_EXIT);
423 			switch (NumVisits++)
424 			{
425 				case 0:
426 					NPCPhrase (GOODBYE_1);
427 					break;
428 				case 1:
429 					NPCPhrase (GOODBYE_2);
430 					break;
431 				case 2:
432 					NPCPhrase (GOODBYE_3);
433 					break;
434 				case 3:
435 					NPCPhrase (GOODBYE_4);
436 					--NumVisits;
437 					break;
438 			}
439 			SET_GAME_STATE (SLYLANDRO_PROBE_EXIT, NumVisits);
440 		}
441 
442 		NPCPhrase (HOSTILE);
443 
444 		SET_GAME_STATE (PROBE_EXHIBITED_BUG, 1);
445 		setSegue (Segue_hostile);
446 	}
447 }
448 
449 static void
Intro(void)450 Intro (void)
451 {
452 	BYTE  NumVisits;
453 
454 	NumVisits = GET_GAME_STATE (SLYLANDRO_PROBE_VISITS);
455 	switch (NumVisits++)
456 	{
457 		case 0:
458 			NPCPhrase (WE_COME_IN_PEACE_1);
459 			break;
460 		case 1:
461 			NPCPhrase (WE_COME_IN_PEACE_2);
462 			break;
463 		case 2:
464 			NPCPhrase (WE_COME_IN_PEACE_3);
465 			break;
466 		case 3:
467 			NPCPhrase (WE_COME_IN_PEACE_4);
468 			break;
469 		case 4:
470 			NPCPhrase (WE_COME_IN_PEACE_5);
471 			break;
472 		case 5:
473 			NPCPhrase (WE_COME_IN_PEACE_6);
474 			break;
475 		case 6:
476 			NPCPhrase (WE_COME_IN_PEACE_7);
477 			break;
478 		case 7:
479 			NPCPhrase (WE_COME_IN_PEACE_8);
480 			--NumVisits;
481 			break;
482 	}
483 	SET_GAME_STATE (SLYLANDRO_PROBE_VISITS, NumVisits);
484 
485 	CombatIsInevitable ((RESPONSE_REF)0);
486 }
487 
488 static COUNT
uninit_slyland(void)489 uninit_slyland (void)
490 {
491 	return (0);
492 }
493 
494 static void
post_slyland_enc(void)495 post_slyland_enc (void)
496 {
497 	// nothing defined so far
498 }
499 
500 LOCDATA*
init_slyland_comm(void)501 init_slyland_comm (void)
502 {
503 	LOCDATA *retval;
504 
505 	slylandro_desc.init_encounter_func = Intro;
506 	slylandro_desc.post_encounter_func = post_slyland_enc;
507 	slylandro_desc.uninit_encounter_func = uninit_slyland;
508 
509 	slylandro_desc.AlienTextBaseline.x = TEXT_X_OFFS + (SIS_TEXT_WIDTH >> 1);
510 	slylandro_desc.AlienTextBaseline.y = 0;
511 	slylandro_desc.AlienTextWidth = SIS_TEXT_WIDTH - 16;
512 
513 	setSegue (Segue_hostile);
514 	retval = &slylandro_desc;
515 
516 	return (retval);
517 }
518 
519