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 "resinst.h"
21 #include "strings.h"
22 
23 #include "uqm/gameev.h"
24 
25 
26 static LOCDATA shofixti_desc =
27 {
28 	NULL, /* init_encounter_func */
29 	NULL, /* post_encounter_func */
30 	NULL, /* uninit_encounter_func */
31 	SHOFIXTI_PMAP_ANIM, /* AlienFrame */
32 	SHOFIXTI_FONT, /* AlienFont */
33 	WHITE_COLOR_INIT, /* AlienTextFColor */
34 	BLACK_COLOR_INIT, /* AlienTextBColor */
35 	{0, 0}, /* AlienTextBaseline */
36 	0, /* SIS_TEXT_WIDTH, */ /* AlienTextWidth */
37 	ALIGN_CENTER, /* AlienTextAlign */
38 	VALIGN_TOP, /* AlienTextValign */
39 	SHOFIXTI_COLOR_MAP, /* AlienColorMap */
40 	SHOFIXTI_MUSIC, /* AlienSong */
41 	NULL_RESOURCE, /* AlienAltSong */
42 	0, /* AlienSongFlags */
43 	SHOFIXTI_CONVERSATION_PHRASES, /* PlayerPhrases */
44 	11, /* NumAnimations */
45 	{ /* AlienAmbientArray (ambient animations) */
46 		{
47 			5, /* StartIndex */
48 			15, /* NumFrames */
49 			CIRCULAR_ANIM, /* AnimFlags */
50 			ONE_SECOND / 30, 0, /* FrameRate */
51 			ONE_SECOND / 30, 0, /* RestartRate */
52 			0, /* BlockMask */
53 		},
54 		{
55 			20, /* StartIndex */
56 			3, /* NumFrames */
57 			RANDOM_ANIM, /* AnimFlags */
58 			ONE_SECOND / 10, 0, /* FrameRate */
59 			(ONE_SECOND >> 1), (ONE_SECOND >> 1) * 3, /* RestartRate */
60 			0, /* BlockMask */
61 		},
62 		{
63 			23, /* StartIndex */
64 			3, /* NumFrames */
65 			RANDOM_ANIM, /* AnimFlags */
66 			ONE_SECOND / 10, 0, /* FrameRate */
67 			(ONE_SECOND >> 1), (ONE_SECOND >> 1) * 3, /* RestartRate */
68 			0, /* BlockMask */
69 		},
70 		{
71 			26, /* StartIndex */
72 			3, /* NumFrames */
73 			YOYO_ANIM, /* AnimFlags */
74 			ONE_SECOND / 30, 0, /* FrameRate */
75 			ONE_SECOND, ONE_SECOND * 3, /* RestartRate */
76 			0, /* BlockMask */
77 		},
78 		{
79 			29, /* StartIndex */
80 			4, /* NumFrames */
81 			YOYO_ANIM, /* AnimFlags */
82 			ONE_SECOND / 15, 0, /* FrameRate */
83 			ONE_SECOND, ONE_SECOND * 3, /* RestartRate */
84 			0, /* BlockMask */
85 		},
86 
87 		{
88 			33, /* StartIndex */
89 			6, /* NumFrames */
90 			CIRCULAR_ANIM, /* AnimFlags */
91 			ONE_SECOND / 20, ONE_SECOND / 30, /* FrameRate */
92 			ONE_SECOND / 20, ONE_SECOND / 30, /* RestartRate */
93 			0, /* BlockMask */
94 		},
95 		{
96 			39, /* StartIndex */
97 			7, /* NumFrames */
98 			CIRCULAR_ANIM, /* AnimFlags */
99 			ONE_SECOND / 20, ONE_SECOND / 30, /* FrameRate */
100 			ONE_SECOND / 20, ONE_SECOND / 30, /* RestartRate */
101 			(1 << 7), /* BlockMask */
102 		},
103 		{
104 			46, /* StartIndex */
105 			6, /* NumFrames */
106 			CIRCULAR_ANIM, /* AnimFlags */
107 			ONE_SECOND / 20, ONE_SECOND / 30, /* FrameRate */
108 			ONE_SECOND / 20, ONE_SECOND / 30, /* RestartRate */
109 			(1 << 6), /* BlockMask */
110 		},
111 		{
112 			52, /* StartIndex */
113 			4, /* NumFrames */
114 			CIRCULAR_ANIM, /* AnimFlags */
115 			ONE_SECOND / 20, ONE_SECOND / 30, /* FrameRate */
116 			ONE_SECOND / 20, ONE_SECOND / 30, /* RestartRate */
117 			0, /* BlockMask */
118 		},
119 		{
120 			56, /* StartIndex */
121 			7, /* NumFrames */
122 			CIRCULAR_ANIM, /* AnimFlags */
123 			ONE_SECOND / 20, ONE_SECOND / 30, /* FrameRate */
124 			ONE_SECOND / 20, ONE_SECOND / 30, /* RestartRate */
125 			(1 << 10), /* BlockMask */
126 		},
127 		{
128 			63, /* StartIndex */
129 			6, /* NumFrames */
130 			CIRCULAR_ANIM, /* AnimFlags */
131 			ONE_SECOND / 20, ONE_SECOND / 30, /* FrameRate */
132 			ONE_SECOND / 20, ONE_SECOND / 30, /* RestartRate */
133 			(1 << 9), /* BlockMask */
134 		},
135 	},
136 	{ /* AlienTransitionDesc */
137 		0, /* StartIndex */
138 		0, /* NumFrames */
139 		0, /* AnimFlags */
140 		0, 0, /* FrameRate */
141 		0, 0, /* RestartRate */
142 		0, /* BlockMask */
143 	},
144 	{ /* AlienTalkDesc */
145 		1, /* StartIndex */
146 		4, /* NumFrames */
147 		0, /* AnimFlags */
148 		ONE_SECOND / 20, 0, /* FrameRate */
149 		ONE_SECOND / 15, 0, /* RestartRate */
150 		0, /* BlockMask */
151 	},
152 	NULL, /* AlienNumberSpeech - none */
153 	/* Filler for loaded resources */
154 	NULL, NULL, NULL,
155 	NULL,
156 	NULL,
157 };
158 
159 static RESPONSE_REF shofixti_name;
160 
161 static void
GetShofixtiName(void)162 GetShofixtiName (void)
163 {
164 	if (GET_GAME_STATE (SHOFIXTI_KIA))
165 		shofixti_name = katana;
166 	else
167 		shofixti_name = tanaka;
168 }
169 
170 static void
ExitConversation(RESPONSE_REF R)171 ExitConversation (RESPONSE_REF R)
172 {
173 	setSegue (Segue_hostile);
174 
175 	if (PLAYER_SAID (R, bye0))
176 	{
177 		NPCPhrase (GOODBYE);
178 
179 		setSegue (Segue_peace);
180 	}
181 	else if (PLAYER_SAID (R, go_ahead))
182 	{
183 		NPCPhrase (ON_SECOND_THOUGHT);
184 
185 		setSegue (Segue_peace);
186 	}
187 	else if (PLAYER_SAID (R, need_you_for_duty))
188 	{
189 		NPCPhrase (OK_WILL_BE_SENTRY);
190 
191 		setSegue (Segue_peace);
192 	}
193 	else if (PLAYER_SAID (R, females)
194 			|| PLAYER_SAID (R, nubiles)
195 			|| PLAYER_SAID (R, rat_babes))
196 	{
197 		NPCPhrase (LEAPING_HAPPINESS);
198 
199 		SET_GAME_STATE (SHOFIXTI_RECRUITED, 1);
200 		SET_GAME_STATE (MAIDENS_ON_SHIP, 0);
201 		setSegue (Segue_peace);
202 
203 		AddEvent (RELATIVE_EVENT, 2, 0, 0, SHOFIXTI_RETURN_EVENT);
204 	}
205 	else if (PLAYER_SAID (R, dont_attack))
206 	{
207 		NPCPhrase (TYPICAL_PLOY);
208 
209 		SET_GAME_STATE (SHOFIXTI_STACK1, 1);
210 	}
211 	else if (PLAYER_SAID (R, hey_stop))
212 	{
213 		NPCPhrase (ONLY_STOP);
214 
215 		SET_GAME_STATE (SHOFIXTI_STACK1, 2);
216 	}
217 	else if (PLAYER_SAID (R, look_you_are))
218 	{
219 		NPCPhrase (TOO_BAD);
220 
221 		SET_GAME_STATE (SHOFIXTI_STACK1, 3);
222 	}
223 	else if (PLAYER_SAID (R, no_one_insults))
224 	{
225 		NPCPhrase (YOU_LIMP);
226 
227 		SET_GAME_STATE (SHOFIXTI_STACK2, 1);
228 	}
229 	else if (PLAYER_SAID (R, mighty_words))
230 	{
231 		NPCPhrase (HANG_YOUR);
232 
233 		SET_GAME_STATE (SHOFIXTI_STACK2, 2);
234 	}
235 	else if (PLAYER_SAID (R, dont_know))
236 	{
237 		NPCPhrase (NEVER);
238 
239 		SET_GAME_STATE (SHOFIXTI_STACK3, 1);
240 	}
241 	else if (PLAYER_SAID (R, look0))
242 	{
243 		NPCPhrase (FOR_YOU);
244 
245 		SET_GAME_STATE (SHOFIXTI_STACK3, 2);
246 	}
247 	else if (PLAYER_SAID (R, no_bloodshed))
248 	{
249 		NPCPhrase (YES_BLOODSHED);
250 
251 		SET_GAME_STATE (SHOFIXTI_STACK3, 3);
252 	}
253 	else if (PLAYER_SAID (R, dont_want_to_fight))
254 	{
255 		BYTE NumVisits;
256 
257 		NumVisits = GET_GAME_STATE (SHOFIXTI_STACK4);
258 		switch (NumVisits++)
259 		{
260 			case 0:
261 				NPCPhrase (MUST_FIGHT_YOU_URQUAN_1);
262 				break;
263 			case 1:
264 				NPCPhrase (MUST_FIGHT_YOU_URQUAN_2);
265 				break;
266 			case 2:
267 				NPCPhrase (MUST_FIGHT_YOU_URQUAN_3);
268 				break;
269 			case 3:
270 				NPCPhrase (MUST_FIGHT_YOU_URQUAN_4);
271 				--NumVisits;
272 				break;
273 		}
274 		SET_GAME_STATE (SHOFIXTI_STACK4, NumVisits);
275 	}
276 }
277 
278 static void
GiveMaidens(RESPONSE_REF R)279 GiveMaidens (RESPONSE_REF R)
280 {
281 	if (PLAYER_SAID (R, important_duty))
282 	{
283 		NPCPhrase (WHAT_DUTY);
284 
285 		Response (procreating_wildly, GiveMaidens);
286 		Response (replenishing_your_species, GiveMaidens);
287 		Response (hope_you_have, GiveMaidens);
288 	}
289 	else
290 	{
291 		NPCPhrase (SOUNDS_GREAT_BUT_HOW);
292 
293 		Response (females, ExitConversation);
294 		Response (nubiles, ExitConversation);
295 		Response (rat_babes, ExitConversation);
296 	}
297 }
298 
299 static void
ConsoleShofixti(RESPONSE_REF R)300 ConsoleShofixti (RESPONSE_REF R)
301 {
302 	if (PLAYER_SAID (R, dont_do_it))
303 	{
304 		NPCPhrase (YES_I_DO_IT);
305 		DISABLE_PHRASE (dont_do_it);
306 	}
307 	else
308 		NPCPhrase (VERY_SAD_KILL_SELF);
309 
310 	if (GET_GAME_STATE (MAIDENS_ON_SHIP))
311 	{
312 		Response (important_duty, GiveMaidens);
313 	}
314 	if (PHRASE_ENABLED (dont_do_it))
315 	{
316 		Response (dont_do_it, ConsoleShofixti);
317 	}
318 	Response (need_you_for_duty, ExitConversation);
319 	Response (go_ahead, ExitConversation);
320 }
321 
322 static void
ExplainDefeat(RESPONSE_REF R)323 ExplainDefeat (RESPONSE_REF R)
324 {
325 	if (PLAYER_SAID (R, i_am_nice))
326 		NPCPhrase (MUST_UNDERSTAND);
327 	else if (PLAYER_SAID (R, i_am_guy))
328 		NPCPhrase (NICE_BUT_WHAT_IS_DONKEY);
329 	else /* if (PLAYER_SAID (R, i_am_captain0)) */
330 		NPCPhrase (SO_SORRY);
331 	NPCPhrase (IS_DEFEAT_TRUE);
332 
333 	Response (yes_and_no, ConsoleShofixti);
334 	Response (clobbered, ConsoleShofixti);
335 	Response (butt_blasted, ConsoleShofixti);
336 }
337 
338 static void
RealizeMistake(RESPONSE_REF R)339 RealizeMistake (RESPONSE_REF R)
340 {
341 	(void) R;  // ignored
342 	NPCPhrase (DGRUNTI);
343 	SET_GAME_STATE (SHOFIXTI_STACK1, 0);
344 	SET_GAME_STATE (SHOFIXTI_STACK3, 0);
345 	SET_GAME_STATE (SHOFIXTI_STACK2, 3);
346 
347 	{
348 		UNICODE buf[ALLIANCE_NAME_BUFSIZE];
349 
350 		GetAllianceName (buf, name_1);
351 		construct_response (
352 				shared_phrase_buf,
353 				i_am_captain0,
354 				GLOBAL_SIS (CommanderName),
355 				i_am_captain1,
356 				buf,
357 				i_am_captain2,
358 				GLOBAL_SIS (ShipName),
359 				i_am_captain3,
360 				(UNICODE*)NULL);
361 	}
362 	DoResponsePhrase (i_am_captain0, ExplainDefeat, shared_phrase_buf);
363 	Response (i_am_nice, ExplainDefeat);
364 	Response (i_am_guy, ExplainDefeat);
365 }
366 
367 static void
Hostile(RESPONSE_REF R)368 Hostile (RESPONSE_REF R)
369 {
370 	(void) R;  // ignored
371 	switch (GET_GAME_STATE (SHOFIXTI_STACK1))
372 	{
373 		case 0:
374 			Response (dont_attack, ExitConversation);
375 			break;
376 		case 1:
377 			Response (hey_stop, ExitConversation);
378 			break;
379 		case 2:
380 			Response (look_you_are, ExitConversation);
381 			break;
382 	}
383 	switch (GET_GAME_STATE (SHOFIXTI_STACK2))
384 	{
385 		case 0:
386 			Response (no_one_insults, ExitConversation);
387 			break;
388 		case 1:
389 			Response (mighty_words, ExitConversation);
390 			break;
391 		case 2:
392 			Response (donkey_breath, RealizeMistake);
393 			break;
394 	}
395 	switch (GET_GAME_STATE (SHOFIXTI_STACK3))
396 	{
397 		case 0:
398 			Response (dont_know, ExitConversation);
399 			break;
400 		case 1:
401 		{
402 			construct_response (
403 					shared_phrase_buf,
404 					look0,
405 					"",
406 					shofixti_name,
407 					"",
408 					look1,
409 					(UNICODE*)NULL);
410 			DoResponsePhrase (look0, ExitConversation, shared_phrase_buf);
411 			break;
412 		}
413 		case 2:
414 			Response (look_you_are, ExitConversation);
415 			break;
416 	}
417 	Response (dont_want_to_fight, ExitConversation);
418 }
419 
420 static void
Friendly(RESPONSE_REF R)421 Friendly (RESPONSE_REF R)
422 {
423 	BYTE i, LastStack;
424 	struct
425 	{
426 		RESPONSE_REF pStr;
427 		UNICODE *c_buf;
428 	} Resp[3];
429 	static UNICODE buf0[80], buf1[80];
430 
431 	LastStack = 0;
432 	memset (Resp, 0, sizeof (Resp));
433 	if (PLAYER_SAID (R, report0))
434 	{
435 		NPCPhrase (NOTHING_NEW);
436 
437 		DISABLE_PHRASE (report0);
438 	}
439 	else if (PLAYER_SAID (R, why_here0))
440 	{
441 		NPCPhrase (I_GUARD);
442 
443 		LastStack = 1;
444 		SET_GAME_STATE (SHOFIXTI_STACK1, 1);
445 	}
446 	else if (PLAYER_SAID (R, what_happened))
447 	{
448 		NPCPhrase (MET_VUX);
449 
450 		LastStack = 1;
451 		SET_GAME_STATE (SHOFIXTI_STACK1, 2);
452 	}
453 	else if (PLAYER_SAID (R, glory_device))
454 	{
455 		NPCPhrase (SWITCH_BROKE);
456 
457 		SET_GAME_STATE (SHOFIXTI_STACK1, 3);
458 	}
459 	else if (PLAYER_SAID (R, where_world))
460 	{
461 		NPCPhrase (BLEW_IT_UP);
462 
463 		LastStack = 2;
464 		SET_GAME_STATE (SHOFIXTI_STACK3, 1);
465 	}
466 	else if (PLAYER_SAID (R, how_survive))
467 	{
468 		NPCPhrase (NOT_HERE);
469 
470 		SET_GAME_STATE (SHOFIXTI_STACK3, 2);
471 	}
472 
473 	if (PHRASE_ENABLED (report0))
474 	{
475 		construct_response (
476 				buf0,
477 				report0,
478 				"",
479 				shofixti_name,
480 				"",
481 				report1,
482 				(UNICODE*)NULL);
483 		Resp[0].pStr = report0;
484 		Resp[0].c_buf = buf0;
485 	}
486 
487 	switch (GET_GAME_STATE (SHOFIXTI_STACK1))
488 	{
489 		case 0:
490 			construct_response (
491 					buf1,
492 					why_here0,
493 					"",
494 					shofixti_name,
495 					"",
496 					why_here1,
497 					(UNICODE*)NULL);
498 			Resp[1].pStr = why_here0;
499 			Resp[1].c_buf = buf1;
500 			break;
501 		case 1:
502 			Resp[1].pStr = what_happened;
503 			break;
504 		case 2:
505 			Resp[1].pStr = glory_device;
506 			break;
507 	}
508 
509 	switch (GET_GAME_STATE (SHOFIXTI_STACK3))
510 	{
511 		case 0:
512 				Resp[2].pStr = where_world;
513 			break;
514 		case 1:
515 				Resp[2].pStr = how_survive;
516 			break;
517 	}
518 
519 	if (Resp[LastStack].pStr)
520 		DoResponsePhrase (Resp[LastStack].pStr, Friendly, Resp[LastStack].c_buf);
521 	for (i = 0; i < 3; ++i)
522 	{
523 		if (i != LastStack && Resp[i].pStr)
524 			DoResponsePhrase (Resp[i].pStr, Friendly, Resp[i].c_buf);
525 	}
526 	if (GET_GAME_STATE (MAIDENS_ON_SHIP))
527 	{
528 		Response (important_duty, GiveMaidens);
529 	}
530 
531 	construct_response (
532 			shared_phrase_buf,
533 			bye0,
534 			"",
535 			shofixti_name,
536 			"",
537 			bye1,
538 			(UNICODE*)NULL);
539 	DoResponsePhrase (bye0, ExitConversation, shared_phrase_buf);
540 }
541 
542 static void
Intro(void)543 Intro (void)
544 {
545 	if (LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE)
546 	{
547 		NPCPhrase (OUT_TAKES);
548 
549 		setSegue (Segue_peace);
550 		return;
551 	}
552 
553 	GetShofixtiName ();
554 
555 	if (GET_GAME_STATE (SHOFIXTI_STACK2) > 2)
556 	{
557 		NPCPhrase (FRIENDLY_HELLO);
558 
559 		Friendly ((RESPONSE_REF)0);
560 	}
561 	else
562 	{
563 		BYTE NumVisits;
564 
565 		NumVisits = GET_GAME_STATE (SHOFIXTI_VISITS);
566 		if (GET_GAME_STATE (SHOFIXTI_KIA))
567 		{
568 			switch (NumVisits++)
569 			{
570 				case 0:
571 					NPCPhrase (HOSTILE_KATANA_1);
572 					break;
573 				case 1:
574 					NPCPhrase (HOSTILE_KATANA_2);
575 					break;
576 				case 2:
577 					NPCPhrase (HOSTILE_KATANA_3);
578 					break;
579 				case 3:
580 					NPCPhrase (HOSTILE_KATANA_4);
581 					--NumVisits;
582 					break;
583 			}
584 		}
585 		else
586 		{
587 			switch (NumVisits++)
588 			{
589 				case 0:
590 					NPCPhrase (HOSTILE_TANAKA_1);
591 					break;
592 				case 1:
593 					NPCPhrase (HOSTILE_TANAKA_2);
594 					break;
595 				case 2:
596 					NPCPhrase (HOSTILE_TANAKA_3);
597 					break;
598 				case 3:
599 					NPCPhrase (HOSTILE_TANAKA_4);
600 					break;
601 				case 4:
602 					NPCPhrase (HOSTILE_TANAKA_5);
603 					break;
604 				case 5:
605 					NPCPhrase (HOSTILE_TANAKA_6);
606 					break;
607 				case 6:
608 					NPCPhrase (HOSTILE_TANAKA_7);
609 					break;
610 				case 7:
611 					NPCPhrase (HOSTILE_TANAKA_8);
612 					--NumVisits;
613 					break;
614 			}
615 		}
616 		SET_GAME_STATE (SHOFIXTI_VISITS, NumVisits);
617 
618 		Hostile ((RESPONSE_REF)0);
619 	}
620 }
621 
622 static COUNT
uninit_shofixti(void)623 uninit_shofixti (void)
624 {
625 	return(0);
626 }
627 
628 static void
post_shofixti_enc(void)629 post_shofixti_enc (void)
630 {
631 	// nothing defined so far
632 }
633 
634 LOCDATA*
init_shofixti_comm(void)635 init_shofixti_comm (void)
636 {
637 	LOCDATA *retval;
638 
639 	shofixti_desc.init_encounter_func = Intro;
640 	shofixti_desc.post_encounter_func = post_shofixti_enc;
641 	shofixti_desc.uninit_encounter_func = uninit_shofixti;
642 
643 	shofixti_desc.AlienTextBaseline.x = TEXT_X_OFFS + (SIS_TEXT_WIDTH >> 1);
644 	shofixti_desc.AlienTextBaseline.y = 0;
645 	shofixti_desc.AlienTextWidth = SIS_TEXT_WIDTH;
646 
647 	setSegue (Segue_peace);
648 
649 	retval = &shofixti_desc;
650 
651 	return (retval);
652 }
653