1 /*
2  * Seven Kingdoms: Ancient Adversaries
3  *
4  * Copyright 1997,1998 Enlight Software Ltd.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 //Filename    : OTALKRES.CPP
22 //Description : Object Talk
23 
24 #include <OMOUSE.h>
25 #include <OSYS.h>
26 #include <OVGA.h>
27 #include <OINFO.h>
28 #include <OFONT.h>
29 #include <OTECHRES.h>
30 #include <OGAMESET.h>
31 #include <ONEWS.h>
32 #include <ONATION.h>
33 #include <OTALKRES.h>
34 #include <OREMOTE.h>
35 // #### begin Gilbert 9/10 ######//
36 #include <OSE.h>
37 // #### end Gilbert 9/10 ######//
38 #include "gettext.h"
39 
40 //---------- the subtitle area ----------//
41 
42 enum { TALK_X1 = ZOOM_X1+16,
43 		 TALK_Y1 = ZOOM_Y1+252,
44 		 TALK_X2 = ZOOM_X2-16,
45 		 TALK_Y2 = ZOOM_Y2-86,
46 	  };
47 
48 enum { TALK_LINE_HEIGHT = 18 };
49 
50 //------- define constant --------//
51 
52 #define MESSAGE_SENT_STR		_("The message has been sent.")
53 
54 //------- define static vars -------//
55 
56 static String nation_name_str_array[MAX_NATION];
57 
58 // ----------- Define static function ----------//
59 
60 static char* select_nation_color(char nation_color);
61 
62 //---------- Begin of function TalkRes::TalkRes -----------//
63 //
TalkRes()64 TalkRes::TalkRes() : talk_msg_array( sizeof(TalkMsg), 100 )
65 {
66 }
67 //---------- End of function TalkRes::TalkRes -----------//
68 
69 
70 //---------- Begin of function TalkRes::init -----------//
71 //
init()72 void TalkRes::init()
73 {
74 	memset( this, 0, sizeof(TalkRes) - sizeof(talk_msg_array) );
75 
76 	talk_msg_array.zap();
77 }
78 //---------- End of function TalkRes::init -----------//
79 
80 
81 //---------- Begin of function TalkRes::deinit -----------//
82 //
deinit()83 void TalkRes::deinit()
84 {
85 }
86 //---------- End of function TalkRes::deinit -----------//
87 
88 
89 //------- Begin of function TalkRes::init_conversion --------//
90 //
91 // <int> toNationRecno - recno of the nation which the player
92 //								 is going to talk to.
93 //
init_conversion(int toNationRecno)94 void TalkRes::init_conversion(int toNationRecno)
95 {
96 	memset( &cur_talk_msg, 0, sizeof(TalkMsg) );
97 
98 	cur_talk_msg.from_nation_recno = (char) nation_array.player_recno;
99 	cur_talk_msg.to_nation_recno = toNationRecno;
100 
101 	reply_talk_msg_recno = 0;
102 
103 	set_talk_choices();
104 }
105 //-------- End of function TalkRes::init_conversion ---------//
106 
107 
108 //---- Begin of function TalkRes::set_talk_choices ------//
109 //
110 // Set the choices of the next talk.
111 //
112 // return : <int> 1 - choices are set
113 //                0 - if there is no additional talk segment for this talk
114 //
set_talk_choices()115 int TalkRes::set_talk_choices()
116 {
117 	//------------------------------------//
118 
119 	Nation* playerNation = ~nation_array;
120 
121 	talk_choice_count = 0;
122 	choice_question = NULL;
123 	choice_question_second_line = NULL;
124 	cur_choice_id = 0;
125 
126 	//------------------------------------//
127 
128 	int rc=0;
129 
130 	memset( available_talk_id_array, 0, sizeof(available_talk_id_array) );
131 
132 	switch( cur_talk_msg.talk_id )
133 	{
134 		//--- add the main option choices ---//
135 
136 		case 0:
137 			add_main_choices();
138 			return 1;
139 
140 		case TALK_PROPOSE_TRADE_TREATY:
141 		case TALK_PROPOSE_FRIENDLY_TREATY:
142 		case TALK_PROPOSE_ALLIANCE_TREATY:
143 		case TALK_END_TRADE_TREATY:
144 		case TALK_END_FRIENDLY_TREATY:
145 		case TALK_END_ALLIANCE_TREATY:
146 		case TALK_REQUEST_CEASE_WAR:
147 		case TALK_DECLARE_WAR:
148 		case TALK_REQUEST_MILITARY_AID:
149 			return 0;
150 
151 		case TALK_REQUEST_TRADE_EMBARGO:
152 			rc = add_trade_embargo_choices();
153 			break;
154 
155 		case TALK_REQUEST_DECLARE_WAR:
156 			rc = add_declare_war_choices();
157 			break;
158 
159 		case TALK_REQUEST_BUY_FOOD:
160 			rc = add_buy_food_choices();
161 			break;
162 
163 		case TALK_GIVE_TRIBUTE:
164 		case TALK_DEMAND_TRIBUTE:
165 			rc = add_tribute_choices();
166 			if( rc )
167 				choice_question = _("How much tribute?");	// add the choice question here because we use the same function for both tribute and aid
168 			break;
169 
170 		case TALK_GIVE_AID:
171 		case TALK_DEMAND_AID:
172 			rc = add_tribute_choices();
173 			if( rc )
174 				choice_question = _("How much aid?");
175 			break;
176 
177 		case TALK_GIVE_TECH:
178 		case TALK_DEMAND_TECH:
179 			rc = add_give_tech_choices();
180 			break;
181 
182 		case TALK_REQUEST_SURRENDER:
183 			rc = add_request_surrender_choices();
184 			break;
185 
186 		case TALK_SURRENDER:
187 			rc = add_surrender_choices();
188 			break;
189 
190 		default:
191 			err_here();
192 	}
193 
194 	if( rc )
195 		add_talk_choice( _("Cancel."), 0 );
196 
197 	return rc;
198 }
199 //----- End of function TalkRes::set_talk_choices -------//
200 
201 
202 //---- Begin of function TalkRes::add_main_choices ------//
203 //
add_main_choices()204 void TalkRes::add_main_choices()
205 {
206 	static const char* talkMsgArray[] =
207 	{
208 		N_("Propose a trade treaty."),
209 		N_("Propose a friendly treaty."),
210 		N_("Propose an alliance treaty."),
211 		N_("Terminate our trade treaty."),
212 		N_("Terminate our friendly treaty."),
213 		N_("Terminate our alliance treaty."),
214 		N_("Request immediate military aid."),
215 		N_("Request a trade embargo."),
216 		N_("Request a cease-fire."),
217 		N_("Request a declaration of war against a foe."),
218 		N_("Request to purchase food."),
219 		N_("Declare war."),
220 		N_("Offer to pay tribute."),
221 		N_("Demand tribute."),
222 		N_("Offer aid."),
223 		N_("Request aid."),
224 		N_("Offer to transfer technology."),
225 		N_("Request technology."),
226 		N_("Offer to purchase throne and unite kingdoms."),
227 		N_("Surrender."),
228 	};
229 
230 	//-----------------------------------------//
231 
232 	int rc;
233 	int relationStatus = (~nation_array)->get_relation_status(cur_talk_msg.to_nation_recno);
234 
235 	for( int i=1 ; i<=MAX_TALK_TYPE ; i++ )
236 	{
237 		if( !can_send_msg(cur_talk_msg.to_nation_recno, nation_array.player_recno, i) )
238 			continue;
239 
240 		rc=0;
241 
242 		if( !rc )
243 			add_talk_choice( _(talkMsgArray[i-1]), i );
244 
245 		available_talk_id_array[i-1] = 1;
246 	}
247 }
248 //----- End of function TalkRes::add_main_choices -------//
249 
250 
251 //---- Begin of function TalkRes::add_trade_embargo_choices ------//
252 //
add_trade_embargo_choices()253 int TalkRes::add_trade_embargo_choices()
254 {
255 	if( cur_talk_msg.talk_para1 )
256 		return 0;
257 
258 	choice_question = _("Request an embargo on trade with which kingdom?");
259 
260 	Nation* fromNation = nation_array[cur_talk_msg.from_nation_recno];
261 	Nation* toNation   = nation_array[cur_talk_msg.to_nation_recno];
262 
263 	for( int i=1 ; i<=nation_array.size() ; i++ )
264 	{
265 		if( nation_array.is_deleted(i) )
266 			continue;
267 
268 		if( i==cur_talk_msg.from_nation_recno ||
269 			 i==cur_talk_msg.to_nation_recno )
270 		{
271 			continue;
272 		}
273 
274 		if( fromNation->get_relation(i)->trade_treaty==0 &&
275 			 toNation->get_relation(i)->trade_treaty==1 )
276 		{
277 			//------ add color bar -------//
278 
279 			nation_name_str_array[i-1] = select_nation_color(nation_array[i]->color_scheme_id);
280 
281 			//------ add natino name ------//
282 
283 			nation_name_str_array[i-1] += nation_array[i]->nation_name();
284 
285 			//---- add talk choice string ------//
286 
287 			add_talk_choice( nation_name_str_array[i-1], i );
288 		}
289 	}
290 
291 	return 1;
292 }
293 //----- End of function TalkRes::add_trade_embargo_choices -------//
294 
295 
296 //---- Begin of function TalkRes::add_declare_war_choices ------//
297 //
add_declare_war_choices()298 int TalkRes::add_declare_war_choices()
299 {
300 	if( cur_talk_msg.talk_para1 )
301 		return 0;
302 
303 	choice_question = _("Declare war on which kingdom?");
304 
305 	Nation* fromNation = nation_array[cur_talk_msg.from_nation_recno];
306 	Nation* toNation   = nation_array[cur_talk_msg.to_nation_recno];
307 
308 	for( int i=1 ; i<=nation_array.size() ; i++ )
309 	{
310 		if( nation_array.is_deleted(i) )
311 			continue;
312 
313 		//--- can only ask another nation to declare war with a nation that is currently at war with our nation ---//
314 
315 		if( fromNation->get_relation_status(i) == NATION_HOSTILE &&
316 			 toNation->get_relation_status(i) != NATION_HOSTILE )
317 		{
318 			//------ add color bar -------//
319 
320 			nation_name_str_array[i-1] = select_nation_color(nation_array[i]->color_scheme_id);
321 
322 			//------ add natino name ------//
323 
324 			nation_name_str_array[i-1] += nation_array[i]->nation_name();
325 
326 			//---- add talk choice string ------//
327 
328 			add_talk_choice( nation_name_str_array[i-1], i );
329 		}
330 	}
331 
332 	return 1;
333 }
334 //----- End of function TalkRes::add_declare_war_choices -------//
335 
336 
337 //---- Begin of function TalkRes::add_buy_food_choices ------//
338 //
add_buy_food_choices()339 int TalkRes::add_buy_food_choices()
340 {
341 	#define MIN_FOOD_PURCHASE_PRICE	5
342 
343 	if( !cur_talk_msg.talk_para1 )
344 	{
345 		choice_question = _("How much food do you want to purchase?");
346 
347 		static const char* qtyStrArray[] = { "500.", "1000.", "2000.", "4000." };
348 		static short qtyArray[] = { 500, 1000, 2000, 4000 };
349 
350 		for( int i=0 ; i<4 ; i++ )
351 		{
352 			if( (~nation_array)->cash >= qtyArray[i] * MIN_FOOD_PURCHASE_PRICE / 10 )
353 				add_talk_choice( qtyStrArray[i], qtyArray[i] );
354 		}
355 
356 		return 1;
357 	}
358 	else if( !cur_talk_msg.talk_para2 )
359 	{
360 		choice_question = _("How much do you offer for 10 units of food?");
361 
362 		static const char* priceStrArray[] = { "$5.", "$10.", "$15.", "$20." };
363 		static short priceArray[] = { 5, 10, 15, 20 };
364 
365 		for( int i=0 ; i<4 ; i++ )
366 		{
367 			if( i==0 || (~nation_array)->cash >= cur_talk_msg.talk_para1 * priceArray[i] / 10 )		// i==0 to at least add one option
368 				add_talk_choice( priceStrArray[i], priceArray[i] );
369 		}
370 
371 		return 1;
372 	}
373 	else
374 		return 0;
375 }
376 //----- End of function TalkRes::add_buy_food_choices -------//
377 
378 
379 //---- Begin of function TalkRes::add_tribute_choices ------//
380 //
add_tribute_choices()381 int TalkRes::add_tribute_choices()
382 {
383 	if( cur_talk_msg.talk_para1 )
384 		return 0;
385 
386 	static const char* tributeStrArray[] = { "$500.", "$1000.", "$2000.", "$3000.", "$4000." };
387 	static short tributeAmtArray[] = { 500, 1000, 2000, 3000, 4000 };
388 
389 	for( int i=0 ; i<5 ; i++ )
390 	{
391 		if( cur_talk_msg.talk_id == TALK_DEMAND_TRIBUTE ||		// when demand tribute, the amount can be sent to any
392 			 cur_talk_msg.talk_id == TALK_DEMAND_AID ||
393 			 (~nation_array)->cash >= tributeAmtArray[i] )
394 		{
395 			add_talk_choice( tributeStrArray[i], tributeAmtArray[i] );
396 		}
397 	}
398 
399 	return 1;
400 }
401 //----- End of function TalkRes::add_tribute_choices -------//
402 
403 
404 //---- Begin of function TalkRes::add_give_tech_choices ------//
405 //
add_give_tech_choices()406 int TalkRes::add_give_tech_choices()
407 {
408 	int i, techNationRecno;
409 
410 	if( cur_talk_msg.talk_id == TALK_GIVE_TECH )
411 		techNationRecno = cur_talk_msg.from_nation_recno;
412 	else	// demand tech
413 		techNationRecno = cur_talk_msg.to_nation_recno;
414 
415 	if( !cur_talk_msg.talk_para1 )
416 	{
417 		choice_question = _("Which technology?");
418 
419 		for( i=1 ; i<=tech_res.tech_count ; i++ )
420 		{
421 			if( tech_res[i]->get_nation_tech_level(techNationRecno) > 0 )
422 			{
423 				add_talk_choice( tech_res[i]->tech_des(), i );
424 			}
425 		}
426 
427 		return 1;
428 	}
429 	else if( !cur_talk_msg.talk_para2 && cur_talk_msg.talk_id == TALK_GIVE_TECH )
430 	{
431 		TechInfo* techInfo = tech_res[cur_talk_msg.talk_para1];
432 
433 		if( techInfo->max_tech_level==1 )		// this tech only has one level
434 			return 0;
435 
436 		choice_question = _("Which version?");
437 
438 		int nationLevel = techInfo->get_nation_tech_level(techNationRecno);
439 
440 		err_when( nationLevel<1 || nationLevel>3 );
441 
442 		static const char* verStrArray[] = { "Mark I", "Mark II", "Mark III" };
443 
444 		for( i=1 ; i<=MIN(3, nationLevel) ; i++ )
445 			add_talk_choice( verStrArray[i-1], i );
446 
447 		return 1;
448 	}
449 	else
450 		return 0;
451 }
452 //----- End of function TalkRes::add_give_tech_choices -------//
453 
454 
455 //---- Begin of function TalkRes::add_request_surrender_choices ------//
456 //
add_request_surrender_choices()457 int TalkRes::add_request_surrender_choices()
458 {
459 	if( cur_talk_msg.talk_para1 )
460 		return 0;
461 
462 	choice_question = _("How much do you offer?");
463 
464 	static const char* strArray[] = { "$5000.", "$7500.", "$10000.",
465 		"$15000.", "$20000.", "$30000.", "$40000.", "$50000." };
466 
467 	static int amtArray[] = { 5000, 7500, 10000, 15000, 20000, 30000, 40000, 50000 };
468 
469 	for( int i=0 ; i<8 ; i++ )
470 	{
471 		if( (~nation_array)->cash >= amtArray[i] )
472 		{
473 			add_talk_choice( strArray[i], amtArray[i]/10 );		// divided by 10 to cope with the limit of <short>
474 		}
475 	}
476 
477 	return 1;
478 }
479 //----- End of function TalkRes::add_request_surrender_choices -------//
480 
481 
482 //---- Begin of function TalkRes::add_surrender_choices ------//
483 //
add_surrender_choices()484 int TalkRes::add_surrender_choices()
485 {
486 	if( cur_talk_msg.talk_para1 )
487 		return 0;
488 
489 	static String str;
490 
491 	snprintf( str, MAX_STR_LEN+1, _("Do you really want to Surrender to %s's Kingdom?"), nation_array[cur_talk_msg.to_nation_recno]->king_name(1) );
492 	choice_question = str;
493 
494 	add_talk_choice( _("Confirm."), 1 );
495 
496 	return 1;
497 }
498 //----- End of function TalkRes::add_surrender_choices -------//
499 
500 
501 //------- Begin of function TalkRes::can_send_any_msg --------//
502 //
can_send_any_msg(int toNationRecno,int fromNationRecno)503 int TalkRes::can_send_any_msg(int toNationRecno, int fromNationRecno)
504 {
505 	return wait_msg_count(toNationRecno, fromNationRecno) < MAX_WAIT_MSG_PER_NATION;
506 }
507 //-------- End of function TalkRes::can_send_any_msg ---------//
508 
509 
510 //------- Begin of function TalkRes::can_send_msg --------//
511 //
512 // return whether one specific nation can send a specific message
513 // to another specific nation.
514 //
can_send_msg(int toNationRecno,int fromNationRecno,int talkId)515 int TalkRes::can_send_msg(int toNationRecno, int fromNationRecno, int talkId)
516 {
517 	Nation* fromNation = nation_array[fromNationRecno];
518 	Nation* toNation 	 = nation_array[toNationRecno];
519 
520 	NationRelation *nationRelation = fromNation->get_relation(toNationRecno);
521 	int relationStatus = nationRelation->status;
522 
523 	switch( talkId )
524 	{
525 		case TALK_PROPOSE_TRADE_TREATY:
526 			return relationStatus !=NATION_ALLIANCE && 		// allied nations are oblied to trade with each other
527 					 relationStatus !=NATION_HOSTILE &&
528 					 !toNation->get_relation(fromNationRecno)->trade_treaty;
529 
530 		case TALK_PROPOSE_FRIENDLY_TREATY:
531 			return relationStatus==NATION_TENSE ||
532 					 relationStatus==NATION_NEUTRAL;
533 
534 		case TALK_PROPOSE_ALLIANCE_TREATY:
535 			return relationStatus==NATION_FRIENDLY ||
536 					 relationStatus==NATION_NEUTRAL;
537 
538 		case TALK_END_TRADE_TREATY:
539 			return relationStatus !=NATION_ALLIANCE && 		// allied nations are oblied to trade with each other
540 					 toNation->get_relation(fromNationRecno)->trade_treaty;
541 
542 		case TALK_END_FRIENDLY_TREATY:
543 			return relationStatus==NATION_FRIENDLY;
544 
545 		case TALK_END_ALLIANCE_TREATY:
546 			return relationStatus==NATION_ALLIANCE;
547 
548 		case TALK_REQUEST_MILITARY_AID:
549 			return fromNation->is_at_war() &&
550 					 (relationStatus==NATION_FRIENDLY ||
551 					  relationStatus==NATION_ALLIANCE);
552 
553 		case TALK_REQUEST_TRADE_EMBARGO:
554 			return relationStatus==NATION_FRIENDLY ||
555 					 relationStatus==NATION_ALLIANCE;
556 
557 		case TALK_REQUEST_CEASE_WAR:
558 			return relationStatus==NATION_HOSTILE;
559 
560 		case TALK_REQUEST_DECLARE_WAR:		// can only request an allied nation to declare war with another nation
561 		{
562 			if( relationStatus != NATION_ALLIANCE )
563 				return 0;
564 
565 			//--- see if this nation has an enemy right now ---//
566 
567 			for( int i=nation_array.size() ; i>0 ; i-- )
568 			{
569 				if( nation_array.is_deleted(i) )
570 					continue;
571 
572 				if( fromNation->get_relation(i)->status == NATION_HOSTILE )
573 					return 1;
574 			}
575 
576 			return 0;
577 		}
578 
579 		case TALK_REQUEST_BUY_FOOD:
580 			return relationStatus != NATION_HOSTILE;
581 
582 		case TALK_DECLARE_WAR:
583 			return relationStatus != NATION_ALLIANCE &&
584 					 relationStatus != NATION_FRIENDLY &&
585 					 relationStatus != NATION_HOSTILE;
586 
587 		case TALK_GIVE_TRIBUTE:
588 		case TALK_DEMAND_TRIBUTE:
589 			return relationStatus <= NATION_NEUTRAL;
590 
591 		case TALK_GIVE_AID:
592 		case TALK_DEMAND_AID:
593 			return relationStatus >= NATION_FRIENDLY;
594 
595 		case TALK_GIVE_TECH:
596 			return fromNation->total_tech_level() > 0;
597 
598 		case TALK_DEMAND_TECH:
599 			return toNation->total_tech_level() > 0;
600 
601 		case TALK_REQUEST_SURRENDER:
602 			return 1;
603 
604 		case TALK_SURRENDER:
605 			return 1;
606 	}
607 
608 	return 0;
609 }
610 //-------- End of function TalkRes::can_send_msg ---------//
611 
612 
613 //------- Begin of function TalkRes::add_talk_choice --------//
614 //
add_talk_choice(const char * talkStr,int talkPara)615 void TalkRes::add_talk_choice(const char* talkStr, int talkPara)
616 {
617 	err_when( talk_choice_count >= MAX_TALK_CHOICE );
618 
619 	talk_choice_count++;
620 
621 	talk_choice_array[talk_choice_count-1].str  = talkStr;
622 	talk_choice_array[talk_choice_count-1].para = talkPara;
623 }
624 //-------- End of function TalkRes::add_talk_choice ---------//
625 
626 
627 //------- Begin of function TalkRes::ai_send_talk_msg --------//
628 //
629 // <int> toNationRecno	 - the nation which this message is being sent to
630 // <int> fromNationRecno - the nation which this message is from
631 // <int> talkId			 - id. of the talk
632 // [int] talkPara1		 - talk para 1
633 // [int] talkPara2		 - talk para 2
634 // [int] forceSend		 - if 1, then should_diplomacy_retry() won't
635 //									be checked. (default: 0)
636 //
ai_send_talk_msg(int toNationRecno,int fromNationRecno,int talkId,int talkPara1,int talkPara2,int forceSend)637 int TalkRes::ai_send_talk_msg(int toNationRecno, int fromNationRecno, int talkId, int talkPara1, int talkPara2, int forceSend)
638 {
639 	Nation* fromNation = nation_array[fromNationRecno];
640 
641 	if( !fromNation->is_ai() )
642 		return 0;
643 
644 	//--- first check again if the nation should send the message now ---//
645 
646 	if( !forceSend )
647 	{
648 		if( !fromNation->should_diplomacy_retry(talkId, toNationRecno) )
649 			return 0;
650 	}
651 
652 	//-------- avoid send opposite message too soon ----//
653 
654 	int oppTalkId=0;
655 
656 	switch( talkId )
657 	{
658 		case TALK_PROPOSE_ALLIANCE_TREATY:
659 			oppTalkId = TALK_END_FRIENDLY_TREATY;
660 			break;
661 
662 		case TALK_GIVE_TRIBUTE:
663 			oppTalkId = TALK_DEMAND_TRIBUTE;
664 			break;
665 
666 		case TALK_DEMAND_TRIBUTE:
667 			oppTalkId = TALK_GIVE_TRIBUTE;
668 			break;
669 
670 		case TALK_GIVE_AID:
671 			oppTalkId = TALK_DEMAND_AID;
672 			break;
673 
674 		case TALK_DEMAND_AID:
675 			oppTalkId = TALK_GIVE_AID;
676 			break;
677 
678 		case TALK_GIVE_TECH:
679 			oppTalkId = TALK_DEMAND_TECH;
680 			break;
681 
682 		case TALK_DEMAND_TECH:
683 			oppTalkId = TALK_GIVE_TECH;
684 			break;
685 	}
686 
687 	if( oppTalkId )
688 	{
689 		fromNation->get_relation(toNationRecno)->
690 			last_talk_reject_date_array[oppTalkId-1] = info.game_date;
691 	}
692 
693 	//------------------------------------------//
694 
695 	TalkMsg talkMsg;
696 
697 	memset(&talkMsg, 0, sizeof(TalkMsg));
698 
699 	talkMsg.to_nation_recno   = toNationRecno;
700 	talkMsg.from_nation_recno = fromNationRecno;
701 	talkMsg.talk_id  			  = talkId;
702 	talkMsg.talk_para1		  = talkPara1;
703 	talkMsg.talk_para2		  = talkPara2;
704 
705 	err_when( !nation_array[fromNationRecno]->is_ai() );
706 
707 	send_talk_msg( &talkMsg, COMMAND_AI );
708 
709 	return 1;
710 }
711 //-------- End of function TalkRes::ai_send_talk_msg ---------//
712 
713 
714 //------- Begin of function TalkRes::send_talk_msg --------//
715 //
716 // Now records in talk_msg_array cannot be deleted as
717 // news_array.diplomacy() use recno to refer to talk_msg_array.
718 //
send_talk_msg(TalkMsg * talkMsgPtr,char remoteAction)719 void TalkRes::send_talk_msg(TalkMsg* talkMsgPtr, char remoteAction)
720 {
721 	//-------- send multiplayer -----------//
722 
723 	if( !remoteAction && remote.is_enable() )
724 	{
725 		// packet strcture : <TalkMsg>
726 		char* dataPtr = remote.new_send_queue_msg(MSG_SEND_TALK_MSG, sizeof(TalkMsg) );
727 
728 		memcpy( dataPtr, talkMsgPtr, sizeof(TalkMsg) );
729 		return;
730 	}
731 
732 	//------ the TalkMsg::reply_type ------//
733 
734 	if( talkMsgPtr->is_reply_needed() )
735 		talkMsgPtr->reply_type = REPLY_WAITING;
736 	else
737 		talkMsgPtr->reply_type = REPLY_NOT_NEEDED;
738 
739 	//-- If this is an AI message check if this message has already been sent --//
740 
741 	if( nation_array[talkMsgPtr->from_nation_recno]->nation_type == NATION_AI )
742 	{
743 		if( talkMsgPtr->reply_type == REPLY_WAITING )	// for messages that do not need a reply, duplication in the message log is allowed.
744 		{
745 			if( is_talk_msg_exist(talkMsgPtr, 0) )		// 0-don't check talk_para1 & talk_para2
746 				return;
747 		}
748 	}
749 
750 	//--- in a multiplayer game, when the msg comes back from the network, can_send_msg might be different, so we have to check it again ---//
751 
752 	if( !can_send_msg( talkMsgPtr->to_nation_recno, talkMsgPtr->from_nation_recno, talkMsgPtr->talk_id ) )
753 		return;
754 
755 	//-------- send the message now ---------//
756 
757 	send_talk_msg_now(talkMsgPtr);
758 
759 	//---- if it's a notification message ----//
760 
761 	if( talkMsgPtr->reply_type == REPLY_NOT_NEEDED )
762 		talkMsgPtr->process_accepted_reply();
763 }
764 //-------- End of function TalkRes::send_talk_msg ---------//
765 
766 
767 //------- Begin of function TalkRes::send_talk_msg_now --------//
768 //
send_talk_msg_now(TalkMsg * talkMsgPtr)769 void TalkRes::send_talk_msg_now(TalkMsg* talkMsgPtr)
770 {
771 	//--------- add the message ------------//
772 
773 	Nation* toNation = nation_array[talkMsgPtr->to_nation_recno];
774 
775 	talkMsgPtr->date = info.game_date;
776 	talkMsgPtr->relation_status = toNation->get_relation_status(talkMsgPtr->from_nation_recno);
777 
778 	talk_msg_array.linkin( talkMsgPtr );
779 
780 	err_when( nation_array.is_deleted(talkMsgPtr->from_nation_recno) );
781 	err_when( nation_array.is_deleted(talkMsgPtr->to_nation_recno) );
782 
783 	//--------------------------------------//
784 
785 	switch(toNation->nation_type)
786 	{
787 		case NATION_OWN:		// can be from both AI or a remote player
788 			news_array.diplomacy( talk_msg_array.recno() );
789 			// ###### begin Gilbert 9/10 ########//
790 			// sound effect
791 			if( toNation->get_relation(talkMsgPtr->from_nation_recno)->has_contact )
792 				se_ctrl.immediate_sound(talkMsgPtr->talk_id==TALK_DECLARE_WAR ? (char*)"DECL_WAR":(char*)"GONG");
793 			// ###### end Gilbert 9/10 ########//
794 			break;
795 
796 		case NATION_AI:
797 			if( talkMsgPtr->reply_type == REPLY_WAITING )
798 			{
799 				//-- put the message in the receiver's action queue --//
800 
801 				toNation->add_action( 0, 0, 0, 0, ACTION_AI_PROCESS_TALK_MSG, talk_msg_array.recno() );
802 			}
803 			else if( talkMsgPtr->reply_type == REPLY_NOT_NEEDED )
804 			{
805 				//--- notify the receiver immediately ---//
806 
807 				toNation->notify_talk_msg( talkMsgPtr );
808 			}
809 			else
810 				err_here();
811 			break;
812 
813 		case NATION_REMOTE:	// do nothing here as NATION_OWN handle both msg from AI and a remote player
814 			break;
815 	}
816 }
817 //-------- End of function TalkRes::send_talk_msg_now ---------//
818 
819 
820 //------- Begin of function TalkRes::reply_talk_msg --------//
821 //
822 // If the nation which receives this message decides to accept
823 // the offer of this message, this function is called.
824 //
825 // <int>  talkMsgRecno - the recno of the TalkMsg
826 // <char> replyType	  - reply type, either REPLY_ACCEPT or REPLY_REJECT
827 // <char> remoteAction - remote action type
828 //
reply_talk_msg(int talkMsgRecno,char replyType,char remoteAction)829 void TalkRes::reply_talk_msg(int talkMsgRecno, char replyType, char remoteAction)
830 {
831 	//-------- send multiplayer -----------//
832 
833 	if( !remoteAction && remote.is_enable() )
834 	{
835 		// packet structure : <talkRecno:int> <reply type:char> <padding:char>
836 		char* charPtr = remote.new_send_queue_msg( MSG_REPLY_TALK_MSG, sizeof(int)+2*sizeof(char) );
837 		*(int *)charPtr = talkMsgRecno;
838 		charPtr[sizeof(int)] = replyType;
839 		charPtr[sizeof(int)+sizeof(char)] = 0;
840 		return;
841 	}
842 
843 	//-------------------------------------//
844 
845 	err_when( is_talk_msg_deleted(talkMsgRecno) );
846 
847 	TalkMsg* talkMsgPtr = get_talk_msg(talkMsgRecno);
848 	Nation*  fromNation = nation_array[talkMsgPtr->from_nation_recno];
849 
850 	err_when( talkMsgPtr->reply_type == REPLY_NOT_NEEDED );
851 	err_when( replyType != REPLY_ACCEPT && replyType != REPLY_REJECT );
852 
853 	talkMsgPtr->reply_type = replyType;
854 	talkMsgPtr->reply_date = info.game_date;
855 
856 	switch( fromNation->nation_type )
857 	{
858 		case NATION_OWN:
859 			news_array.diplomacy( talkMsgRecno );
860 			// ###### begin Gilbert 9/10 ########//
861 			// sound effect
862 			se_ctrl.immediate_sound("GONG");
863 			// ###### end Gilbert 9/10 ########//
864 			break;
865 
866 		case NATION_AI:
867 			fromNation->ai_notify_reply( talkMsgRecno );		// notify the AI nation about this reply.
868 			break;
869 
870 		case NATION_REMOTE:
871 			break;
872 	}
873 
874 	//------- if the offer is accepted -------//
875 
876 	if( talkMsgPtr->reply_type == REPLY_ACCEPT )
877 		talkMsgPtr->process_accepted_reply();
878 
879 	//--- if the player has replyed the message, remove it from the news display ---//
880 
881 	if( talkMsgPtr->to_nation_recno == nation_array.player_recno )
882 		news_array.remove(NEWS_DIPLOMACY, talkMsgRecno);
883 }
884 //-------- End of function TalkRes::reply_talk_msg ---------//
885 
886 
887 //------- Begin of function TalkRes::disp_talk --------//
888 
disp_talk()889 void TalkRes::disp_talk()
890 {
891 	//----- if the player can send no more message to the nation ---//
892 
893 	if( !info.player_reply_mode &&
894 		 !can_send_any_msg(cur_talk_msg.to_nation_recno, nation_array.player_recno) )
895 	{
896 		if( !( choice_question && strcmp(choice_question, MESSAGE_SENT_STR)==0 ) )		// if it's currently displaying the has sent notification, display that message
897 		{
898 			const char* msgStr = _("You've sent too many messages to this kingdom. You cannot send any new messages until the existing ones are processed.");
899 
900 			font_san.put_paragraph( TALK_X1, TALK_Y1, TALK_X2, TALK_Y2, msgStr, 4 );
901 			return;
902 		}
903 	}
904 
905 	//--- return whether the talk choices should be refreshed. ---//
906 
907 	if( !reply_talk_msg_recno && !cur_talk_msg.talk_id )		// not replying and haven't selected a message type yet.
908 	{
909 		for( int i=0 ; i<MAX_TALK_TYPE ; i++ )
910 		{
911 			if( available_talk_id_array[i] != can_send_msg(cur_talk_msg.to_nation_recno, cur_talk_msg.from_nation_recno, i+1) )
912 			{
913 				set_talk_choices();
914 				break;
915 			}
916 		}
917 	}
918 
919 	//------ repaint the area for displaying the sub-title ------//
920 
921 	int 	 y=TALK_Y1;
922 	String str;
923 
924 	//----- if there is a question on the choices ------//
925 
926 	if( choice_question )
927 	{
928 		font_san.put( TALK_X1+3, y, choice_question );
929 		y+=TALK_LINE_HEIGHT;
930 	}
931 
932 	if( choice_question_second_line )		// second line message
933 	{
934 		font_san.put( TALK_X1+3, y, choice_question_second_line );
935 		y+=TALK_LINE_HEIGHT;
936 	}
937 
938 	//--------- display talk choices ---------//
939 
940 	for( int i=0 ; i<talk_choice_count ; i++, y+=TALK_LINE_HEIGHT )
941 	{
942 		if( i+1 == cur_choice_id )		// this is the one the mouse cursor is currently on
943 			vga_back.adjust_brightness( TALK_X1, y, TALK_X2, y+TALK_LINE_HEIGHT-1, -3 );
944 
945 		if( choice_question )
946 		{
947 			str  = "- ";		// display bullets in front of the text strings
948 			str += talk_choice_array[i].str;
949 		}
950 		else
951 			str = talk_choice_array[i].str;
952 
953 		font_san.put_paragraph( TALK_X1+3, y+2, TALK_X2-3, y+font_san.height()+1, str );
954 	}
955 }
956 //-------- End of function TalkRes::disp_talk ---------//
957 
958 
959 //------- Begin of function TalkRes::detect_talk_choices --------//
960 //
detect_talk_choices()961 int TalkRes::detect_talk_choices()
962 {
963 	int i, y=TALK_Y1;
964 	int newChoiceId=0;
965 
966 	if( choice_question )
967 		y+=TALK_LINE_HEIGHT;
968 
969 	if( choice_question_second_line )
970 		y+=TALK_LINE_HEIGHT;
971 
972 	for( i=0 ; i<talk_choice_count ; i++, y+=TALK_LINE_HEIGHT )
973 	{
974 		if( mouse.in_area(TALK_X1, y, TALK_X2, y+TALK_LINE_HEIGHT-1) )
975 		{
976 			newChoiceId = i+1;
977 			break;
978 		}
979 	}
980 
981 	//-------- refresh talk display -------//
982 
983 	if( newChoiceId != cur_choice_id )
984 	{
985 		cur_choice_id = newChoiceId;
986 		disp_talk();
987 	}
988 
989 	//------ if pressed on one of the talks ------//
990 
991 	if( newChoiceId && mouse.single_click(TALK_X1, y, TALK_X2, y+TALK_LINE_HEIGHT-1) )
992 		return newChoiceId;
993 
994 	return 0;
995 }
996 //-------- End of function TalkRes::detect_talk_choices ---------//
997 
998 
999 //------- Begin of function TalkRes::detect_talk --------//
1000 //
detect_talk()1001 int TalkRes::detect_talk()
1002 {
1003 	//----- if the message which player is reply is deleted (this can only happen when the player stays on the reply message screen for almost 1 year without doing anything and then the message is automatically deleted after having being kept for 1 year ---//
1004 
1005 	if( reply_talk_msg_recno &&
1006 		 is_talk_msg_deleted(reply_talk_msg_recno) )		// the message may become invalid during the replying period
1007 	{
1008 		sys.set_view_mode(save_view_mode);
1009 
1010 		if( save_view_mode == MODE_NATION )
1011 		{
1012 			cur_talk_msg.talk_id = 0;
1013 			init_conversion(cur_talk_msg.to_nation_recno);
1014 		}
1015 
1016 		return 0;
1017 	}
1018 
1019 	//------------------------------------------//
1020 
1021 	int choiceId = detect_talk_choices();
1022 
1023 	if( !choiceId )
1024 		return 0;
1025 
1026 	int choicePara = talk_choice_array[choiceId-1].para;
1027 
1028 	//---- if the player is replying message from other nation ----//
1029 
1030 	if( reply_talk_msg_recno )
1031 	{
1032 		if( !is_talk_msg_deleted(reply_talk_msg_recno) )		// the message may become invalid during the replying period
1033 		{
1034 			if( choicePara==1 )
1035 				reply_talk_msg(reply_talk_msg_recno, REPLY_ACCEPT, COMMAND_PLAYER);
1036 			else
1037 				reply_talk_msg(reply_talk_msg_recno, REPLY_REJECT, COMMAND_PLAYER);
1038 		}
1039 
1040 		sys.set_view_mode(save_view_mode);
1041 
1042 		if( save_view_mode == MODE_NATION )
1043 		{
1044 			cur_talk_msg.talk_id = 0;
1045 			init_conversion(cur_talk_msg.to_nation_recno);
1046 		}
1047 
1048 		return 1;
1049 	}
1050 
1051 	//---------------------------------------//
1052 
1053 	if( strcmp( talk_choice_array[choiceId-1].str, _("Cancel.") ) == 0 ||
1054 		 (choice_question && strcmp( choice_question, MESSAGE_SENT_STR )==0) )
1055 	{
1056 		cur_talk_msg.talk_id = 0;
1057 		init_conversion(cur_talk_msg.to_nation_recno);
1058 		return 1;
1059 	}
1060 
1061 	//------ set the current choice to cur_talk_msg -------//
1062 
1063 	if( cur_talk_msg.talk_id == 0 )
1064 		cur_talk_msg.talk_id = choicePara;
1065 
1066 	else if( cur_talk_msg.talk_para1 == 0 )
1067 		cur_talk_msg.talk_para1 = choicePara;
1068 
1069 	else if( cur_talk_msg.talk_para2 == 0 )
1070 		cur_talk_msg.talk_para2 = choicePara;
1071 
1072 	else
1073 		err_here();
1074 
1075 	//------ prepare the next available choices ------//
1076 
1077 	if( !set_talk_choices() )		// the talk is complete
1078 	{
1079 		send_talk_msg( &cur_talk_msg, COMMAND_PLAYER );
1080 
1081 		//--- the message has been sent, display notification message ---//
1082 
1083 		choice_question = MESSAGE_SENT_STR;
1084 		choice_question_second_line = NULL;
1085 
1086 		talk_choice_count = 0;
1087 		add_talk_choice( _("Continue."), 0 );
1088 	}
1089 
1090 	return 1;
1091 }
1092 //-------- End of function TalkRes::detect_talk ---------//
1093 
1094 
1095 //------- Begin of function TalkRes::get_talk_msg --------//
1096 
get_talk_msg(int recNo)1097 TalkMsg* TalkRes::get_talk_msg(int recNo)
1098 {
1099 	err_when( recNo < 1 || recNo > talk_msg_array.size() );
1100 
1101 	TalkMsg* talkMsg = (TalkMsg*) talk_msg_array.get(recNo);
1102 
1103 	if( !talkMsg->talk_id )
1104 		err.run( "get_talk_msg() error, the TalkMsg is deleted." );
1105 
1106 	return talkMsg;
1107 }
1108 //-------- End of function TalkRes::get_talk_msg ---------//
1109 
1110 
1111 //------- Begin of function TalkRes::is_talk_msg_deleted --------//
1112 
is_talk_msg_deleted(int recNo)1113 int TalkRes::is_talk_msg_deleted(int recNo)
1114 {
1115 	if( recNo < 1 || recNo > talk_msg_array.size() )
1116 		return 1;
1117 
1118 	TalkMsg* talkMsg = (TalkMsg*) talk_msg_array.get(recNo);
1119 
1120 	return talkMsg->talk_id==0;
1121 }
1122 //-------- End of function TalkRes::is_talk_msg_deleted ---------//
1123 
1124 
1125 //------- Begin of function TalkRes::next_day --------//
1126 
next_day()1127 void TalkRes::next_day()
1128 {
1129 	if( info.game_date%7 == 0 )
1130 		process_talk_msg();
1131 }
1132 //-------- End of function TalkRes::next_day ---------//
1133 
1134 
1135 //------ Begin of function TalkRes::process_talk_msg ------//
1136 //
process_talk_msg()1137 void TalkRes::process_talk_msg()
1138 {
1139 	int 		i;
1140 	TalkMsg* talkMsg;
1141 
1142 	for( i=talk_msg_count() ; i>0 ; i-- )
1143 	{
1144 		if( is_talk_msg_deleted(i) )
1145 			continue;
1146 
1147 		talkMsg = get_talk_msg(i);
1148 
1149 		//--------------------------------------------------------//
1150 		// If this is an AI message and there is no response from
1151 		// the player after one month the message has been sent,
1152 		// it presumes that the message has been rejected.
1153 		//--------------------------------------------------------//
1154 
1155 		if( nation_array[talkMsg->from_nation_recno]->nation_type == NATION_AI &&
1156 			 talkMsg->reply_type == REPLY_WAITING &&
1157 			 info.game_date > talkMsg->date + DISP_NEWS_DAYS )
1158 		{
1159 			talkMsg->reply_type = REPLY_REJECT;
1160 
1161 			nation_array[talkMsg->from_nation_recno]->ai_notify_reply(i);
1162 		}
1163 
1164 		//--- delete the talk message after a year ---//
1165 
1166 		if( info.game_date > talkMsg->date + TALK_MSG_KEEP_DAYS )
1167 			del_talk_msg(i);
1168 	}
1169 }
1170 //-------- End of function TalkRes::process_talk_msg ---------//
1171 
1172 
1173 //------ Begin of function TalkRes::del_talk_msg ------//
1174 //
del_talk_msg(int talkMsgRecno)1175 void TalkRes::del_talk_msg(int talkMsgRecno)
1176 {
1177 	err_when( is_talk_msg_deleted(talkMsgRecno) );
1178 
1179 	TalkMsg* talkMsg = get_talk_msg(talkMsgRecno);
1180 
1181 	//--- if this message is sent to an AI nation ---//
1182 
1183 	Nation* nationPtr = nation_array[talkMsg->to_nation_recno];
1184 
1185 	if( nationPtr->nation_type == NATION_AI &&
1186 		 (talkMsg->reply_type == REPLY_NOT_NEEDED ||		// even if a reply is not needed, the message will still be sent to the AI for notification.
1187 		  talkMsg->reply_type == REPLY_WAITING) )
1188 	{
1189 		//--- it may still have the message in its action queue ---//
1190 
1191 		ActionNode* actionNode;
1192 
1193 		for( int i=nationPtr->action_count() ; i>0 ; i-- )
1194 		{
1195 			actionNode = nationPtr->get_action(i);
1196 
1197 			if( actionNode->action_mode == ACTION_AI_PROCESS_TALK_MSG &&
1198 				 actionNode->action_para == talkMsgRecno )
1199 			{
1200 				nationPtr->del_action(i);
1201 				break;
1202 			}
1203 		}
1204 	}
1205 
1206 	//----- delete the message from the news array -----//
1207 
1208 	if( talkMsg->to_nation_recno == nation_array.player_recno ||
1209 		 talkMsg->from_nation_recno == nation_array.player_recno )
1210 	{
1211 		news_array.remove( NEWS_DIPLOMACY, talkMsgRecno );
1212 	}
1213 
1214 	//----- link it out from talk_msg_array -----//
1215 
1216 	talk_msg_array.linkout(talkMsgRecno);
1217 }
1218 //-------- End of function TalkRes::del_talk_msg ---------//
1219 
1220 
1221 //------- Begin of function TalkRes::is_talk_msg_exist --------//
1222 //
1223 // <int> checkPara - whether check talk_para1 and talk_para2
1224 //						   in comparing TalkMsg.
1225 //
1226 // return : <int> >0 - the recno of the talk msg that already exists
1227 //					  ==0 - not found
1228 //
is_talk_msg_exist(TalkMsg * thisTalkMsg,int checkPara)1229 int TalkRes::is_talk_msg_exist(TalkMsg* thisTalkMsg, int checkPara)
1230 {
1231 	int 		i;
1232 	TalkMsg* talkMsg;
1233 
1234 	for( i=talk_msg_count() ; i>0 ; i-- )
1235 	{
1236 		if( is_talk_msg_deleted(i) )
1237 			continue;
1238 
1239 		talkMsg = get_talk_msg(i);
1240 
1241 		if( talkMsg->reply_type == REPLY_WAITING ||
1242 			 talkMsg->reply_type == REPLY_NOT_NEEDED )
1243 		{
1244 			if( talkMsg->talk_id 			 == thisTalkMsg->talk_id &&
1245 				 talkMsg->from_nation_recno == thisTalkMsg->from_nation_recno &&
1246 				 talkMsg->to_nation_recno   == thisTalkMsg->to_nation_recno )
1247 			{
1248 				if( checkPara )
1249 				{
1250 					if( talkMsg->talk_para1 == thisTalkMsg->talk_para1 &&
1251 						 talkMsg->talk_para2 == thisTalkMsg->talk_para2 )
1252 					{
1253 						return i;
1254 					}
1255 				}
1256 				else
1257 					return i;
1258 			}
1259 		}
1260 	}
1261 
1262 	return 0;
1263 }
1264 //-------- End of function TalkRes::is_talk_msg_exist ---------//
1265 
1266 
1267 //------- Begin of function TalkRes::wait_msg_count --------//
1268 //
1269 // Return the number of messages sent to the nation waiting
1270 // for its reply.
1271 //
wait_msg_count(int toNationRecno,int fromNationRecno)1272 int TalkRes::wait_msg_count(int toNationRecno, int fromNationRecno)
1273 {
1274 	int 		i, waitMsgCount=0;
1275 	TalkMsg* talkMsg;
1276 
1277 	for( i=talk_msg_count() ; i>0 ; i-- )
1278 	{
1279 		if( is_talk_msg_deleted(i) )
1280 			continue;
1281 
1282 		talkMsg = get_talk_msg(i);
1283 
1284 		if( talkMsg->reply_type == REPLY_WAITING &&
1285 			 talkMsg->to_nation_recno == toNationRecno &&
1286 			 talkMsg->from_nation_recno == fromNationRecno &&
1287 			 info.game_date < talkMsg->date + 30 )					// only count message in a month
1288 		{
1289 			waitMsgCount++;
1290 		}
1291 	}
1292 
1293 	return waitMsgCount;
1294 }
1295 //-------- End of function TalkRes::wait_msg_count ---------//
1296 
1297 
1298 //------- Begin of function TalkRes::player_reply --------//
1299 
player_reply(int talkMsgRecno)1300 void TalkRes::player_reply(int talkMsgRecno)
1301 {
1302 	//------- set the reply choices --------//
1303 
1304 	err_when( is_talk_msg_deleted(talkMsgRecno) );
1305 
1306 	TalkMsg* talkMsg = get_talk_msg(talkMsgRecno);
1307 
1308 	if( nation_array.is_deleted(talkMsg->from_nation_recno) )
1309 		return;
1310 
1311 	init_conversion(talkMsg->from_nation_recno);
1312 
1313 	talk_choice_count    = 0;
1314 	cur_choice_id 		   = 0;
1315 	reply_talk_msg_recno = talkMsgRecno;
1316 
1317 	//--------- add talk choices ---------//
1318 
1319 	static String msgStr, msgStr2;
1320 
1321 	msgStr = talkMsg->msg_str(nation_array.player_recno);		// make a static copy of it.
1322 	choice_question = msgStr;
1323 
1324 	//---- see if this message has a second line -----//
1325 
1326 	msgStr2 = talkMsg->msg_str(nation_array.player_recno, 0, 1);		// 1-display the second line of the question
1327 
1328 	if( msgStr!=msgStr2 )
1329 		choice_question_second_line = msgStr2;
1330 	else
1331 		choice_question_second_line = NULL;
1332 
1333 	//--------- add choices to the question ---------//
1334 
1335 	if( talkMsg->can_accept() )			// whether the replier can accept the request or demand of the message
1336 		add_talk_choice( _("Accept."), 1 );
1337 
1338 	add_talk_choice( _("Reject."), 0 );
1339 
1340 	//--- switch to the nation report mode and go to the diplomacy mode ---//
1341 
1342 	info.init_player_reply( talkMsg->from_nation_recno );
1343 
1344 	save_view_mode = sys.view_mode;
1345 
1346 	sys.set_view_mode(MODE_NATION);
1347 }
1348 //-------- End of function TalkRes::player_reply ---------//
1349 
1350 
1351 //------- Begin of function TalkRes::del_all_nation_msg --------//
1352 //
1353 // Delete all messages related to this nation.
1354 //
del_all_nation_msg(int nationRecno)1355 void TalkRes::del_all_nation_msg(int nationRecno)
1356 {
1357 	int 		i;
1358 	TalkMsg* talkMsg;
1359 
1360 	for( i=talk_msg_count() ; i>0 ; i-- )
1361 	{
1362 		if( is_talk_msg_deleted(i) )
1363 			continue;
1364 
1365 		talkMsg = get_talk_msg(i);
1366 
1367 		// If the nation is referenced anywhere in the talk-message, is_valid_to_disp() will return 0 and the talk message should than be deleted. Need to explicitly specify nation as it hasn't been deleted yet.
1368 		if( !talkMsg->is_valid_to_disp(nationRecno) )
1369 		{
1370 			del_talk_msg(i);
1371 		}
1372 	}
1373 }
1374 //-------- End of function TalkRes::del_all_nation_msg ---------//
1375 
1376 
1377 #define ASCII_ZERO 0x30
1378 //------ Begin of static function select_nation_color ------//
1379 //
select_nation_color(char nation_color)1380 static char* select_nation_color(char nation_color)
1381 {
1382 	static char colorCodeStr[] = "@COL0 ";
1383 
1384 	colorCodeStr[4] = ASCII_ZERO + nation_color;
1385 
1386 	return colorCodeStr;
1387 }
1388 //------ End of static function select_nation_color ------//
1389