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    : ONEWS2.CPP
22 //Description : News adding functions
23 
24 #include <OTOWN.h>
25 #include <ONATION.h>
26 #include <OMONSRES.h>
27 #include <OTALKRES.h>
28 #include <OFIRM.h>
29 #include <OSPY.h>
30 #include <OUNIT.h>
31 #include <ONEWS.h>
32 
33 
34 //------ Begin of function NewsArray::diplomacy -----//
35 //
36 // <int> talkMsgRecno = the recno of the TalkMsg in talk_res.talk_msg_array
37 //
38 // short_para1 = the recno of the TalkMsg in talk_res.talk_msg_array
39 //
diplomacy(int talkMsgRecno)40 void NewsArray::diplomacy(int talkMsgRecno)
41 {
42 	//----------- add news --------------//
43 
44 	err_when( talk_res.is_talk_msg_deleted(talkMsgRecno) );
45 
46 	TalkMsg* talkMsgPtr = talk_res.get_talk_msg(talkMsgRecno);
47 
48 	News* newsPtr = add_news( NEWS_DIPLOMACY, NEWS_NORMAL, talkMsgPtr->from_nation_recno, talkMsgPtr->to_nation_recno );
49 
50 	if( !newsPtr )		// only news of nations that have contact with the player are added
51 		return;
52 
53 	newsPtr->short_para1 = talkMsgRecno;
54 }
55 //------- End of function NewsArray::diplomacy -----//
56 
57 
58 //------ Begin of function NewsArray::town_rebel -----//
59 //
60 // <int> townRecno  = the recno of the town where people there rebel
61 // <int> rebelCount = no. of rebels
62 //
63 // short_para1 = the town name id.
64 // short_para2 = no. of rebels
65 //
town_rebel(int townRecno,int rebelCount)66 void NewsArray::town_rebel(int townRecno, int rebelCount)
67 {
68 	Town* townPtr = town_array[townRecno];
69 
70 	//----------- add news --------------//
71 
72 	News* newsPtr = add_news( NEWS_TOWN_REBEL, NEWS_NORMAL, townPtr->nation_recno );
73 
74 	if( !newsPtr )		// only news of nations that have contact with the player are added
75 		return;
76 
77 	newsPtr->short_para1 = townPtr->town_name_id;
78 	newsPtr->short_para2 = rebelCount;
79 
80 	//-------- set location ----------//
81 
82 	newsPtr->set_loc( townPtr->center_x, townPtr->center_y, NEWS_LOC_TOWN, townRecno );
83 }
84 //------- End of function NewsArray::town_rebel -----//
85 
86 
87 //------ Begin of function NewsArray::migrate -----//
88 //
89 // <int> srcTownRecno = the town that the worker migrates from
90 // <int> desTownRecno = the town that the worker migrates to
91 // <int> raceId		 = race id. of the migrated worker/peasant
92 // <int> migratedCount= no. of people migrated.
93 // [int] firmRecno    = if firm worker migrates,
94 //					  			>this is the firm id. that the worker works for
95 //               			if town peasant migrates
96 //					  			>this is 0
97 //
98 // short_para1 = the town name id. that the worker migrates from
99 // short_para2 = the town name id. that the worker migrates to
100 // short_para3 = race id. of the migrated worker/peasant
101 // short_para4 = no. of people migrated
102 // short_para5 = the firm id. that the worker works for
103 //
migrate(int srcTownRecno,int desTownRecno,int raceId,int migratedCount,int firmRecno)104 void NewsArray::migrate(int srcTownRecno, int desTownRecno, int raceId, int migratedCount, int firmRecno)
105 {
106 	err_when( srcTownRecno==0 || desTownRecno==0 || raceId==0 || migratedCount==0 );
107 
108 	Town* srcTown = town_array[srcTownRecno];
109 	Town* desTown = town_array[desTownRecno];
110 
111 	//----------- add news --------------//
112 
113 	News* newsPtr = add_news( NEWS_MIGRATE, NEWS_NORMAL, srcTown->nation_recno, desTown->nation_recno );
114 
115 	if( !newsPtr )		// only news of nations that have contact with the player are added
116 		return;
117 
118 	newsPtr->short_para1 = srcTown->town_name_id;
119 	newsPtr->short_para2 = desTown->town_name_id;
120 	newsPtr->short_para3 = raceId;
121 	newsPtr->short_para4 = migratedCount;
122 
123 	if( firmRecno )
124 		newsPtr->short_para5 = firm_array[firmRecno]->firm_id;
125 	else
126 		newsPtr->short_para5 = 0;
127 
128 	//-------- set location ----------//
129 
130 	newsPtr->set_loc( desTown->center_x, desTown->center_y, NEWS_LOC_TOWN, desTownRecno );
131 }
132 //------- End of function NewsArray::migrate -----//
133 
134 
135 //------ Begin of function NewsArray::new_nation -----//
136 //
137 // <int> nationRecno - recno of the new nation.
138 //
139 // king_name1() - name of the king of the new kingdom.
140 //
new_nation(int nationRecno)141 void NewsArray::new_nation(int nationRecno)
142 {
143 	News* newsPtr = add_news( NEWS_NEW_NATION, NEWS_NORMAL, nationRecno );
144 
145 	if( !newsPtr )
146 		return;
147 
148 	//---- set the news location to one of its town ----//
149 
150 	for( int i=town_array.size() ; i>0 ; i-- )
151 	{
152 		if( town_array.is_deleted(i) )
153 			continue;
154 
155 		Town* townPtr = town_array[i];
156 
157 		if( townPtr->nation_recno == nationRecno )
158 		{
159 			newsPtr->set_loc( townPtr->center_x, townPtr->center_y,
160 									NEWS_LOC_TOWN, i );
161 			break;
162 		}
163 	}
164 }
165 //------- End of function NewsArray::new_nation -----//
166 
167 
168 //------ Begin of function NewsArray::nation_destroyed -----//
169 //
170 // <int> nationRecno - recno of the nation that has been destroyed
171 //
172 // nation_name1() - the nation that has been destroyed.
173 //
nation_destroyed(int nationRecno)174 void NewsArray::nation_destroyed(int nationRecno)
175 {
176 	add_news( NEWS_NATION_DESTROYED, NEWS_NORMAL, nationRecno );
177 }
178 //------- End of function NewsArray::nation_destroyed -----//
179 
180 
181 //------ Begin of function NewsArray::nation_surrender -----//
182 //
183 // <int> nationRecno   - recno of the surrendering nation.
184 // <int> toNationRecno - recno of the nation to surrender.
185 //
nation_surrender(int nationRecno,int toNationRecno)186 void NewsArray::nation_surrender(int nationRecno, int toNationRecno)
187 {
188 	add_news( NEWS_NATION_SURRENDER, NEWS_NORMAL, nationRecno, toNationRecno );
189 }
190 //------- End of function NewsArray::nation_surrender -----//
191 
192 
193 //------ Begin of function NewsArray::king_die -----//
194 //
195 // <int> nationRecno - recno of the nation with its king died.
196 //
197 // king_name1() - the nation whose king has died.
198 //
king_die(int nationRecno)199 void NewsArray::king_die(int nationRecno)
200 {
201 	add_news( NEWS_KING_DIE, NEWS_NORMAL, nationRecno );
202 }
203 //------- End of function NewsArray::king_die -----//
204 
205 
206 //------ Begin of function NewsArray::new_king -----//
207 //
208 // <int> nationRecno   - recno of the nation
209 // <int> kingUnitRecno - unit recno of the new king.
210 //
211 // This function should be called before set_king() has been called.
212 //
213 // nation_name1() - name of the nation where there is a new king.
214 //
215 // short_para1 - race id. of the new king.
216 // short_para2 - name id. of the new king.
217 //
new_king(int nationRecno,int kingUnitRecno)218 void NewsArray::new_king(int nationRecno, int kingUnitRecno)
219 {
220 	News* newsPtr = add_news( NEWS_NEW_KING, NEWS_NORMAL, nationRecno );
221 
222 	if( !newsPtr )
223 		return;
224 
225 	Unit* unitPtr = unit_array[kingUnitRecno];
226 
227 	newsPtr->short_para1 = unitPtr->race_id;
228 	newsPtr->short_para2 = unitPtr->name_id;
229 }
230 //------- End of function NewsArray::new_king -----//
231 
232 
233 //------ Begin of function NewsArray::firm_destroyed -----//
234 //
235 // <int>   firmRecno  - recno of the firm destroyed.
236 // <Unit*> attackUnit - recno to the attacking unit.
237 // <short> destroyerNationRecno - recno of the nation that destroyed the firm.
238 //
239 // short_para1 - id. of the firm destroyed.
240 // short_para2 - name id of the town where the firm is located.
241 // short_para3 - destroyer type: 1 - a nation, 2 - rebels, 3 - Fryhtans.
242 //
firm_destroyed(int firmRecno,Unit * attackUnit,short destroyerNationRecno)243 void NewsArray::firm_destroyed(int firmRecno, Unit *attackUnit, short destroyerNationRecno)
244 {
245 	Firm* firmPtr = firm_array[firmRecno];
246 
247 	err_when( firmPtr->nation_recno != nation_array.player_recno );
248 
249 	News* newsPtr = add_news( NEWS_FIRM_DESTROYED, NEWS_NORMAL, firmPtr->nation_recno, destroyerNationRecno );
250 
251 	if( !newsPtr )		// only news of nations that have contact with the player are added
252 		return;
253 
254 	newsPtr->short_para1 = firmPtr->firm_id;
255 
256 	if( firmPtr->closest_town_name_id )
257 		newsPtr->short_para2 = firmPtr->closest_town_name_id;
258 	else
259 		newsPtr->short_para2 = firmPtr->get_closest_town_name_id();
260 
261 	//-------- set destroyer type ------//
262 
263 	newsPtr->short_para3 = DESTROYER_UNKNOWN;
264 
265 	if( destroyerNationRecno )
266 	{
267 		if( !nation_array.is_deleted(destroyerNationRecno) )
268 			newsPtr->short_para3 = DESTROYER_NATION;
269 	}
270 	else if( attackUnit )
271 	{
272 		if( attackUnit->unit_mode == UNIT_MODE_REBEL )
273 			newsPtr->short_para3 = DESTROYER_REBEL;
274 
275 		else if( unit_res[attackUnit->unit_id]->unit_class == UNIT_CLASS_MONSTER )
276 			newsPtr->short_para3 = DESTROYER_MONSTER;
277 	}
278 
279 	//--------- set location ---------//
280 
281 	newsPtr->set_loc( firmPtr->center_x, firmPtr->center_y, NEWS_LOC_ANY );
282 }
283 //------- End of function NewsArray::firm_destroyed -----//
284 
285 
286 //------ Begin of function NewsArray::firm_captured -----//
287 //
288 // <int> firmRecno 	  - recno of the firm destroyed.
289 // <int> takeoverNationRecno - recno of nation that has taken over the firm.
290 // <int> spyTakeover	  - whether the capturer of the firm is a spy.
291 //
292 // short_para1 - id. of the firm destroyed.
293 // short_para2 - name id of the town where the firm is located.
294 // short_para3 - whether the capturer of the firm is a spy.
295 //
firm_captured(int firmRecno,int takeoverNationRecno,int spyTakeover)296 void NewsArray::firm_captured(int firmRecno, int takeoverNationRecno, int spyTakeover)
297 {
298 	Firm* firmPtr = firm_array[firmRecno];
299 
300 	err_when( firmPtr->nation_recno != nation_array.player_recno );
301 
302 	News* newsPtr = add_news( NEWS_FIRM_CAPTURED, NEWS_NORMAL, firmPtr->nation_recno, takeoverNationRecno );
303 
304 	if( !newsPtr )		// only news of nations that have contact with the player are added
305 		return;
306 
307 	newsPtr->short_para1 = firmPtr->firm_id;
308 
309 	if( firmPtr->closest_town_name_id )
310 		newsPtr->short_para2 = firmPtr->closest_town_name_id;
311 	else
312 		newsPtr->short_para2 = firmPtr->get_closest_town_name_id();
313 
314 	newsPtr->short_para3 = spyTakeover;
315 
316 	//--------- set location ---------//
317 
318 	newsPtr->set_loc( firmPtr->center_x, firmPtr->center_y, NEWS_LOC_FIRM, firmRecno );
319 }
320 //------- End of function NewsArray::firm_captured -----//
321 
322 
323 //------ Begin of function NewsArray::town_destroyed -----//
324 //
325 // <int> townNameId	 - name id. of the town destroyed.
326 // <int> xLoc, yLoc   - location of the town
327 // <Unit*> attackUnit - recno to the attacking unit.
328 // <short> destroyerNationRecno - recno of the nation that destroyed the firm.
329 //
330 // short_para1 - name id. of the town destroyed.
331 // short_para2 - destroyer type: 1 - a nation, 2 - rebels, 3 - Fryhtans.
332 //
town_destroyed(int townNameId,int xLoc,int yLoc,Unit * attackUnit,short destroyerNationRecno)333 void NewsArray::town_destroyed(int townNameId, int xLoc, int yLoc, Unit* attackUnit, short destroyerNationRecno)
334 {
335 	News* newsPtr = add_news( NEWS_TOWN_DESTROYED, NEWS_NORMAL, nation_array.player_recno, destroyerNationRecno );
336 
337 	if( !newsPtr )		// only news of nations that have contact with the player are added
338 		return;
339 
340 	newsPtr->short_para1 = townNameId;
341 
342 	//-------- set destroyer type ------//
343 
344 	newsPtr->short_para2 = DESTROYER_UNKNOWN;
345 
346 	if( destroyerNationRecno )
347 	{
348 		if( !nation_array.is_deleted(destroyerNationRecno) )
349 			newsPtr->short_para2 = DESTROYER_NATION;
350 	}
351 	else if( attackUnit )
352 	{
353 		if( attackUnit->unit_mode == UNIT_MODE_REBEL )
354 			newsPtr->short_para2 = DESTROYER_REBEL;
355 
356 		else if( unit_res[attackUnit->unit_id]->unit_class == UNIT_CLASS_MONSTER )
357 			newsPtr->short_para2 = DESTROYER_MONSTER;
358 	}
359 
360 	//-------- set location ----------//
361 
362 	newsPtr->set_loc( xLoc, yLoc, NEWS_LOC_ANY );
363 }
364 //------- End of function NewsArray::town_destroyed -----//
365 
366 
367 //------ Begin of function NewsArray::town_abandoned -----//
368 //
369 // <int> townRecno - recno of the town destroyed.
370 //
371 // short_para1 - name id. of the town destroyed.
372 //
town_abandoned(int townRecno)373 void NewsArray::town_abandoned(int townRecno)
374 {
375 	Town* townPtr = town_array[townRecno];
376 
377 	err_when( townPtr->nation_recno != nation_array.player_recno );
378 
379 	News* newsPtr = add_news( NEWS_TOWN_ABANDONED, NEWS_NORMAL, townPtr->nation_recno );
380 
381 	if( !newsPtr )		// only news of nations that have contact with the player are added
382 		return;
383 
384 	newsPtr->short_para1 = townPtr->town_name_id;
385 
386 	//-------- set location ----------//
387 
388 	newsPtr->set_loc( townPtr->center_x, townPtr->center_y, NEWS_LOC_ANY );
389 }
390 //------- End of function NewsArray::town_abandoned -----//
391 
392 
393 //------ Begin of function NewsArray::town_surrendered -----//
394 //
395 // <int> townRecno 	  - recno of the town
396 // <int> toNationRecno - recno of the nation this town surrenders to
397 //
398 // short_para1 - name id. of the surrendering town.
399 //
400 // nation_name1() - name of the nation the town surrenders to.
401 // nation_name2() - name of the nation of the surrendering town.
402 //
403 // This function should be called before the town surrenders.
404 //
town_surrendered(int townRecno,int toNationRecno)405 void NewsArray::town_surrendered(int townRecno, int toNationRecno)
406 {
407 	Town* townPtr = town_array[townRecno];
408 
409 	err_when( townPtr->nation_recno != nation_array.player_recno &&
410 				 toNationRecno != nation_array.player_recno );
411 
412 	News* newsPtr = add_news( NEWS_TOWN_SURRENDERED, NEWS_NORMAL, toNationRecno, townPtr->nation_recno );
413 
414 	if( !newsPtr )		// only news of nations that have contact with the player are added
415 		return;
416 
417 	newsPtr->short_para1 = townPtr->town_name_id;
418 
419 	//-------- set location ----------//
420 
421 	newsPtr->set_loc( townPtr->center_x, townPtr->center_y, NEWS_LOC_TOWN, townRecno );
422 }
423 //------- End of function NewsArray::town_surrendered -----//
424 
425 
426 //------ Begin of function NewsArray::monster_king_killed -----//
427 //
428 // <int> monsterId - monster id. of the monster king.
429 //
430 // short_para1 - monster id.
431 //
monster_king_killed(int monsterId,int xLoc,int yLoc)432 void NewsArray::monster_king_killed(int monsterId, int xLoc, int yLoc)
433 {
434 	err_when( monsterId < 1 || monsterId > monster_res.monster_count );
435 
436 	News* newsPtr = add_news( NEWS_MONSTER_KING_KILLED, NEWS_NORMAL );
437 
438 	if( !newsPtr )		// only news of nations that have contact with the player are added
439 		return;
440 
441 	newsPtr->short_para1 = monsterId;
442 
443 	//-------- set location ----------//
444 
445 	newsPtr->set_loc( xLoc, yLoc, NEWS_LOC_ANY );
446 }
447 //------- End of function NewsArray::monster_king_killed -----//
448 
449 
450 //------ Begin of function NewsArray::monster_firm_destroyed -----//
451 //
452 // <int> monsterId - monster id. of the monster king.
453 //
454 // short_para1 - monster id.
455 //
monster_firm_destroyed(int monsterId,int xLoc,int yLoc)456 void NewsArray::monster_firm_destroyed(int monsterId, int xLoc, int yLoc)
457 {
458 	err_when( monsterId < 1 || monsterId > monster_res.monster_count );
459 
460 	News* newsPtr = add_news( NEWS_MONSTER_FIRM_DESTROYED, NEWS_NORMAL );
461 
462 	if( !newsPtr )		// only news of nations that have contact with the player are added
463 		return;
464 
465 	newsPtr->short_para1 = monsterId;
466 
467 	//-------- set location ----------//
468 
469 	newsPtr->set_loc( xLoc, yLoc, NEWS_LOC_ANY );
470 }
471 //------- End of function NewsArray::monster_firm_destroyed -----//
472 
473 
474 //------ Begin of function NewsArray::scroll_acquired -----//
475 //
476 // <int> acquireNationRecno - recno of the nation that has acquired the scroll
477 // <int> scrollRaceId	    - race of the scroll
478 //
479 // nation_name1() - the nation that has acquired the scroll.
480 //
481 // short_para1 = the race id. of the scroll.
482 //
scroll_acquired(int acquireNationRecno,int scrollRaceId)483 void NewsArray::scroll_acquired(int acquireNationRecno, int scrollRaceId)
484 {
485 	News* newsPtr = add_news( NEWS_SCROLL_ACQUIRED, NEWS_NORMAL, acquireNationRecno );
486 
487 	if( !newsPtr )		// only news of nations that have contact with the player are added
488 		return;
489 
490 	newsPtr->short_para1 = scrollRaceId;
491 }
492 //------- End of function NewsArray::scroll_acquired -----//
493 
494 
495 //------ Begin of function NewsArray::monster_gold_acquired -----//
496 //
497 // When the player recovered treasures from monsters.
498 //
499 // <int> goldAmt - the amount of treasure recovered.
500 //
501 // short_para1 = amount of gold.
502 //
monster_gold_acquired(int goldAmt)503 void NewsArray::monster_gold_acquired(int goldAmt)
504 {
505 	News* newsPtr = add_news( NEWS_MONSTER_GOLD_ACQUIRED, NEWS_NORMAL, nation_array.player_recno );
506 
507 	if( !newsPtr )
508 		return;
509 
510 	newsPtr->short_para1 = goldAmt;
511 }
512 //------- End of function NewsArray::monster_gold_acquired -----//
513 
514 
515 //------ Begin of function NewsArray::spy_killed -----//
516 //
517 // <int> spyRecno - recno of the spy.
518 //
519 // nation_name1() - your nation.
520 // nation_name2() - the nation that killed your spy.
521 //
522 // short_para1 - firm id. if it's a firm
523 //					  0 if it's a town
524 // short_para2 - the town id.
525 // short_para3 - spy place
526 //
527 // This function should be called just right before the spy is killed.
528 //
spy_killed(int spyRecno)529 void NewsArray::spy_killed(int spyRecno)
530 {
531 	Spy*  spyPtr = spy_array[spyRecno];
532 	News* newsPtr;
533 
534 	//---------- your spy is killed in an enemy nation ---------//
535 
536 	if( spyPtr->true_nation_recno == nation_array.player_recno )
537 	{
538 		newsPtr = add_news( NEWS_YOUR_SPY_KILLED, NEWS_NORMAL,
539 					 nation_array.player_recno, spyPtr->cloaked_nation_recno );
540 	}
541 	else //----- an enemy spy in your nation is uncovered and executed ----//
542 	{
543 		err_when( spyPtr->cloaked_nation_recno != nation_array.player_recno );
544 
545 		newsPtr = add_news( NEWS_ENEMY_SPY_KILLED, NEWS_NORMAL,
546 					 nation_array.player_recno, spyPtr->true_nation_recno );
547 	}
548 
549 	if( !newsPtr )		// only news of nations that have contact with the player are added
550 		return;
551 
552 	//-------------------------------------------//
553 
554 	newsPtr->short_para3 = spyPtr->spy_place;
555 
556 	if( spyPtr->spy_place == SPY_FIRM )
557 	{
558 		Firm* firmPtr = firm_array[spyPtr->spy_place_para];
559 
560 		newsPtr->short_para1 = firmPtr->firm_id;
561 		newsPtr->short_para2 = firmPtr->get_closest_town_name_id();
562 
563 		newsPtr->set_loc( firmPtr->center_x, firmPtr->center_y, NEWS_LOC_FIRM, firmPtr->firm_recno );
564 	}
565 	else if( spyPtr->spy_place == SPY_TOWN )
566 	{
567 		Town* townPtr = town_array[spyPtr->spy_place_para];
568 
569 		newsPtr->short_para1 = 0;
570 		newsPtr->short_para2 = townPtr->town_name_id;
571 
572 		newsPtr->set_loc( townPtr->center_x, townPtr->center_y, NEWS_LOC_TOWN, townPtr->town_recno );
573 	}
574 	else if( spyPtr->spy_place == SPY_MOBILE )
575 	{
576 		Unit* unitPtr = unit_array[spyPtr->spy_place_para];
577 
578 		newsPtr->short_para1 = unitPtr->race_id;
579 		newsPtr->short_para2 = unitPtr->name_id;
580 	}
581 }
582 //------- End of function NewsArray::spy_killed -----//
583 
584 
585 //------ Begin of function NewsArray::unit_betray -----//
586 //
587 // <int> unitRecno - recno of the unit.
588 // <int> betrayToNationRecno - the nation which the unit betray towards
589 //
590 // nation_name1() - the nation that the unit originally belongs to.
591 // nation_name2() - the nation that the unit has turned towards.
592 //
593 // short_para1 - race id. of the unit
594 // short_para2 - name id. of the unit
595 // short_para3 - rank id. of the unit
596 //
597 // This function should be called before the unit betray.
598 //
unit_betray(int unitRecno,int betrayToNationRecno)599 void NewsArray::unit_betray(int unitRecno, int betrayToNationRecno)
600 {
601 	Unit* unitPtr = unit_array[unitRecno];
602 
603 	err_when( unitPtr->nation_recno != nation_array.player_recno &&
604 				 betrayToNationRecno != nation_array.player_recno );
605 
606 	News* newsPtr = add_news( NEWS_UNIT_BETRAY, NEWS_NORMAL, unitPtr->nation_recno, betrayToNationRecno );
607 
608 	if( !newsPtr )		// only news of nations that have contact with the player are added
609 		return;
610 
611 	newsPtr->short_para1 = unitPtr->race_id;
612 	newsPtr->short_para2 = unitPtr->name_id;
613 	newsPtr->short_para3 = unitPtr->rank_id;
614 
615 	//------- set location --------//
616 
617 	if( betrayToNationRecno == nation_array.player_recno )
618 		newsPtr->set_loc( unitPtr->next_x_loc(), unitPtr->next_y_loc(), NEWS_LOC_UNIT, unitRecno, unitPtr->name_id );
619 	else
620 		newsPtr->set_loc( unitPtr->next_x_loc(), unitPtr->next_y_loc(), NEWS_LOC_ANY );
621 }
622 //------- End of function NewsArray::unit_betray -----//
623 
624 
625 //------ Begin of function NewsArray::unit_assassinated -----//
626 //
627 // <int> unitRecno - recno of the unit that has been assassinated.
628 // <int> spyKilled - whether the enemy spy has been killed during his assissination mission.
629 //
630 // short_para1 - race id. of the assassinated unit
631 // short_para2 - name id. of the assassinated unit
632 // short_para3 - rank id. of the assassinated unit
633 // short_para4 - whether the enemy spy has been killed or not.
634 //
unit_assassinated(int unitRecno,int spyKilled)635 void NewsArray::unit_assassinated(int unitRecno, int spyKilled)
636 {
637 	Unit* unitPtr = unit_array[unitRecno];
638 
639 	err_when( unitPtr->nation_recno != nation_array.player_recno );
640 
641 	News* newsPtr = add_news( NEWS_UNIT_ASSASSINATED, NEWS_NORMAL, unitPtr->nation_recno );
642 
643 	if( !newsPtr )		// only news of nations that have contact with the player are added
644 		return;
645 
646 	newsPtr->short_para1 = unitPtr->race_id;
647 	newsPtr->short_para2 = unitPtr->name_id;
648 	newsPtr->short_para3 = unitPtr->rank_id;
649 	newsPtr->short_para4 = spyKilled;
650 
651 	//------- set location --------//
652 
653 	short xLoc, yLoc;
654 
655 	unitPtr->get_cur_loc(xLoc, yLoc);
656 
657 	newsPtr->set_loc( xLoc, yLoc, NEWS_LOC_ANY );
658 }
659 //------- End of function NewsArray::unit_assassinated -----//
660 
661 
662 //------ Begin of function NewsArray::assassinator_caught -----//
663 //
664 // <int> spyRecno 	 - spy recno of the assassinator.
665 // <int> targetRankId - the rank id. of the assassinating target
666 //
667 // short_para1 - rank id. of the assassinating target.
668 //
assassinator_caught(int spyRecno,int targetRankId)669 void NewsArray::assassinator_caught(int spyRecno, int targetRankId)
670 {
671 	News* newsPtr = add_news( NEWS_ASSASSINATOR_CAUGHT, NEWS_NORMAL );
672 
673 	if( !newsPtr )		// only news of nations that have contact with the player are added
674 		return;
675 
676 	newsPtr->short_para1 = targetRankId;
677 
678 	//------- set location --------//
679 
680 	int xLoc, yLoc;
681 
682 	spy_array[spyRecno]->get_loc(xLoc, yLoc);
683 
684 	newsPtr->set_loc( xLoc, yLoc, NEWS_LOC_ANY );
685 }
686 //------- End of function NewsArray::assassinator_caught -----//
687 
688 
689 //------ Begin of function NewsArray::general_die -----//
690 //
691 // <int> unitRecno - recno of the unit.
692 //
693 // short_para1 - race id. of your general
694 // short_para2 - name id. of your general
695 //
general_die(int unitRecno)696 void NewsArray::general_die(int unitRecno)
697 {
698 	Unit* unitPtr = unit_array[unitRecno];
699 
700 	err_when( unitPtr->nation_recno != nation_array.player_recno );
701 
702 	News* newsPtr = add_news( NEWS_GENERAL_DIE, NEWS_NORMAL, unitPtr->nation_recno );
703 
704 	if( !newsPtr )		// only news of nations that have contact with the player are added
705 		return;
706 
707 	newsPtr->short_para1 = unitPtr->race_id;
708 	newsPtr->short_para2 = unitPtr->name_id;
709 
710 	//------- set location --------//
711 
712 	newsPtr->set_loc( unitPtr->next_x_loc(), unitPtr->next_y_loc(), NEWS_LOC_ANY );
713 }
714 //------- End of function NewsArray::general_die -----//
715 
716 
717 //------ Begin of function NewsArray::raw_exhaust -----//
718 //
719 // short_para1 - raw id.
720 //
raw_exhaust(int rawId,int xLoc,int yLoc)721 void NewsArray::raw_exhaust(int rawId, int xLoc, int yLoc)
722 {
723 	News* newsPtr = add_news( NEWS_RAW_EXHAUST, NEWS_NORMAL );
724 
725 	if( !newsPtr )		// only news of nations that have contact with the player are added
726 		return;
727 
728 	newsPtr->short_para1 = rawId;
729 
730 	//------- set location --------//
731 
732 	newsPtr->set_loc( xLoc, yLoc, NEWS_LOC_ANY );
733 }
734 //------- End of function NewsArray::raw_exhaust -----//
735 
736 
737 //------ Begin of function NewsArray::tech_researched -----//
738 //
739 // short_para1 - tech id.
740 // short_para2 - tech version.
741 //
tech_researched(int techId,int techVersion)742 void NewsArray::tech_researched(int techId, int techVersion)
743 {
744 	News* newsPtr = add_news( NEWS_TECH_RESEARCHED, NEWS_NORMAL, nation_array.player_recno );
745 
746 	if( !newsPtr )		// only news of nations that have contact with the player are added
747 		return;
748 
749 	newsPtr->short_para1 = techId;
750 	newsPtr->short_para2 = techVersion;
751 }
752 //------- End of function NewsArray::tech_researched -----//
753 
754 
755 //------ Begin of function NewsArray::lightning_damage -----//
756 //
lightning_damage(int xLoc,int yLoc,int objectId,int recno,int objectDie)757 void NewsArray::lightning_damage(int xLoc, int yLoc, int objectId, int recno, int objectDie)
758 {
759 	News* newsPtr = add_news( NEWS_LIGHTNING_DAMAGE, NEWS_NORMAL );
760 
761 	if( !newsPtr )
762 		return;
763 
764 	newsPtr->set_loc( xLoc, yLoc, objectId, recno);
765 
766 	newsPtr->short_para1 = objectId;
767 	newsPtr->short_para2 = 0;
768 	newsPtr->short_para3 = 0;
769 	newsPtr->short_para4 = 0;
770 	switch( objectId )
771 	{
772 	case NEWS_LOC_UNIT:
773 		newsPtr->short_para4 = unit_array[recno]->rank_id;
774 		if( (newsPtr->short_para2 = unit_array[recno]->race_id) > 0)
775 			newsPtr->short_para3 = (short) unit_array[recno]->name_id;
776 		else
777 			newsPtr->short_para3 = unit_array[recno]->unit_id;
778 		break;
779 	case NEWS_LOC_FIRM:
780 		newsPtr->short_para2 = firm_array[recno]->firm_id;
781 		newsPtr->short_para3 = firm_array[recno]->closest_town_name_id;
782 		break;
783 	case NEWS_LOC_TOWN:
784 		newsPtr->short_para3 = town_array[recno]->town_name_id;
785 		break;
786 	default:
787 		err_here();
788 	}
789 	newsPtr->short_para5 = objectDie;
790 }
791 //------- End of function NewsArray::lightning_damage -----//
792 
793 
794 //------ Begin of function NewsArray::earthquake_damage -----//
795 //
earthquake_damage(int unitDamage,int unitDie,int townDamage,int firmDamage,int firmDie)796 void NewsArray::earthquake_damage(int unitDamage, int unitDie, int townDamage, int firmDamage, int firmDie)
797 {
798 	News* newsPtr;
799 	// ######## begin Gilbert 12/9 #######//
800 	if( unitDamage > 0 || unitDie > 0)
801 	{
802 		newsPtr = add_news( NEWS_EARTHQUAKE_DAMAGE, NEWS_NORMAL );
803 		if( newsPtr )
804 		{
805 			newsPtr->short_para1 = 1;
806 			newsPtr->short_para2 = unitDamage;
807 			newsPtr->short_para3 = unitDie;
808 		}
809 	}
810 	if( townDamage > 0)
811 	{
812 		newsPtr = add_news( NEWS_EARTHQUAKE_DAMAGE, NEWS_NORMAL );
813 		if( newsPtr )
814 		{
815 			newsPtr->short_para1 = 2;
816 			newsPtr->short_para2 = townDamage;
817 		}
818 	}
819 	if( firmDamage > 0 || firmDie > 0)
820 	{
821 		newsPtr = add_news( NEWS_EARTHQUAKE_DAMAGE, NEWS_NORMAL );
822 		if( newsPtr )
823 		{
824 			newsPtr->short_para1 = 3;
825 			newsPtr->short_para2 = firmDamage;
826 			newsPtr->short_para3 = firmDie;
827 		}
828 	}
829 	// ######## end Gilbert 12/9 #######//
830 }
831 //------- End of function NewsArray::earthquake_damage -----//
832 
833 
834 //------ Begin of function NewsArray::goal_deadline -----//
835 //
836 // Display a warning message as the deadline of the goals approaches.
837 //
838 // short_para1 - years left before the deadline.
839 // short_para2 - months left before the deadline.
840 //
goal_deadline(int yearLeft,int monthLeft)841 void NewsArray::goal_deadline(int yearLeft, int monthLeft)
842 {
843 	News* newsPtr = add_news( NEWS_GOAL_DEADLINE, NEWS_NORMAL, nation_array.player_recno );
844 
845 	if( !newsPtr )		// only news of nations that have contact with the player are added
846 		return;
847 
848 	newsPtr->short_para1 = yearLeft;
849 	newsPtr->short_para2 = monthLeft;
850 }
851 //------- End of function NewsArray::goal_deadline -----//
852 
853 
854 //------ Begin of function NewsArray::weapon_ship_worn_out -----//
855 //
856 // Your weapon worn out and destroyed due to lack of money for
857 // maintenance.
858 //
859 // short_para1 - unit id. of the weapon
860 // short_para2 - level of the weapon
861 //
weapon_ship_worn_out(int unitId,int weaponLevel)862 void NewsArray::weapon_ship_worn_out(int unitId, int weaponLevel)
863 {
864 	err_when( unit_res[unitId]->unit_class != UNIT_CLASS_WEAPON &&
865 				 unit_res[unitId]->unit_class != UNIT_CLASS_SHIP );
866 
867 	News* newsPtr = add_news( NEWS_WEAPON_SHIP_WORN_OUT, NEWS_NORMAL, nation_array.player_recno );
868 
869 	if( !newsPtr )		// only news of nations that have contact with the player are added
870 		return;
871 
872 	newsPtr->short_para1 = unitId;
873 	newsPtr->short_para2 = weaponLevel;
874 }
875 //------- End of function NewsArray::weapon_ship_worn_out -----//
876 
877 
878 //------ Begin of function NewsArray::firm_worn_out -----//
879 //
880 // <int> firmRecno - recno of the firm destroyed.
881 //
882 // short_para1 - id. of the firm destroyed.
883 // short_para2 - name id of the town where the firm is located.
884 //
firm_worn_out(int firmRecno)885 void NewsArray::firm_worn_out(int firmRecno)
886 {
887 	Firm* firmPtr = firm_array[firmRecno];
888 
889 	err_when( firmPtr->nation_recno != nation_array.player_recno );
890 
891 	News* newsPtr = add_news( NEWS_FIRM_WORN_OUT, NEWS_NORMAL, firmPtr->nation_recno);
892 
893 	if( !newsPtr )		// only news of nations that have contact with the player are added
894 		return;
895 
896 	newsPtr->short_para1 = firmPtr->firm_id;
897 
898 	if( firmPtr->closest_town_name_id )
899 		newsPtr->short_para2 = firmPtr->closest_town_name_id;
900 	else
901 		newsPtr->short_para2 = firmPtr->get_closest_town_name_id();
902 }
903 //------- End of function NewsArray::firm_worn_out -----//
904 
905 
906 //------ Begin of function NewsArray::chat_msg -----//
907 //
908 // <int>   fromNationRecno - recno of the nation from which this chat message is sent.
909 // <char*> chatStr     	   - pointer to the chat string.
910 //
911 // short_para1 - id. of the chat msg in Info::remote_chat_str_array[]
912 //
913 // nation_name1() - the nation from which this chat message is sent.
914 //
chat_msg(int fromNationRecno,char * chatStr)915 void NewsArray::chat_msg(int fromNationRecno, char* chatStr)
916 {
917 	//---- add the chat string into Info::remote_chat_str_array[] ----//
918 
919 	int useChatId=0;
920 	int minDate=info.game_date+1;
921 
922 	for( int i=0; i<MAX_REMOTE_CHAT_STR ; i++ )
923 	{
924 		if( info.remote_chat_array[i].received_date < minDate )	 // replace the oldest one
925 		{
926 			minDate	 = info.remote_chat_array[i].received_date;
927 			useChatId = i+1;
928 		}
929 	}
930 
931 	if( useChatId )
932 	{
933 		ChatInfo* chatInfo = info.remote_chat_array+useChatId-1;
934 
935 		chatInfo->received_date = info.game_date;
936 		chatInfo->from_nation_recno = fromNationRecno;
937 
938 		strncpy( chatInfo->chat_str, chatStr, CHAT_STR_LEN );
939 		chatInfo->chat_str[CHAT_STR_LEN] = '\0';
940 	}
941 
942 	//----------------------------------------------//
943 
944 	News* newsPtr = add_news( NEWS_CHAT_MSG, NEWS_NORMAL, fromNationRecno);
945 
946 	if( !newsPtr )		// only news of nations that have contact with the player are added
947 		return;
948 
949 	newsPtr->short_para1 = useChatId;
950 }
951 //------- End of function NewsArray::chat_msg -----//
952 
953 
954 //------ Begin of function NewsArray::multi_retire -----//
955 //
956 // This function is called when a human player retires.
957 //
multi_retire(int nationRecno)958 void NewsArray::multi_retire(int nationRecno)
959 {
960 	add_news( NEWS_MULTI_RETIRE, NEWS_NORMAL, nationRecno, nation_array.player_recno, 1 );		// add player recno as the 2nd parameter so this message is always displayed even if the player doesn't yet have contact with this nation
961 }
962 //------- End of function NewsArray::multi_retire -----//
963 
964 
965 //------ Begin of function NewsArray::multi_quit_game -----//
966 //
967 // This function is called when a human player quits the game.
968 //
multi_quit_game(int nationRecno)969 void NewsArray::multi_quit_game(int nationRecno)
970 {
971 	add_news( NEWS_MULTI_QUIT_GAME, NEWS_NORMAL, nationRecno, nation_array.player_recno, 1 );		// add player recno as the 2nd parameter so this message is always displayed even if the player doesn't yet have contact with this nation
972 }
973 //------- End of function NewsArray::multi_quit_game -----//
974 
975 
976 //------ Begin of function NewsArray::multi_save_game -----//
977 //
978 // This function is called when a human player calls for saving the game.
979 //
multi_save_game()980 void NewsArray::multi_save_game()
981 {
982 	add_news( NEWS_MULTI_SAVE_GAME, NEWS_NORMAL );
983 }
984 //------- End of function NewsArray::multi_save_game -----//
985 
986 
987 //------ Begin of function NewsArray::multi_connection_lost -----//
988 //
989 // This function is called when a human player's connection has been lost.
990 //
multi_connection_lost(int nationRecno)991 void NewsArray::multi_connection_lost(int nationRecno)
992 {
993 	add_news( NEWS_MULTI_CONNECTION_LOST, NEWS_NORMAL, nationRecno, nation_array.player_recno, 1 );		// add player recno as the 2nd parameter so this message is always displayed even if the player doesn't yet have contact with this nation
994 }
995 //------- End of function NewsArray::multi_connection_lost -----//
996 
997 
998 //------ Begin of function NewsArray::add_news -----//
999 //
1000 // Called by news processing function to set news parameters
1001 //
1002 // <int> newsId       = the id. of the news
1003 // <int> newsType     = news type
1004 // [int] nationRecno  = nation recno of the news
1005 // [int] nationRecno2 = recno of the 2nd nation related to the news
1006 // [int] forceAdd		 = add this news anyway, regardless of whether
1007 //								the nation has contact with the player or not
1008 //                      (default: 0)
1009 //
1010 // return : <News*> return the pointer of the News
1011 //						  NULL - the nation of the news does not have contact with the player
1012 //
add_news(int newsId,int newsType,int nationRecno,int nationRecno2,int forceAdd)1013 News* NewsArray::add_news(int newsId, int newsType, int nationRecno, int nationRecno2, int forceAdd)
1014 {
1015 	if( nation_array.player_recno==0 )		// if the player has lost
1016 		return NULL;
1017 
1018 	//----- only news of nations that have contact with the player are added ----//
1019 
1020 	if( nation_array.player_recno && !forceAdd )
1021 	{
1022 		Nation* playerNation = ~nation_array;
1023 
1024 		if( nationRecno && nationRecno != nation_array.player_recno )
1025 		{
1026 			if( !playerNation->get_relation(nationRecno)->has_contact )
1027 				return NULL;
1028 		}
1029 
1030 		if( nationRecno2 && nationRecno2 != nation_array.player_recno )
1031 		{
1032 			if( !playerNation->get_relation(nationRecno2)->has_contact )
1033 				return NULL;
1034 		}
1035 	}
1036 
1037 	//----------------------------------------------//
1038 
1039 	static News news;
1040 
1041 	news.id   = newsId;
1042 	news.type = newsType;
1043 	news.news_date = info.game_date;
1044 	news.loc_type = 0;
1045 
1046 	Nation* nationPtr;
1047 
1048 	if( nationRecno )
1049 	{
1050 		nationPtr = nation_array[nationRecno];
1051 
1052 		news.nation_name_id1 = nationPtr->nation_name_id;
1053 		news.nation_race_id1 = (char) nationPtr->race_id;
1054 		news.nation_color1   = nationPtr->color_scheme_id;
1055 
1056 		err_when( !news.nation_name_id1 || !news.nation_race_id1 );
1057 	}
1058 	else
1059 	{
1060 		news.nation_name_id1 = 0;
1061 		news.nation_color1   = -1;
1062 	}
1063 
1064 	if( nationRecno2 )
1065 	{
1066 		nationPtr = nation_array[nationRecno2];
1067 
1068 		news.nation_name_id2 = nationPtr->nation_name_id;
1069 		news.nation_race_id2 = (char) nationPtr->race_id;
1070 		news.nation_color2   = nationPtr->color_scheme_id;
1071 	}
1072 	else
1073 	{
1074 		news.nation_name_id2 = 0;
1075 		news.nation_color2   = -1;
1076 	}
1077 
1078 	//--- if the news adding flag is turned off, don't add the news ---//
1079 
1080 	if( news_add_flag )
1081 	{
1082 		//--- if no. of news reaches MAX., delete the oldest one ---//
1083 
1084 		if( size() >= MAX_NEWS )
1085 		{
1086 			start();
1087 			linkout();
1088 
1089 			if( last_clear_recno > 0 )
1090 				last_clear_recno--;
1091 		}
1092 
1093 		//--------- link in a new news ---------//
1094 
1095 		linkin(&news);
1096 
1097 		return (News*) get();
1098 	}
1099 	else
1100 	{
1101 		return &news;
1102 	}
1103 }
1104 //------- End of function NewsArray::add_news -----//
1105 
1106 
1107 //------ Begin of function News::set_loc ------//
1108 //
set_loc(int xLoc,int yLoc,int locType,int locTypePara,int locTypePara2)1109 void News::set_loc(int xLoc, int yLoc, int locType, int locTypePara, int locTypePara2)
1110 {
1111 	loc_type 	   = locType;
1112 	loc_type_para  = locTypePara;
1113 	loc_type_para2 = locTypePara2;
1114 
1115 	err_when( loc_type_para < 0 );
1116 	err_when( locTypePara2 < 0 );
1117 
1118 	loc_x = xLoc;
1119 	loc_y = yLoc;
1120 }
1121 //------- End of function News::set_loc -------//
1122 
1123 
1124 //------ Begin of function News::is_loc_valid ------//
1125 //
1126 // Whether the location of this news is still valid.
1127 //
is_loc_valid()1128 int News::is_loc_valid()
1129 {
1130 	if( !loc_type )
1131 		return 0;
1132 
1133 	int rc=0;
1134 
1135 	if( loc_type == NEWS_LOC_TOWN )
1136 	{
1137 		if( !town_array.is_deleted(loc_type_para) )
1138 		{
1139 			Town* townPtr = town_array[loc_type_para];
1140 
1141 			rc = townPtr->center_x == loc_x &&
1142 				  townPtr->center_y == loc_y;
1143 		}
1144 	}
1145 	else if( loc_type == NEWS_LOC_FIRM )
1146 	{
1147 		if( !firm_array.is_deleted(loc_type_para) )
1148 		{
1149 			Firm* firmPtr = firm_array[loc_type_para];
1150 
1151 			rc = firmPtr->center_x == loc_x &&
1152 				  firmPtr->center_y == loc_y;
1153 		}
1154 	}
1155 	else if( loc_type == NEWS_LOC_UNIT )
1156 	{
1157 		if( !unit_array.is_deleted(loc_type_para) )
1158 		{
1159 			Unit* unitPtr = unit_array[loc_type_para];
1160 
1161 			if( unitPtr->name_id == loc_type_para2 )
1162 			{
1163 				//--- if the unit is no longer belong to our nation ----//
1164 				//--- only keep track of the unit for one month --------//
1165 
1166 				if( unitPtr->nation_recno == nation_array.player_recno ||
1167 					 info.game_date < news_date + 30 )
1168 				{
1169 					if( unitPtr->get_cur_loc(loc_x, loc_y) )
1170 					{
1171 						Location* locPtr = world.get_loc(loc_x, loc_y);
1172 
1173 						rc = locPtr->visit_level > 0;
1174 					}
1175 				}
1176 			}
1177 		}
1178 	}
1179 	else if( loc_type == NEWS_LOC_ANY )
1180 	{
1181 		rc = 1;
1182 	}
1183 
1184 	if( !rc )
1185 		loc_type = 0;
1186 
1187 	return rc;
1188 }
1189 //------- End of function News::is_loc_valid -------//
1190 
1191 
1192