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 //cFilename    : OTOWN.CPP
22 //Description : Object Town
23 
24 #include <string.h>
25 #include <ALL.h>
26 #include <OVGA.h>
27 #include <OWORLD.h>
28 #include <OSYS.h>
29 #include <OIMGRES.h>
30 #include <ONEWS.h>
31 #include <OCONFIG.h>
32 #include <OFONT.h>
33 #include <OINFO.h>
34 #include <OPLANT.h>
35 #include <ODATE.h>
36 #include <OSPY.h>
37 #include <OCONFIG.h>
38 #include <OF_MARK.h>
39 #include <OF_CAMP.h>
40 #include <OUNIT.h>
41 #include <OTERRAIN.h>
42 #include <OREBEL.h>
43 #include <OSPRTRES.h>
44 #include <ORACERES.h>
45 #include <ONATION.h>
46 #include <OREMOTE.h>
47 #include <OTOWN.h>
48 #include <OTownNetwork.h>
49 #include <ONEWS.h>
50 #include <OANLINE.h>
51 // ##### begin Gilbert 9/10 ######//
52 #include <OSE.h>
53 // ##### end Gilbert 9/10 ######//
54 #include <OSERES.h>
55 #include <OLOG.h>
56 #include <ConfigAdv.h>
57 
58 static char random_race();
59 
60 
61 //--------- Begin of function Town::Town ----------//
62 //
Town()63 Town::Town()
64 {
65 	memset( this, 0, sizeof(Town) );
66 }
67 //---------- End of function Town::Town ----------//
68 
69 
70 //--------- Begin of function Town::init ----------//
71 //
72 // <int> nationRecno - the nation recno
73 // <int> raceId 	   - the race of the majority of the town poulation
74 // <int> xLoc, yLoc  - location of the town
75 //
init(int nationRecno,int raceId,int xLoc,int yLoc)76 void Town::init(int nationRecno, int raceId, int xLoc, int yLoc)
77 {
78 	nation_recno = nationRecno;
79 	race_id		 = raceId;
80 
81 	err_when( raceId<1 || raceId>MAX_RACE );
82 
83 	//---- set the town section's absolute positions on the map ----//
84 
85 	loc_x1 = xLoc;
86 	loc_y1 = yLoc;
87 	loc_x2 = loc_x1 + STD_TOWN_LOC_WIDTH - 1;
88 	loc_y2 = loc_y1 + STD_TOWN_LOC_HEIGHT - 1;
89 
90 	abs_x1 = xLoc * ZOOM_LOC_WIDTH;
91 	abs_y1 = yLoc * ZOOM_LOC_HEIGHT;
92 	abs_x2 = abs_x1 + STD_TOWN_LOC_WIDTH * ZOOM_LOC_WIDTH  - 1;
93 	abs_y2 = abs_y1 + STD_TOWN_LOC_HEIGHT * ZOOM_LOC_HEIGHT - 1;
94 
95 	center_x = (loc_x1+loc_x2)/2;
96 	center_y = (loc_y1+loc_y2)/2;
97 
98 	region_id = world.get_region_id( center_x, center_y );
99 
100 	ai_town = !nation_recno || nation_array[nation_recno]->nation_type == NATION_AI;    // nation_recno==0 for independent towns
101 	ai_link_checked = 1;			// check the linked towns and firms connected only if ai_link_checked==0
102 
103 	independent_unit_join_nation_min_rating = 100 + misc.random(150);		// the minimum rating a nation must have in order for an independent unit to join it
104 
105 	setup_date = info.game_date;
106 
107 	//-------- init resistance ------------//
108 
109 	if( nationRecno==0 )
110 	{
111 		for( int i=0 ; i<MAX_RACE ; i++ )
112 		{
113 			for( int j=0 ; j<MAX_NATION ; j++ )
114 			{
115 				race_resistance_array[i][j] = (float) 60 + misc.random(40);
116 				race_target_resistance_array[i][j] = -1;
117 			}
118 		}
119 
120 		//--- some independent towns have higher than normal combat level for its defender ---//
121 
122 		switch( config.independent_town_resistance )
123 		{
124 			case OPTION_LOW:
125 				town_combat_level = CITIZEN_COMBAT_LEVEL;
126 				break;
127 
128 			case OPTION_MODERATE:
129 				town_combat_level = 10 + misc.random(20);
130 				break;
131 
132 			case OPTION_HIGH:
133 				town_combat_level = 10 + misc.random(30);
134 				if( misc.random(5)==0 )
135 					town_combat_level += misc.random(30);
136 				break;
137 
138 			default:
139 				err_here();
140 		}
141 	}
142 
143 	//-------------------------------------//
144 
145 	town_name_id = town_res.get_new_name_id(raceId);
146 
147 	set_world_matrix();
148 
149 	setup_link();
150 
151 	//-------- if this is an AI town ------//
152 
153 	if( ai_town && nation_recno )
154 	{
155 		nation_array[nation_recno]->add_town_info(town_recno);
156 
157 		update_base_town_status();
158 	}
159 
160 	//------ set national auto policy -----//
161 
162 	if( nation_recno )
163 	{
164 		Nation* nationPtr = nation_array[nation_recno];
165 
166 		set_auto_collect_tax_loyalty( nationPtr->auto_collect_tax_loyalty );
167 		set_auto_grant_loyalty( nationPtr->auto_grant_loyalty );
168 	}
169 
170 	//--------- setup town network ---------//
171 
172 	town_network_pulsed = false;
173 	town_network_recno = town_network_array.town_created(town_recno, nation_recno, linked_town_array, linked_town_count);
174 }
175 //--------- End of function Town::init ----------//
176 
177 
178 //--------- Begin of function Town::deinit ----------//
179 //
deinit()180 void Town::deinit()
181 {
182 	if( !town_recno )
183 		return;
184 
185 	//--------- remove from town network ---------//
186 
187 	town_network_array.town_destroyed(town_recno);
188 
189 
190 	clear_defense_mode();
191 
192 	//------- if it's an AI town --------//
193 
194 	if( ai_town && nation_recno )
195 		nation_array[nation_recno]->del_town_info(town_recno);
196 
197 	//------ if this town is the nation's larget town, reset it ----//
198 
199 	if( nation_recno &&
200 		 nation_array[nation_recno]->largest_town_recno == town_recno )
201 	{
202 		nation_array[nation_recno]->largest_town_recno = 0;
203 	}
204 
205 	//-----------------------------------//
206 
207 	restore_world_matrix();
208 
209 	release_link();
210 
211 	//-- if there is a unit being trained when the town vanishes --//
212 
213 	if(train_unit_recno)
214 		unit_array.disappear_in_town(train_unit_recno, town_recno);
215 
216 	//------- if the current town is the selected -----//
217 
218 	if( town_array.selected_recno == town_recno )
219 	{
220 		town_array.selected_recno = 0;
221 		info.disp();
222 	}
223 
224 	//------- reset parameters ---------//
225 
226 	town_recno = 0;
227 	town_network_recno = 0;
228 }
229 //--------- End of function Town::deinit ----------//
230 
231 
232 //------- Begin of function Town::set_world_matrix --------//
233 //
234 // Set the cargo id of current town section on the world matrix
235 //
set_world_matrix()236 void Town::set_world_matrix()
237 {
238 	//--- if a nation set up a town in a location that the player has explored, contact between the nation and the player is established ---//
239 
240 	int xLoc, yLoc;
241 	Location* locPtr;
242 
243 	for( yLoc=loc_y1 ; yLoc<=loc_y2 ; yLoc++ )
244 	{
245 		for( xLoc=loc_x1 ; xLoc<=loc_x2 ; xLoc++ )
246 		{
247 			locPtr = world.get_loc(xLoc, yLoc);
248 
249 			if(!locPtr->cargo_recno)	// skip the location where the settle unit is standing
250 				locPtr->set_town(town_recno);
251 		}
252 	}
253 
254 	//--- if a nation set up a town in a location that the player has explored, contact between the nation and the player is established ---//
255 
256 	establish_contact_with_player();
257 
258 	//---- set this town's influence on the map ----//
259 
260 	if( nation_recno )
261 		world.set_power(loc_x1, loc_y1, loc_x2, loc_y2, nation_recno);
262 
263 	//------------ reveal new land ----------//
264 
265 	if( nation_recno == nation_array.player_recno ||
266 		 ( nation_recno && nation_array[nation_recno]->is_allied_with_player ) )
267 	{
268 		world.unveil( loc_x1, loc_y1, loc_x2, loc_y2 );
269 		world.visit( loc_x1, loc_y1, loc_x2, loc_y2, EXPLORE_RANGE-1 );
270 	}
271 
272 	//---- if the newly built firm is visual in the zoom window, redraw the zoom buffer ----//
273 
274 	if( is_in_zoom_win() )
275 		sys.zoom_need_redraw = 1;  // set the flag on so it will be redrawn in the next frame
276 }
277 //-------- End of function Town::set_world_matrix --------//
278 
279 
280 //------- Begin of function Town::establish_contact_with_player --------//
281 //
282 // See if the town's location is an explored area, establish contact
283 // with the player.
284 //
establish_contact_with_player()285 void Town::establish_contact_with_player()
286 {
287 	if( !nation_recno )
288 		return;
289 
290 	//--- if a nation set up a town in a location that the player has explored, contact between the nation and the player is established ---//
291 
292 	int xLoc, yLoc;
293 	Location* locPtr;
294 
295 	for( yLoc=loc_y1 ; yLoc<=loc_y2 ; yLoc++ )
296 	{
297 		for( xLoc=loc_x1 ; xLoc<=loc_x2 ; xLoc++ )
298 		{
299 			locPtr = world.get_loc(xLoc, yLoc);
300 
301 			if( locPtr->explored() && nation_array.player_recno )
302 			{
303 				NationRelation *relation = (~nation_array)->get_relation(nation_recno);
304 
305 				if( !remote.is_enable() )
306 				{
307 					relation->has_contact = 1;
308 				}
309 				else
310 				{
311 					if( !relation->contact_msg_flag && !relation->has_contact )
312 					{
313 						// packet structure : <player nation> <explored nation>
314 						short *shortPtr = (short *)remote.new_send_queue_msg(MSG_NATION_CONTACT, 2*sizeof(short));
315 						*shortPtr = nation_array.player_recno;
316 						shortPtr[1] = nation_recno;
317 						relation->contact_msg_flag = 1;
318 					}
319 				}
320 			}
321 		}
322 	}
323 }
324 //-------- End of function Town::establish_contact_with_player --------//
325 
326 
327 //--------- Begin of function Town::restore_world_matrix --------//
328 //
329 // When the town section is destroyed, restore the original land id
330 //
restore_world_matrix()331 void Town::restore_world_matrix()
332 {
333 	int xLoc, yLoc;
334 
335 	for( yLoc=loc_y1 ; yLoc<=loc_y2 ; yLoc++ )
336 	{
337 		for( xLoc=loc_x1 ; xLoc<=loc_x2 ; xLoc++ )
338       {
339 			world.get_loc(xLoc,yLoc)->remove_town();
340 		}
341 	}
342 
343 	//---- restore this town's influence on the map ----//
344 
345 	if( nation_recno )
346 		world.restore_power(loc_x1, loc_y1, loc_x2, loc_y2, town_recno, 0);
347 
348 	//---- if the newly built firm is visual in the zoom window, redraw the zoom buffer ----//
349 
350 	if( is_in_zoom_win() )
351 		sys.zoom_need_redraw = 1;
352 }
353 //----------- End of function Town::restore_world_matrix --------//
354 
355 
356 //---------- Begin of function Town::next_day --------//
357 //
next_day()358 void Town::next_day()
359 {
360 	err_when( population>MAX_TOWN_POPULATION );
361 	err_when( town_recno<1 );
362 	err_when( town_recno>town_array.size() );
363 
364 	int townRecno = town_recno;
365 
366 	//------ update quality_of_life --------//
367 
368 	update_quality_of_life();
369 
370 	//---------- update population ----------//
371 
372 #if defined(DEBUG) && defined(ENABLE_LOG)
373 	String logStr;
374 	logStr = "begin Town::next_day, town_recno = ";
375 	logStr += townRecno;
376 	logStr += " nation=";
377 	logStr += nation_recno;
378 	LOG_MSG(logStr);
379 #endif
380 
381 	if( info.game_date%30 == town_recno%30 )
382 	{
383 		LOG_MSG(" population_grow");
384 		population_grow();
385 		LOG_MSG(misc.get_random_seed());
386 	}
387 
388 	err_when(population>MAX_TOWN_POPULATION);
389 
390 	//------- update link status to camps ------//
391 
392 	LOG_MSG(" update_camp_link");
393 	update_camp_link();
394 	LOG_MSG(misc.get_random_seed());
395 
396 	//------ update target loyalty/resistance -------//
397 
398 	if( info.game_date%15 == town_recno%15 )
399 	{
400 		if( nation_recno )
401 		{
402 			LOG_MSG(" update_target_loyalty");
403 			update_target_loyalty();
404 		}
405 		else
406 		{
407 			LOG_MSG(" update_target_resistance");
408 			update_target_resistance();		// update resistance for independent towns
409 		}
410 		LOG_MSG(misc.get_random_seed());
411 	}
412 
413 	//------ update loyalty/resistance -------//
414 
415 	if( info.game_date%5 == town_recno%5 )
416 	{
417 		if( nation_recno )
418 		{
419 			LOG_MSG(" update_target_loyalty");
420 			update_loyalty();
421 		}
422 		else
423 		{
424 			LOG_MSG(" update_target_resistance");
425 			update_resistance();
426 		}
427 		LOG_MSG(misc.get_random_seed());
428 
429 		if( town_array.is_deleted(townRecno) )
430 			return;
431 	}
432 
433 	//------ think town people migration -------//
434 
435 	LOG_MSG(" think_migrate");
436 	think_migrate();
437 	LOG_MSG(misc.get_random_seed());
438 
439 	if( town_array.is_deleted(townRecno) )
440 		return;
441 
442 	//-------- think about rebel -----//
443 
444 	if( nation_recno && info.game_date%15 == town_recno%15 )
445 	{
446 		LOG_MSG(" think_rebel");
447 		think_rebel();
448 		LOG_MSG(misc.get_random_seed() );
449 
450 		if( town_array.is_deleted(townRecno) )
451 			return;
452 	}
453 
454 	//-------- think about surrender -----//
455 
456 	if( nation_recno &&
457 		 ( info.game_date%15==town_recno%15 || average_loyalty()==0 ) )
458 	{
459 		LOG_MSG(" think_surrender");
460 		think_surrender();		// for nation town only, independent town surrender is handled in update_resistance()
461 		LOG_MSG(misc.get_random_seed() );
462 
463 		if( town_array.is_deleted(townRecno) )
464 			return;
465 	}
466 
467 	//------- process training -------//
468 
469 	//### begin alex 6/9 ###//
470 	/*if( nation_recno && train_unit_recno )
471 	{
472 		process_train();
473 
474 		if( town_array.is_deleted(townRecno) )	// when the last peasant in the town is trained, the town disappear
475 			return;
476 	}*/
477 	if(nation_recno)
478 	{
479 		if(train_unit_recno)
480 		{
481 			LOG_MSG(" process_train");
482 			process_train();
483 			LOG_MSG(misc.get_random_seed() );
484 		}
485 		else
486 		{
487 			LOG_MSG(" process_queue");
488 			process_queue();
489 			LOG_MSG(misc.get_random_seed() );
490 		}
491 
492 		if( town_array.is_deleted(townRecno) )	// when the last peasant in the town is trained, the town disappear
493 			return;
494 	}
495 	//#### end alex 6/9 ####//
496 
497 	//-------- process food ---------//
498 
499 	if( nation_recno )
500 	{
501 		LOG_MSG(" process_food");
502 		process_food();
503 		LOG_MSG(misc.get_random_seed());
504 
505 		if( town_array.is_deleted(townRecno) )
506 			return;
507 	}
508 
509 	//------ auto collect tax and auto grant -------//
510 
511 	if( nation_recno )
512 	{
513 		LOG_MSG(" process_auto");
514 		process_auto();
515 		LOG_MSG(misc.get_random_seed() );
516 
517 		if( town_array.is_deleted(townRecno) )
518 			return;
519 	}
520 
521 	//------ collect yearly tax -------//
522 
523 	if( nation_recno && info.game_month==1 && info.game_day==1 )
524 	{
525 		collect_yearly_tax();
526 	}
527 
528 	//------ catching spies -------//
529 
530 	LOG_MSG(" process_auto");
531 
532 	if( info.game_date%30 == town_recno%30 )
533 		spy_array.catch_spy(SPY_TOWN, town_recno);
534 
535 	LOG_MSG(misc.get_random_seed() );
536 
537 	if( town_array.is_deleted(townRecno) )
538 		return;
539 
540 	//-------- update visibility ---------//
541 
542 	if( nation_recno == nation_array.player_recno ||
543 		 (nation_recno && nation_array[nation_recno]->is_allied_with_player) )
544 	{
545 		world.visit( loc_x1, loc_y1, loc_x2, loc_y2, EXPLORE_RANGE-1 );
546 	}
547 
548 	//--- recheck no_neighbor_space after a period, there may be new space available now ---//
549 
550 	if( no_neighbor_space && info.game_date%180 == town_recno%180 )
551 	{
552 		LOG_MSG("begin finding neighor space");
553 		short buildXLoc, buildYLoc;
554 
555 		//--- for independent town, since we can't call find_best_firm_loc(), we just set no_neighbor_space to 0 every 6 months, if it still has no space, then no_neighbor_space will be set 1 again. ---//
556 
557 		if( nation_recno==0 || nation_array[nation_recno]->find_best_firm_loc(FIRM_INN, loc_x1, loc_y1, buildXLoc, buildYLoc) )		// whether it's FIRM_INN or not really doesn't matter, just any firm type will do
558 			no_neighbor_space = 0;
559 
560 		LOG_MSG(misc.get_random_seed());
561 	}
562 
563 	//------ decrease penalties -----//
564 
565 	if( accumulated_collect_tax_penalty > 0 )
566 		accumulated_collect_tax_penalty--;
567 
568 	if( accumulated_reward_penalty > 0 )
569 		accumulated_reward_penalty--;
570 
571 	if( accumulated_recruit_penalty > 0 )
572 		accumulated_recruit_penalty--;
573 
574 	if( accumulated_enemy_grant_penalty > 0 )
575 		accumulated_enemy_grant_penalty--;
576 
577 	//------------------------------------------------------------//
578 	// check for population for each town
579 	//------------------------------------------------------------//
580 
581    //err_when( town_array.is_deleted(townRecno) );
582 	if( town_array.is_deleted(townRecno) )
583 		return;
584 
585 #ifdef DEBUG
586 	Firm	*firmPtr;
587 	int	i, j;
588 	short	pop[MAX_RACE];
589 
590 	memset(pop, 0, sizeof(short)*MAX_RACE);
591 	for(i=linked_firm_count-1; i>=0; i--)
592 	{
593 		err_when(!linked_firm_array[i] || firm_array.is_deleted(linked_firm_array[i]));
594 		firmPtr = firm_array[linked_firm_array[i]];
595 
596 		if(firmPtr->overseer_recno)
597 		{
598 			if(firmPtr->overseer_town_recno==town_recno)
599 			{
600 				Unit *unitPtr = unit_array[firmPtr->overseer_recno];
601 				pop[unitPtr->race_id-1]++;
602 			}
603 		}
604 
605 		if(firmPtr->worker_count)
606 		{
607 			for(j=firmPtr->worker_count-1; j>=0; j--)
608 			{
609 				if((firmPtr->worker_array[j]).town_recno==town_recno)
610 					pop[(firmPtr->worker_array[j]).race_id-1]++;
611 			}
612 		}
613 	}
614 
615 	for(i=0; i<MAX_RACE; i++)
616 		err_when(pop[i]+jobless_race_pop_array[i] != race_pop_array[i]);
617 #endif
618 
619 	//------------------------------------------------------------//
620 	// check the spy count
621 	//------------------------------------------------------------//
622 
623 #ifdef DEBUG
624 	short	raceSpyCountArray[MAX_RACE];
625 
626 	memset( raceSpyCountArray, 0, sizeof(raceSpyCountArray) );
627 
628 	for( i=spy_array.size() ; i>0 ; i-- )
629 	{
630 		if( spy_array.is_deleted(i) )
631 			continue;
632 
633 		Spy* spyPtr = spy_array[i];
634 
635 		if( spyPtr->spy_place == SPY_TOWN && spyPtr->spy_place_para == town_recno )
636 			raceSpyCountArray[spyPtr->race_id-1]++;
637 	}
638 
639 	for( i=0 ; i<MAX_RACE ; i++ )
640 	{
641 		err_when( race_spy_count_array[i] != raceSpyCountArray[i] );
642 
643 		err_when( race_spy_count_array[i] > jobless_race_pop_array[i] );
644 	}
645 
646 	town_res.get_name(town_name_id);
647 #endif
648 }
649 //----------- End of function Town::next_day ---------//
650 
651 
652 //---------- Begin of function Town::process_food --------//
653 //
process_food()654 void Town::process_food()
655 {
656 	//--------- Peasants produce food ---------//
657 
658 	nation_array[nation_recno]->add_food( (float) jobless_population * PEASANT_FOOD_YEAR_PRODUCTION / 365 );
659 
660 	//---------- People consume food ----------//
661 
662 	nation_array[nation_recno]->consume_food( (float) population * PERSON_FOOD_YEAR_CONSUMPTION / 365 );
663 }
664 //----------- End of function Town::process_food ---------//
665 
666 
667 //---------- Begin of function Town::process_auto --------//
668 //
process_auto()669 void Town::process_auto()
670 {
671 	if( !has_linked_own_camp )		// can only collect or grant when there is a linked camp of its own.
672 		return;
673 
674 	Nation* nationPtr = nation_array[nation_recno];
675 
676 	//----- auto collect tax -----//
677 
678 	if( auto_collect_tax_loyalty > 0 )
679 	{
680 		if( accumulated_collect_tax_penalty == 0 &&
681 			 average_loyalty() >= auto_collect_tax_loyalty )
682 		{
683 			collect_tax(COMMAND_AI);
684 		}
685 	}
686 
687 	//---------- auto grant -----------//
688 
689 	if( auto_grant_loyalty > 0 )
690 	{
691 		if( accumulated_reward_penalty == 0 &&
692 			 average_loyalty() < auto_grant_loyalty && nationPtr->cash > 0 )
693 		{
694 			reward(COMMAND_AI);
695 		}
696 	}
697 }
698 //----------- End of function Town::process_auto ---------//
699 
700 
701 //---------- Begin of function Town::set_nation --------//
702 //
703 // Set the nation of this town.
704 //
705 // Possible changes:
706 //
707 // independent town -> nation town
708 // nation A's town -> nation B's town (surrender)
709 //
set_nation(int newNationRecno)710 void Town::set_nation(int newNationRecno)
711 {
712 	if( nation_recno == newNationRecno )
713 		return;
714 
715 	//--------- update town network (pre-step) ---------//
716 	town_network_array.town_pre_changing_nation(town_recno);
717 
718 
719 	clear_defense_mode();
720 
721 	//------------- stop all actions to attack this town ------------//
722 	unit_array.stop_attack_town(town_recno);
723 	rebel_array.stop_attack_town(town_recno);
724 
725 	//--------- update AI town info ---------//
726 
727 	if( ai_town && nation_recno )
728 	{
729 		nation_array[nation_recno]->del_town_info(town_recno);
730 	}
731 
732 	//--------- reset vars ---------//
733 
734 	is_base_town = 0;
735 	town_defender_count = 0; 	// reset defender count
736 
737 	//----- set power region of the new nation ------//
738 
739 	world.restore_power(loc_x1, loc_y1, loc_x2, loc_y2, town_recno, 0);		// restore power of the old nation
740 	world.set_power(loc_x1, loc_y1, loc_x2, loc_y2, newNationRecno);			// set power of the new nation
741 
742 	//--- update the cloaked_nation_recno of all spies in the firm ---//
743 
744 	spy_array.change_cloaked_nation(SPY_TOWN, town_recno, nation_recno, newNationRecno);		// check the cloaked nation recno of all spies in the firm
745 
746 	//--------- set nation_recno --------//
747 
748 	int oldNationRecno = nation_recno;
749 	nation_recno = newNationRecno;
750 
751 	if( nation_recno )      // reset rebel_recno if the town is then ruled by a nation
752 	{
753 		if( rebel_recno )
754 		{
755 			Rebel* rebelPtr = rebel_array[rebel_recno];
756 
757 			err_when( rebelPtr->mobile_rebel_count > 0 );	// change nation shouldn't happen if mobile_rebel_count > 0
758 
759 			rebel_array.del_rebel(rebel_recno);		// delete the rebel group
760 			rebel_recno = 0;
761 		}
762 	}
763 
764 	//--------- update ai_town ----------//
765 
766 	ai_town = 0;
767 
768 	if( nation_recno==0 )		// independent town
769 	{
770 		ai_town = 1;
771 	}
772 	else if( nation_array[nation_recno]->nation_type==NATION_AI )
773 	{
774 		ai_town = 1;
775 		nation_array[nation_recno]->add_town_info(town_recno);
776 	}
777 
778 	//------ set the loyalty of the town people ------//
779 
780 	int i, nationRaceId;
781 
782 	if( nation_recno )
783 		nationRaceId = nation_array[nation_recno]->race_id;
784 
785 	for( i=0 ; i<MAX_RACE ; i++ )
786 	{
787 		if( nation_recno == 0 )			// independent town set up by rebel
788 			race_loyalty_array[i] = (float) 80;			// this affect the no. of defender if you attack the independent town
789 		else
790 		{
791 			if( nationRaceId == i+1 )
792 				race_loyalty_array[i] = (float) 40;    // loyalty is higher if the ruler and the people are the same race
793 			else
794 				race_loyalty_array[i] = (float) 30;
795 		}
796 	}
797 
798 	//------- reset town_combat_level -------//
799 
800 	town_combat_level = 0;
801 
802 	//------ reset accumulated penalty ------//
803 
804 	accumulated_collect_tax_penalty = 0;
805 	accumulated_reward_penalty	 = 0;
806 	accumulated_enemy_grant_penalty = 0;
807 	accumulated_recruit_penalty = 0;
808 
809 	//---- if there is unit being trained currently, change its nation ---//
810 
811 	if( train_unit_recno )
812 		unit_array[train_unit_recno]->change_nation(newNationRecno);
813 
814 	//-------- update loyalty ---------//
815 
816 	update_target_loyalty();
817 
818 	//--- if a nation set up a town in a location that the player has explored, contact between the nation and the player is established ---//
819 
820 	establish_contact_with_player();
821 
822 	//----- if an AI nation took over this town, see if the AI can capture all firms linked to this town ----//
823 
824 	if( nation_recno && nation_array[nation_recno]->is_ai() )
825 		think_capture_linked_firm();
826 
827 	//--- when a town change nation, call the AI function of call linked firms ---//
828 
829 	Firm* firmPtr;
830 
831 	for( i=0 ; i<linked_firm_count ; i++ )
832 	{
833 		firmPtr = firm_array[ linked_firm_array[i] ];
834 
835 		if( firmPtr->firm_ai )		// tell linked firms that this town has changed nation
836 			firmPtr->think_linked_town_change_nation(town_recno, oldNationRecno, newNationRecno);
837 	}
838 
839 	//------ set national auto policy -----//
840 
841 	if( nation_recno )
842 	{
843 		Nation* nationPtr = nation_array[nation_recno];
844 
845 		set_auto_collect_tax_loyalty( nationPtr->auto_collect_tax_loyalty );
846 		set_auto_grant_loyalty( nationPtr->auto_grant_loyalty );
847 	}
848 
849 	//---- reset the action mode of all spies in this town ----//
850 
851 	spy_array.set_action_mode( SPY_TOWN, town_recno, SPY_IDLE );      // we need to reset it. e.g. when we have captured an enemy town, SPY_SOW_DISSENT action must be reset to SPY_IDLE
852 
853 	//--------- update town network (post-step) ---------//
854 	town_network_array.town_post_changing_nation(town_recno, newNationRecno);
855 
856 	//-------- refresh display ----------//
857 
858 	if( town_array.selected_recno == town_recno )
859 		info.disp();
860 }
861 //----------- End of function Town::set_nation ---------//
862 
863 
864 //------ Begin of function Town::set_hostile_nation -------//
set_hostile_nation(int nationRecno)865 void Town::set_hostile_nation(int nationRecno)
866 {
867 	if(nationRecno==0)
868 		return;
869 
870 	err_when(nationRecno>7); // only 8 bits
871 	independ_town_nation_relation |= (0x1 << nationRecno);
872 }
873 //----------- End of function Town::set_hostile_nation ---------//
874 
875 
876 //------ Begin of function Town::reset_hostile_nation -------//
reset_hostile_nation(int nationRecno)877 void Town::reset_hostile_nation(int nationRecno)
878 {
879 	if(nationRecno==0)
880 		return;
881 
882 	err_when(nationRecno>7); // only 8 bits
883 	independ_town_nation_relation &= ~(0x1 << nationRecno);
884 }
885 //----------- End of function Town::reset_hostile_nation ---------//
886 
887 
888 //------ Begin of function Town::is_hostile_nation -------//
889 // return 1 for hostile nation
890 // return 0 otherwise
891 //
is_hostile_nation(int nationRecno)892 int Town::is_hostile_nation(int nationRecno)
893 {
894 	if(nationRecno==0)
895 		return 0;
896 
897 	err_when(nationRecno>7); // only 8 bits
898 	return (independ_town_nation_relation & (0x1 << nationRecno));
899 }
900 //----------- End of function Town::is_hostile_nation ---------//
901 
902 
903 //--------- Begin of function Town::init_pop ----------//
904 //
905 // Initialize population of the town.
906 //
907 // <int> raceId  - the id. of the race to add.
908 // <int> addPop  - the no. of people to add.
909 // <int> addLoyalty - loyalty of the people to add to the town
910 // [int] hasJob	  - whether the units will have jobs or not after moving into this town
911 //							 (default: 0)
912 // [int] firstInit - first initialization at the beginning of the game
913 //						   (default: 0)
914 //
init_pop(int raceId,int addPop,int addLoyalty,int hasJob,int firstInit)915 void Town::init_pop(int raceId, int addPop, int addLoyalty, int hasJob, int firstInit)
916 {
917 	if(population>=MAX_TOWN_POPULATION)
918 		return;
919 
920 	int addPopulation = MIN(addPop, MAX_TOWN_POPULATION-population);
921 
922 	//-------- update population ---------//
923 
924 	race_pop_array[raceId-1] += addPopulation;
925 	population               += addPopulation;
926 
927 	err_when( race_pop_array[raceId-1] > MAX_TOWN_POPULATION );
928 	err_when( population               > MAX_TOWN_POPULATION );
929 
930 	if( !hasJob )
931 	{
932 		jobless_population               += addPopulation;
933 		jobless_race_pop_array[raceId-1] += addPopulation;
934 	}
935 
936 	err_when( jobless_race_pop_array[raceId-1] > MAX_TOWN_POPULATION );
937 	err_when( jobless_population               > MAX_TOWN_POPULATION );
938 
939 	//------- update loyalty --------//
940 
941 	err_when( race_loyalty_array[raceId-1]<0 || race_loyalty_array[raceId-1]>100 );
942 
943 	if( firstInit )	// first initialization at the beginning of the game
944 	{
945 		if( nation_recno )
946 		{
947 			race_loyalty_array[raceId-1] = (float) addLoyalty;
948 			race_target_loyalty_array[raceId-1] = addLoyalty;
949 		}
950 		else
951 		{
952 			for( int j=0 ; j<MAX_NATION ; j++)							// reset resistance for non-existing races
953 			{
954 				race_resistance_array[raceId-1][j] = (float) addLoyalty;
955 				race_target_resistance_array[raceId-1][j] = addLoyalty;
956 			}
957 		}
958 	}
959 	else
960 	{
961 		if( nation_recno )
962 		{
963 			race_loyalty_array[raceId-1] =
964 					  ( race_loyalty_array[raceId-1] * (race_pop_array[raceId-1]-addPopulation)
965 					  + (float) addLoyalty * addPopulation ) / race_pop_array[raceId-1];
966 
967 			race_target_loyalty_array[raceId-1] = (char) race_loyalty_array[raceId-1];
968 		}
969 		else
970 		{
971 			for( int j=0 ; j<MAX_NATION ; j++)							// reset resistance for non-existing races
972 			{
973 				race_resistance_array[raceId-1][j] =
974 					  ( race_resistance_array[raceId-1][j] * (race_pop_array[raceId-1]-addPopulation)
975 					  + (float) addLoyalty * addPopulation ) / race_pop_array[raceId-1];
976 
977 				race_target_resistance_array[raceId-1][j] = (char) race_resistance_array[raceId-1][j];
978 			}
979 		}
980 	}
981 
982 	err_when( addLoyalty<0 || addLoyalty>100 );
983 	err_when( race_loyalty_array[raceId-1]<0 || race_loyalty_array[raceId-1]>100 );
984 	err_when( race_target_loyalty_array[raceId-1]<0 || race_target_loyalty_array[raceId-1]>100 );
985 
986 	//---------- update town parameters ----------//
987 
988 	town_array.distribute_demand();
989 
990 	if( nation_recno )
991 		update_loyalty();
992 	else
993 		update_resistance();
994 }
995 //--------- End of function Town::init_pop ----------//
996 
997 
998 //--------- Begin of function Town::inc_pop -------//
999 //
1000 // <int> raceId      - the race id. of the population
1001 // <int> unitHasJob  - whether the unit will get a job after moving into the town
1002 // <int> unitLoyalty - loyalty of the unit.
1003 //
inc_pop(int raceId,int unitHasJob,int unitLoyalty)1004 void Town::inc_pop(int raceId, int unitHasJob, int unitLoyalty)
1005 {
1006 	err_when( unitLoyalty < 0 );
1007 
1008 	//---------- increase population ----------//
1009 
1010 	population++;
1011 	race_pop_array[raceId-1]++;
1012 
1013 	err_when( race_pop_array[raceId-1] > MAX_TOWN_POPULATION );
1014 	err_when( population               > MAX_TOWN_POPULATION );
1015 
1016 	if( !unitHasJob )
1017 	{
1018 		jobless_population++;
1019 		jobless_race_pop_array[raceId-1]++;
1020 
1021 		err_when( jobless_race_pop_array[raceId-1] > MAX_TOWN_POPULATION );
1022 		err_when( jobless_population               > MAX_TOWN_POPULATION );
1023 	}
1024 
1025 	//------- update loyalty --------//
1026 
1027 	if( nation_recno )		// if the unit has an unit
1028 	{
1029 		err_when( race_loyalty_array[raceId-1]<0 || race_loyalty_array[raceId-1]>100 );
1030 
1031 		race_loyalty_array[raceId-1] =
1032 				  ( race_loyalty_array[raceId-1] * (race_pop_array[raceId-1]-1)
1033 				  + (float) unitLoyalty ) / race_pop_array[raceId-1];
1034 
1035 		err_when( unitLoyalty<0 || unitLoyalty>100 );
1036 		err_when( race_loyalty_array[raceId-1]<0 || race_loyalty_array[raceId-1]>100 );
1037 	}
1038 
1039 	//-- if the race's population exceeds the capacity of the town layout --//
1040 
1041 	if( race_pop_array[raceId-1] > max_race_pop_array[raceId-1] )
1042 	{
1043 		auto_set_layout();
1044 	}
1045 }
1046 //---------- End of function Town::inc_pop --------//
1047 
1048 
1049 //--------- Begin of function Town::dec_pop -------//
1050 //
1051 // <int> raceId      - the race id. of the population
1052 // <int> unitHasJob  - whether the unit current has a job or not
1053 //
dec_pop(int raceId,int unitHasJob)1054 void Town::dec_pop(int raceId, int unitHasJob)
1055 {
1056 	population--;
1057 	race_pop_array[raceId-1]--;
1058 
1059 	err_when( population < 0 );
1060 	err_when( race_pop_array[raceId-1] < 0 );
1061 
1062 	if( !unitHasJob )
1063 	{
1064 		jobless_population--;
1065 		jobless_race_pop_array[raceId-1]--;
1066 
1067 		err_when( jobless_population < 0 );
1068 		err_when( jobless_race_pop_array[raceId-1] < 0 );
1069 	}
1070 
1071 	err_when( race_pop_array[raceId-1] < jobless_race_pop_array[raceId-1] );
1072 
1073 	//------- if all the population are gone --------//
1074 
1075 	if( population==0 )		// it will be deleted in TownArray::process()
1076 	{
1077 		if( nation_recno == nation_array.player_recno )
1078 	   		news_array.town_abandoned(town_recno);
1079 
1080 		deinit();
1081 		return;
1082 	}
1083 
1084 	//-- if the race's population drops to too low, change the town layout --//
1085 
1086 	if( race_pop_array[raceId-1] <= max_race_pop_array[raceId-1]-POPULATION_PER_HOUSE )
1087 	{
1088 		auto_set_layout();
1089 	}
1090 }
1091 //---------- End of function Town::dec_pop --------//
1092 
1093 
1094 //--------- Begin of function Town::population_grow --------//
1095 //
population_grow()1096 void Town::population_grow()
1097 {
1098 	if( town_defender_count )
1099 		return;
1100 
1101 	if( population >= MAX_TOWN_GROWTH_POPULATION || population >= MAX_TOWN_POPULATION )
1102 		return;
1103 
1104 	//-------- population growth by birth ---------//
1105 
1106 	#ifdef DEBUG
1107 		short	debugPopulation = population;
1108 		char debugRaceGrowth[MAX_RACE] = {0};
1109 	#endif
1110 
1111 	int i, autoSetFlag=0;
1112 
1113 	for( i=0 ; i<MAX_RACE ; i++ )
1114 	{
1115 		//-- the population growth in an independent town is slower than in a nation town ---//
1116 
1117 		if( nation_recno )
1118 			race_pop_growth_array[i] += race_pop_array[i] * (100+quality_of_life) / 100;
1119 		else
1120 			race_pop_growth_array[i] += race_pop_array[i];
1121 
1122 		int loopCount=0;
1123 
1124 		while( race_pop_growth_array[i] > 100 )
1125 		{
1126 			err_when( loopCount++ > 100 );
1127 
1128 			race_pop_growth_array[i] -= 100;
1129 
1130 			race_pop_array[i]++;
1131 			jobless_race_pop_array[i]++;
1132 
1133 			population++;
1134 			jobless_population++;
1135 
1136 			err_when( race_pop_array[i] 			> MAX_TOWN_POPULATION );
1137 			err_when( jobless_race_pop_array[i] > MAX_TOWN_POPULATION );
1138 
1139 			err_when( population > MAX_TOWN_POPULATION );
1140 			err_when( jobless_population > MAX_TOWN_POPULATION );
1141 
1142 			#ifdef DEBUG
1143 				debugRaceGrowth[i]++;
1144 			#endif
1145 
1146 			//-- if the race's population grows too high, change the town layout --//
1147 
1148 			if( race_pop_array[i] > max_race_pop_array[i] )
1149 			{
1150 				autoSetFlag = 1;
1151 			}
1152 
1153 			if(population>=MAX_TOWN_POPULATION)
1154 				break;
1155 		}
1156 
1157 		if(population>=MAX_TOWN_POPULATION)
1158 			break;
1159 	}
1160 
1161 	if( autoSetFlag )
1162 		auto_set_layout();
1163 }
1164 //----------- End of function Town::population_grow --------//
1165 
1166 
1167 //-------- Begin of function Town::race_harmony --------//
1168 //
1169 // Return a harmony rating of the given race.
1170 //
1171 // <int> raceId - id. of the race
1172 //
race_harmony(int raceId)1173 int Town::race_harmony(int raceId)
1174 {
1175 	if( population==0 )
1176 		return 0;
1177 	else
1178 		return 100 * race_pop_array[raceId-1] / population;
1179 }
1180 //--------- End of function Town::race_harmony ---------//
1181 
1182 
1183 //---------- Begin of function Town::update_target_loyalty --------//
1184 //
1185 // Update loyalty for nation towns.
1186 //
update_target_loyalty()1187 void Town::update_target_loyalty()
1188 {
1189 	if( !nation_recno )		// return if independent towns
1190 		return;
1191 
1192 	//----- update loyalty of individual races -------//
1193 	//
1194 	// Loyalty is determined by:
1195 	//
1196 	// - residential harmony
1197 	// - whether the people are racially homogeneous to the king
1198 	// - the nation's reputation
1199 	// - command bases overseeing the town.
1200 	// - quality of life
1201 	// - employment rate
1202 	//
1203 	// Quality of life is determined by:
1204 	//
1205 	// - The provision of goods to the villagers. A more constant
1206 	//	  supply and a bigger variety of goods give to high quality of life.
1207 	//
1208 	//------------------------------------------------//
1209 
1210 	//------- set target loyalty of each race --------//
1211 
1212 	Nation* nationPtr = nation_array[nation_recno];
1213 	int 	  i, targetLoyalty;
1214 	int 	  nationRaceId = nationPtr->race_id;
1215 
1216 	for( i=0 ; i<MAX_RACE ; i++ )
1217 	{
1218 		if( race_pop_array[i] == 0 )
1219 			continue;
1220 
1221 		//------- calculate the target loyalty -------//
1222 
1223 		targetLoyalty = race_harmony(i+1)/3 +				// 0 to 33
1224 							 (int)nationPtr->reputation/4;	// -25 to +25
1225 
1226 		//---- employment help increase loyalty ----//
1227 
1228 		targetLoyalty += 30 - 30 * jobless_race_pop_array[i] / race_pop_array[i];		// +0 to +30
1229 
1230 		if( race_res.is_same_race(i+1, nationRaceId) )
1231 			targetLoyalty += 10;
1232 
1233 		if( targetLoyalty < 0 )		// targetLoyalty can be negative if there are hostile races conflicts
1234 			targetLoyalty = 0;
1235 
1236 		if( targetLoyalty > 100 )
1237 			targetLoyalty = 100;
1238 
1239 		//----------------------------------------//
1240 
1241 		race_target_loyalty_array[i] = targetLoyalty;
1242 
1243 		err_when( targetLoyalty<0 || targetLoyalty>100 );
1244 	}
1245 
1246 	//----- process command bases that have influence on this town -----//
1247 
1248 	int     baseInfluence, thisInfluence, commanderRaceId;
1249 	Firm*   firmPtr;
1250 	Nation  *baseNationPtr;
1251 	Unit*   unitPtr;
1252 
1253 	for( i=0 ; i<linked_firm_count ; i++ )
1254 	{
1255 		if( linked_firm_enable_array[i] != LINK_EE )
1256 			continue;
1257 
1258 		firmPtr = firm_array[linked_firm_array[i]];
1259 
1260 		if( firmPtr->firm_id!=FIRM_CAMP || !firmPtr->overseer_recno )
1261 			continue;
1262 
1263 		//-------- get nation and commander info ------------//
1264 
1265 		unitPtr = unit_array[firmPtr->overseer_recno];
1266 		commanderRaceId = unitPtr->race_id;
1267 
1268 		baseNationPtr = nation_array[firmPtr->nation_recno];
1269 
1270 		//------ if this race is the overseer's race -------//
1271 
1272 		baseInfluence = unitPtr->skill.get_skill(SKILL_LEADING)/3;		// 0 to 33
1273 
1274 		if( unitPtr->rank_id == RANK_KING )			// 20 points bonus for king
1275 			baseInfluence += 20;
1276 
1277 		//------------ update all race -----------//
1278 
1279 		for( int j=0 ; j<MAX_RACE ; j++ )
1280 		{
1281 			if( !race_pop_array[j] )
1282 				continue;
1283 
1284 			//---- if the overseer's race is the same as this race ---//
1285 
1286 			thisInfluence = baseInfluence;
1287 
1288 			if( unitPtr->race_id == j+1 )
1289 				thisInfluence += 8;
1290 
1291 			//--- if the overseer's nation's race is the same as this race ---//
1292 
1293 			if( baseNationPtr->race_id == j+1 )
1294 				thisInfluence += 8;
1295 
1296 			//------------------------------------------//
1297 
1298 			if( firmPtr->nation_recno == nation_recno )	// if the command base belongs to the same nation
1299 			{
1300 				targetLoyalty = race_target_loyalty_array[j] + thisInfluence;
1301 				race_target_loyalty_array[j] = MIN(100, targetLoyalty);
1302 			}
1303 			else if( unitPtr->race_id == j+1 )		// for enemy camps, only decrease same race peasants
1304 			{
1305 				targetLoyalty = race_target_loyalty_array[j] - thisInfluence;
1306 				race_target_loyalty_array[j] = MAX(0, targetLoyalty);
1307 			}
1308 		}
1309 	}
1310 
1311 	//------- apply quality of life -------//
1312 
1313 	int qolContribution = config_adv.town_loyalty_qol ?
1314 		(quality_of_life-50)/3 :			// -17 to +17
1315 		0;						// off
1316 	for( i=0 ; i<MAX_RACE ; i++ )
1317 	{
1318 		if( race_pop_array[i] == 0 )
1319 			continue;
1320 
1321 		targetLoyalty = race_target_loyalty_array[i];
1322 
1323 		// Quality of life only applies to the part above 30 loyalty
1324 		if (targetLoyalty > 30)
1325 		{
1326 			targetLoyalty = MAX(30, targetLoyalty + qolContribution);
1327 			race_target_loyalty_array[i] = MIN(100, targetLoyalty);
1328 		}
1329 	}
1330 
1331 	//------- update link status to linked enemy camps -------//
1332 
1333 	for( i=0 ; i<linked_firm_count ; i++ )
1334 	{
1335 		firmPtr = firm_array[linked_firm_array[i]];
1336 
1337 		if( firmPtr->firm_id != FIRM_CAMP )
1338 			continue;
1339 
1340 		//------------------------------------------//
1341 		// If this town is linked to a own camp,
1342 		// disable all links to enemy camps, otherwise
1343 		// enable all links to enemy camps.
1344 		//------------------------------------------//
1345 
1346 		if( firmPtr->nation_recno != nation_recno )
1347 			toggle_firm_link( i+1, !has_linked_own_camp, COMMAND_AUTO );
1348 	}
1349 }
1350 //----------- End of function Town::update_target_loyalty ---------//
1351 
1352 
1353 //------ Begin of function Town::update_loyalty -----//
1354 //
1355 // Update loyalty and resistance towards the target.
1356 //
update_loyalty()1357 void Town::update_loyalty()
1358 {
1359 	if( !nation_recno )
1360 		return;
1361 
1362 	//------------- update loyalty -------------//
1363 
1364 	float targetLoyalty, loyaltyInc, loyaltyDec;
1365 
1366 	for(int i=0; i<MAX_RACE; i++)
1367 	{
1368 		if( race_pop_array[i] == 0 )
1369 			continue;
1370 
1371 		targetLoyalty = (float) race_target_loyalty_array[i];
1372 
1373 		if(race_loyalty_array[i] < targetLoyalty)
1374 		{
1375 			//--- if this town is linked to enemy camps, but no own camps, no increase in loyalty, only decrease ---//
1376 
1377 			if( !has_linked_own_camp && has_linked_enemy_camp )
1378 				continue;
1379 
1380 			//-------------------------------------//
1381 
1382 			loyaltyInc = (targetLoyalty-race_loyalty_array[i]) / 30;
1383 
1384 			change_loyalty( i+1, MAX(loyaltyInc, (float)0.5) );
1385 		}
1386 		else if(race_loyalty_array[i] > targetLoyalty)
1387 		{
1388 			loyaltyDec = (race_loyalty_array[i]-targetLoyalty) / 30;
1389 
1390 			change_loyalty( i+1, -MAX(loyaltyDec, (float)0.5) );
1391 		}
1392 	}
1393 }
1394 //------- End of function Town::update_loyalty ------//
1395 
1396 
1397 //------ Begin of function Town::change_loyalty -----//
1398 //
1399 // <int>   raceId		    - id. of the race to be changed in loyalty.
1400 // <float> loyaltyChange - the amount of change in loyalty.
1401 //
change_loyalty(int raceId,float loyaltyChange)1402 void Town::change_loyalty(int raceId, float loyaltyChange)
1403 {
1404 	float newLoyalty = race_loyalty_array[raceId-1] + loyaltyChange;
1405 
1406    newLoyalty = MIN( 100, newLoyalty );
1407 	newLoyalty = MAX(   0, newLoyalty );
1408 
1409 	race_loyalty_array[raceId-1] = newLoyalty;
1410 }
1411 //------- End of function Town::change_loyalty ------//
1412 
1413 
1414 //------ Begin of function Town::change_resistance -----//
1415 //
1416 // <int>   raceId		    	 - id. of the race to be changed in loyalty.
1417 // <int>   nationRecno   	 - recno of the nation which the resistance is towards
1418 // <float> resistanceChange - the amount of change in resistance.
1419 //
change_resistance(int raceId,int nationRecno,float resistanceChange)1420 void Town::change_resistance(int raceId, int nationRecno, float resistanceChange)
1421 {
1422 	err_when( raceId < 1 || raceId > MAX_RACE );
1423 	err_when( nation_array.is_deleted(nationRecno) );
1424 
1425 	float newResistance = race_resistance_array[raceId-1][nationRecno-1] + resistanceChange;
1426 
1427 	newResistance = MIN( 100, newResistance );
1428 	newResistance = MAX(   0, newResistance );
1429 
1430 	race_resistance_array[raceId-1][nationRecno-1] = newResistance;
1431 }
1432 //------- End of function Town::change_resistance ------//
1433 
1434 
1435 //------ Begin of function Town::update_target_resistance ------//
1436 //
1437 // Influence from a command base to a town (simplied version)
1438 // ----------------------------------------------------------
1439 // -Reputation of the nation
1440 // -Race of the general and the king (whether its race is the same as the town people's race)
1441 // -Leadership of the general
1442 //
1443 // If the conqueror's race id is the same as the town people's race id.
1444 //   Influence = reputation/2
1445 // else
1446 //   Influence = reputation/4
1447 //
1448 // If the general's race is the same as the town people's race,
1449 //   Influence += general leadership/2
1450 // else
1451 //   Influence += general leadership/4
1452 //
update_target_resistance()1453 void Town::update_target_resistance()
1454 {
1455 	int     i, j;
1456 	Firm*   firmPtr;
1457 	Unit*   unitPtr;
1458 
1459 	if( population==0 || linked_firm_count==0 )
1460 		return;
1461 
1462 	for( i=0 ; i<MAX_RACE ; i++ )
1463 	{
1464 		for( j=0 ; j<MAX_NATION ; j++ )
1465 		{
1466 			race_target_resistance_array[i][j] = -1;		// -1 means influence is not present
1467 		}
1468 	}
1469 
1470 	//---- if this town is controlled by rebels, no decrease in resistance ----//
1471 
1472 	if( rebel_recno )
1473 		return;
1474 
1475 	//----- count the command base that has influence on this town -----//
1476 
1477 	int curValue, newValue;
1478 
1479 	for( i=0 ; i<linked_firm_count ; i++ )
1480 	{
1481 		if( linked_firm_enable_array[i] != LINK_EE )
1482 			continue;
1483 
1484 		firmPtr = firm_array[linked_firm_array[i]];
1485 
1486 		if( firmPtr->firm_id!=FIRM_CAMP || !firmPtr->overseer_recno )
1487 			continue;
1488 
1489 		//-------- get nation and commander info ------------//
1490 
1491 		unitPtr = unit_array[firmPtr->overseer_recno];
1492 
1493 		curValue = race_target_resistance_array[unitPtr->race_id-1][unitPtr->nation_recno-1];
1494 		newValue = 100-camp_influence(firmPtr->overseer_recno);
1495 
1496 		err_when( newValue < 0 );
1497 
1498 		if( curValue == -1 || newValue < curValue )		// need to do this comparsion as there may be more than one command bases of the same nation linked to this town, we use the one with the most influence.
1499 			race_target_resistance_array[unitPtr->race_id-1][unitPtr->nation_recno-1] = newValue;
1500 	}
1501 }
1502 //------- End of function Town::update_target_resistance ------//
1503 
1504 
1505 //------ Begin of function Town::camp_influence ------//
1506 //
1507 // Return a specific military camp's influence on this town.
1508 //
1509 // The influence is calculated based on :
1510 // - the leadership of the commander
1511 // - whether the leader is racially homogenous to this town.
1512 // - whether the king is racially homogenous to this town.
1513 // - the reputation of the nation
1514 //
1515 // <int> unitRecno - unit recno of the commander in the military camp.
1516 //
1517 // return: <int> influence index (0-100)
1518 //
camp_influence(int unitRecno)1519 int Town::camp_influence(int unitRecno)
1520 {
1521 	Unit*   unitPtr = unit_array[unitRecno];
1522 	Nation* nationPtr = nation_array[unitPtr->nation_recno];   // nation of the unit
1523 
1524 	int thisInfluence = unitPtr->skill.get_skill(SKILL_LEADING)*2/3;		// 66% of the leadership
1525 
1526 	if( race_res.is_same_race(nationPtr->race_id, unitPtr->race_id) )
1527 		thisInfluence += thisInfluence/3;		// 33% bonus if the king's race is also the same as the general
1528 
1529 	thisInfluence += (int) nationPtr->reputation/2;;
1530 
1531 	thisInfluence = MIN(100, thisInfluence);
1532 
1533 	return thisInfluence;
1534 }
1535 //------- End of function Town::camp_influence ------//
1536 
1537 
1538 //------ Begin of function Town::update_resistance -----//
1539 //
1540 // Update loyalty and resistance towards the target.
1541 //
update_resistance()1542 void Town::update_resistance()
1543 {
1544 	//------------- update resistance ----------------//
1545 
1546 	int	i, j, maxNation = nation_array.size();
1547 	char	zeroResistance[MAX_NATION];
1548 	float targetResistance;
1549 
1550 	memset( zeroResistance, 1, MAX_NATION );
1551 
1552 	for(i=0; i<MAX_RACE; i++)
1553 	{
1554 		if( race_pop_array[i]==0 )
1555 		{
1556 			for(j=0; j<maxNation; j++)							// reset resistance for non-existing races
1557 				race_resistance_array[i][j] = (float) 0;
1558 
1559 			continue;
1560 		}
1561 
1562 		for(j=0; j<maxNation; j++)
1563 		{
1564 			if( nation_array.is_deleted(j+1) )
1565 				continue;
1566 
1567 			if( race_target_resistance_array[i][j] >= 0 )
1568 			{
1569 				targetResistance = (float) race_target_resistance_array[i][j];
1570 
1571 				if(race_resistance_array[i][j] > targetResistance)		// only decrease, no increase for resistance
1572 				{
1573 					float decValue = (race_resistance_array[i][j]-targetResistance) / 30;
1574 
1575 					race_resistance_array[i][j] -= MAX(1, decValue);
1576 
1577 					if(race_resistance_array[i][j] < targetResistance) // avoid resistance oscillate between taregtLoyalty-1 and taregtLoyalty+1
1578 						race_resistance_array[i][j] = (float)targetResistance;
1579 				}
1580 			}
1581 
1582 			if( race_resistance_array[i][j] >= (float) 1 )		// also values between consider 0 and 1 as zero as they are displayed as 0 in the interface
1583 				zeroResistance[j] = 0;
1584 		}
1585 	}
1586 
1587 	//--- if the town is zero resistance towards any nation, convert to that nation ---//
1588 
1589 	for(j=0; j<maxNation; j++)
1590 	{
1591 		if( nation_array.is_deleted(j+1) )
1592 			continue;
1593 
1594 		if( zeroResistance[j] )
1595 		{
1596 			surrender(j+1);
1597 			break;
1598 		}
1599 	}
1600 }
1601 //------- End of function Town::update_resistance ------//
1602 
1603 
1604 //---------- Begin of function Town::collect_yearly_tax --------//
1605 //
1606 // Collect yearly tax from villagers - this does not decrease their
1607 // loyalty.
1608 //
collect_yearly_tax()1609 void Town::collect_yearly_tax()
1610 {
1611 	nation_array[nation_recno]->add_income(INCOME_TAX, (float)population * TAX_PER_PERSON );
1612 }
1613 //----------- End of function Town::collect_yearly_tax ---------//
1614 
1615 
1616 //---------- Begin of function Town::collect_tax --------//
1617 //
1618 // Collect tax from this town.
1619 //
collect_tax(char remoteAction)1620 void Town::collect_tax(char remoteAction)
1621 {
1622 	if( !has_linked_own_camp )
1623 		return;
1624 
1625 	//------------------------------------------//
1626 
1627 	if( !remoteAction && remote.is_enable() )
1628 	{
1629 		// packet structure : <town recno> <race id>
1630 		short *shortPtr = (short *)remote.new_send_queue_msg(MSG_TOWN_COLLECT_TAX, sizeof(short));
1631 		shortPtr[0] = town_recno;
1632 		return;
1633 	}
1634 
1635 	//----- calculate the loyalty decrease amount ------//
1636 	//
1637 	// If you reward too frequently, the negative effect
1638 	// on loyalty will get larger.
1639 	//
1640 	//--------------------------------------------------//
1641 
1642 	int loyaltyDecrease = COLLECT_TAX_LOYALTY_DECREASE + accumulated_collect_tax_penalty/5;
1643 
1644 	loyaltyDecrease = MIN(loyaltyDecrease, COLLECT_TAX_LOYALTY_DECREASE+10);
1645 
1646 	accumulated_collect_tax_penalty += 10;
1647 
1648 	//------ decrease the loyalty of the town people ------//
1649 
1650 	// ##### patch begin Gilbert 5/8 ######//
1651 //	for( int i=0 ; i<MAX_RACE ; i++ )
1652 //		change_loyalty( i+1, (float) -loyaltyDecrease );
1653 	//----------- increase cash ------------//
1654 //	nation_array[nation_recno]->add_income(INCOME_TAX, (float)population * TAX_PER_PERSON );
1655 
1656 	// ------ cash increase depend on loyalty drop --------//
1657 	float taxCollected = 0.0f;
1658 	for( int i = 0; i < MAX_RACE; i++ )
1659 	{
1660 		float beforeLoyalty = race_loyalty_array[i];
1661 		change_loyalty( i+1, (float) -loyaltyDecrease );
1662 		taxCollected += (beforeLoyalty - race_loyalty_array[i]) * race_pop_array[i] * TAX_PER_PERSON / loyaltyDecrease;
1663 	}
1664 
1665 	//----------- increase cash ------------//
1666 
1667 	nation_array[nation_recno]->add_income(INCOME_TAX, taxCollected );
1668 
1669 	// ##### patch end Gilbert 5/8 ######//
1670 
1671 	//------------ think rebel -------------//
1672 
1673 	think_rebel();
1674 }
1675 //----------- End of function Town::collect_tax ---------//
1676 
1677 
1678 //---------- Begin of function Town::reward --------//
1679 //
1680 // Reward cash to the peasants.
1681 //
reward(char remoteAction)1682 void Town::reward(char remoteAction)
1683 {
1684 	if( !has_linked_own_camp )
1685 		return;
1686 
1687 	//------------------------------------------//
1688 
1689 	if( !remoteAction && remote.is_enable() )
1690 	{
1691 		// packet structure : <town recno> <race id>
1692 		short *shortPtr = (short *)remote.new_send_queue_msg(MSG_TOWN_REWARD, sizeof(short));
1693 		shortPtr[0] = town_recno;
1694 		return;
1695 	}
1696 
1697 	//----- calculate the loyalty increase amount ------//
1698 	//
1699 	// If you reward too frequently, the effect of the
1700 	// granting will be diminished.
1701 	//
1702 	//--------------------------------------------------//
1703 
1704 	int loyaltyIncrease = TOWN_REWARD_LOYALTY_INCREASE - accumulated_reward_penalty/5;
1705 
1706 	loyaltyIncrease = MAX(3, loyaltyIncrease);
1707 
1708 	accumulated_reward_penalty += 10;
1709 
1710 	//------ increase the loyalty of the town people ------//
1711 
1712 	for( int i=0 ; i<MAX_RACE ; i++ )
1713 		change_loyalty( i+1, (float) loyaltyIncrease );
1714 
1715 	//----------- decrease cash ------------//
1716 
1717 	nation_array[nation_recno]->add_expense(EXPENSE_GRANT_OWN_TOWN, (float)population * TOWN_REWARD_PER_PERSON );
1718 }
1719 //----------- End of function Town::reward ---------//
1720 
1721 
1722 //------- Begin of function Town::think_surrender ---------//
1723 //
1724 // Think about surrendering to a nation with camps linked to
1725 // this town.
1726 //
think_surrender()1727 int Town::think_surrender()
1728 {
1729 	if( !nation_recno )			// if it's an independent town
1730 		return 0;
1731 
1732 	//--- only surrender when there is no own camps, but has enemy camps linked to this town ---//
1733 
1734 	if( has_linked_own_camp || !has_linked_enemy_camp )
1735 		return 0;
1736 
1737 	//--- surrender if 2/3 of the population think about surrender ---//
1738 
1739 	int i, discontentedCount=0;
1740 
1741 	for( i=0 ; i<MAX_RACE ; i++ )
1742 	{
1743 		if( race_pop_array[i] <= race_spy_count_array[i] )	// spies do not rebel together with the rebellion
1744 			continue;
1745 
1746 		if( race_loyalty_array[i] <= SURRENDER_LOYALTY )
1747 			discontentedCount += race_pop_array[i];
1748 	}
1749 
1750 	if( discontentedCount < population * 2 / 3 )
1751 		return 0;
1752 
1753 	//-------- think about surrender to which nation ------//
1754 
1755 	int   curRating, bestRating=average_loyalty(), bestNationRecno=0;
1756 	Firm* firmPtr;
1757 
1758 	for( i=0 ; i<linked_firm_count ; i++ )
1759 	{
1760 		firmPtr = firm_array[linked_firm_array[i]];
1761 
1762 		//---- if this is an enemy camp ----//
1763 
1764 		if( firmPtr->firm_id == FIRM_CAMP &&
1765 			 firmPtr->nation_recno != nation_recno &&
1766 			 firmPtr->nation_recno &&
1767 			 firmPtr->overseer_recno )
1768 		{
1769 			curRating = camp_influence(firmPtr->overseer_recno);		// see camp_influence() for details on how the rating is calculated
1770 
1771 			if( curRating > bestRating )
1772 			{
1773 				bestRating = curRating;
1774 				bestNationRecno = firmPtr->nation_recno;
1775 			}
1776 		}
1777 	}
1778 
1779 	//------------------------------------//
1780 
1781 	if( bestNationRecno )
1782 	{
1783 		surrender( bestNationRecno );
1784 		return 1;
1785 	}
1786 	else
1787 		return 0;
1788 }
1789 //------- End of function Town::think_surrender ---------//
1790 
1791 
1792 //------- Begin of function Town::surrender ---------//
1793 //
1794 // This town surrenders to another nation.
1795 //
1796 // <int> toNationRecno - the recno of the nation this town surrenders to.
1797 //
surrender(int toNationRecno)1798 void Town::surrender(int toNationRecno)
1799 {
1800 	err_when( !toNationRecno );
1801 
1802 	//--- if this is a rebel town and the mobile rebel count is > 0, don't surrender (this function can be called by update_resistance() when resistance drops to zero ---//
1803 
1804 	if( rebel_recno )
1805 	{
1806 		Rebel* rebelPtr = rebel_array[rebel_recno];
1807 
1808 		if( rebelPtr->mobile_rebel_count > 0 )
1809 			return;
1810 	}
1811 
1812 	//----------------------------------------//
1813 
1814 	if( nation_recno  == nation_array.player_recno ||
1815 		 toNationRecno == nation_array.player_recno )
1816 	{
1817 		news_array.town_surrendered(town_recno, toNationRecno);
1818 		// ##### begin Gilbert 9/10 ######//
1819 		// sound effect
1820 		if( toNationRecno == nation_array.player_recno )
1821 		{
1822 			se_ctrl.immediate_sound("GET_TOWN");
1823 		}
1824 		// ##### end Gilbert 9/10 ######//
1825 	}
1826 
1827 	set_nation( toNationRecno );
1828 }
1829 //------- End of function Town::surrender ---------//
1830 
1831 
1832 //------- Begin of function Town::think_rebel ---------//
1833 //
think_rebel()1834 void Town::think_rebel()
1835 {
1836 	if( !nation_recno )
1837 		return;
1838 
1839 	#define REBEL_INTERVAL_MONTH		3		// don't rebel twice in less than 3 months
1840 
1841 	if( info.game_date < last_rebel_date + REBEL_INTERVAL_MONTH*30 )
1842 		return;
1843 
1844 	if( town_defender_count > 0 || info.game_date < last_being_attacked_date + 10 )		// don't rebel within ten days after being attacked by a hostile unit
1845 		return;
1846 
1847 	//--- rebel if 2/3 of the population becomes discontented ---//
1848 
1849 	int i, discontentedCount=0, rebelLeaderRaceId=0, largestRebelRace=0;
1850 
1851 	for( i=0 ; i<MAX_RACE ; i++ )
1852 	{
1853 		if( race_pop_array[i] <= race_spy_count_array[i] )	// spies do not rebel together with the rebellion
1854 			continue;
1855 
1856 		if( race_loyalty_array[i] <= REBEL_LOYALTY )
1857 		{
1858 			discontentedCount += race_pop_array[i];
1859 
1860 			if( race_pop_array[i] > largestRebelRace )
1861 			{
1862 				largestRebelRace  = race_pop_array[i];
1863 				rebelLeaderRaceId = i+1;
1864 			}
1865 		}
1866 	}
1867 
1868 	if( population == 1 )			// if population is 1 only, handle otherwise
1869 	{
1870 		if( !rebelLeaderRaceId )
1871 			return;
1872 	}
1873 	else
1874 	{
1875 		if( discontentedCount < population * 2 / 3 )
1876 			return;
1877 	}
1878 
1879 	//----- if there was just one unit in the town and he rebels ----//
1880 
1881 	int oneRebelOnly=0;
1882 
1883 	if( population==1 )
1884 	{
1885 		news_array.town_rebel(town_recno, 1);
1886 		oneRebelOnly = 1;
1887 	}
1888 
1889 	//----- create the rebel leader and the rebel group ------//
1890 
1891 	int rebelCount=1;
1892 	int leaderUnitRecno = create_rebel_unit(rebelLeaderRaceId, 1);		// 1-the unit is the rebel leader
1893 
1894 	if( !leaderUnitRecno )
1895 		return;
1896 
1897 	uint32_t curGroupId = unit_array.cur_group_id++;
1898 	Unit *unitPtr = unit_array[leaderUnitRecno];
1899 	unitPtr->unit_group_id = curGroupId;
1900 
1901 	if( oneRebelOnly )		// if there was just one unit in the town and he rebels
1902 	{
1903 		rebel_array.create_rebel(leaderUnitRecno, nation_recno);
1904 		return;
1905 	}
1906 
1907 	int rebelRecno = rebel_array.create_rebel(leaderUnitRecno, nation_recno, REBEL_ATTACK_TOWN, town_recno);		// create a rebel group
1908 
1909 	//------- create other rebel units in the rebel group -----//
1910 
1911 	int j, unitRecno, raceRebelCount;
1912 
1913 	for( i=0 ; i<MAX_RACE ; i++ )
1914 	{
1915 		if( race_pop_array[i] <= race_spy_count_array[i] || race_loyalty_array[i] > REBEL_LOYALTY )
1916 			continue;
1917 
1918 		if( population==1 )		// if only one peasant left, break, so not all peasants will rebel
1919 			break;
1920 
1921 		raceRebelCount = (int) (race_pop_array[i]-race_spy_count_array[i]) * (30+misc.random(30)) / 100;		// 30% - 60% of the unit will rebel.
1922 		err_when(raceRebelCount+1 > MAX_TOWN_POPULATION); // plus 1 for the leader, cannot excess MAX_TOWN_POPULATION, consider the case these units settle immediately
1923 
1924 		for( j=0 ; j<raceRebelCount ; j++ )		// no. of rebel units of this race
1925 		{
1926 			unitRecno = create_rebel_unit(i+1, 0);
1927 
1928 			if( !unitRecno )		// 0-the unit is not the rebel leader
1929 				break;
1930 
1931 			unitPtr = unit_array[unitRecno];
1932 			unitPtr->unit_group_id = curGroupId;
1933 			unitPtr->leader_unit_recno = leaderUnitRecno;
1934 
1935 			rebel_array[rebelRecno]->join(unitRecno);
1936 
1937 			rebelCount++;
1938 		}
1939 
1940 		//--- when disloyal units left, the average loyalty increases ---//
1941 
1942 		change_loyalty( i+1, (float) 50 * j / race_pop_array[i] );
1943 	}
1944 
1945 	//---------- add news -------------//
1946 
1947 	last_rebel_date = info.game_date;
1948 
1949 	news_array.town_rebel(town_recno, rebelCount);		// add the news first as after callijng ai_spy_town_rebel, the town may disappear as all peasants are gone
1950 
1951 	//--- tell the AI spies in the town that a rebellion is happening ---//
1952 
1953 	spy_array.ai_spy_town_rebel(town_recno);
1954 }
1955 //------- End of function Town::think_rebel ---------//
1956 
1957 
1958 //-------- Begin of function Town::create_rebel_unit --------//
1959 //
1960 // Create a rebel unit from a town.
1961 //
1962 // <int> raceId   - race id. of the unit
1963 // <int> isLeader - whether the unit is a rebel leader
1964 //
1965 // return: <int> recno of the unit created.
1966 //
create_rebel_unit(int raceId,int isLeader)1967 int Town::create_rebel_unit(int raceId, int isLeader)
1968 {
1969 /*	//--- do not mobilize spies as rebels ----//
1970 
1971 	//---------------------------------------//
1972 	//
1973 	// If there are spies in this town, first mobilize
1974 	// the spies whose actions are "Sow Dissent".
1975 	//
1976 	//---------------------------------------//
1977 
1978 	int idleSpyCount=0;
1979 
1980 	if( race_spy_count_array[raceId-1] > 0 )
1981 	{
1982 		Spy* spyPtr;
1983 
1984 		for( int i=spy_array.size() ; i>0 ; i-- )
1985 		{
1986 			if( spy_array.is_deleted(i) )
1987 				continue;
1988 
1989 			spyPtr = spy_array[i];
1990 
1991 			if( spyPtr->spy_place==SPY_TOWN &&
1992 				 spyPtr->spy_place_para==town_recno &&
1993 				 spyPtr->race_id==raceId )
1994 			{
1995 				if( spyPtr->action_mode == SPY_SOW_DISSENT )
1996 				{
1997 					int unitRecno = spyPtr->mobilize_town_spy();
1998 
1999 					if( isLeader )
2000 						unit_array[unitRecno]->set_rank(RANK_GENERAL);
2001 
2002 					return unitRecno;
2003 				}
2004 
2005 				idleSpyCount++;
2006 			}
2007 		}
2008 	}
2009 	//---- if the remaining population are all sleep spy, no new rebels ----//
2010 
2011 	if( race_pop_array[raceId-1] == idleSpyCount )
2012 		return 0;
2013 
2014 	err_when( race_pop_array[raceId-1] < idleSpyCount );
2015 */
2016 
2017 	//---- if no jobless people, make workers and overseers jobless ----//
2018 
2019 	if( recruitable_race_pop(raceId, 0)==0 )	// 0-don't recruit spies as the above code should have handle spies already
2020 	{
2021 		if( !unjob_town_people(raceId, 0) )		// 0-don't unjob overseer
2022 			return 0;
2023 
2024 		if( recruitable_race_pop(raceId,0)==0 )	// if the unjob unit is a spy too, then don't rebel
2025 			return 0;
2026 	}
2027 
2028 	//----look for an empty locatino for the unit to stand ----//
2029 	//--- scan for the 5 rows right below the building ---//
2030 
2031 	int            unitId = race_res[raceId]->basic_unit_id;
2032 	SpriteInfo*    spriteInfo = sprite_res[unit_res[unitId]->sprite_id];
2033 	int            xLoc=loc_x1, yLoc=loc_y1;     // xLoc & yLoc are used for returning results
2034 
2035 	if( !world.locate_space( &xLoc, &yLoc, loc_x2, loc_y2, spriteInfo->loc_width, spriteInfo->loc_height ) )
2036 		return 0;
2037 
2038 	//---------- add the unit now -----------//
2039 
2040 	int rankId;
2041 
2042 	if( isLeader )
2043 		rankId = RANK_GENERAL;
2044 	else
2045 		rankId = RANK_SOLDIER;
2046 
2047 	int unitRecno = unit_array.add_unit( unitId, 0, rankId, 0, xLoc, yLoc );
2048 
2049 	dec_pop(raceId, 0);		// decrease the town's population
2050 
2051 	//------- set the unit's parameters --------//
2052 
2053 	Unit* unitPtr = unit_array[unitRecno];
2054 
2055 	if( isLeader )
2056 	{
2057 		int combatLevel 	  = 10 + population*2 + misc.random(10);		// the higher the population is, the higher the combat level will be
2058 		int leadershipLevel = 10 + population   + misc.random(10);		// the higher the population is, the higher the combat level will be
2059 
2060 		unitPtr->set_combat_level( MIN(combatLevel, 100) );
2061 
2062 		unitPtr->skill.skill_id 	= SKILL_LEADING;
2063 		unitPtr->skill.skill_level = MIN(leadershipLevel, 100);
2064 	}
2065 	else
2066 	{
2067 		unitPtr->set_combat_level(CITIZEN_COMBAT_LEVEL); 	// combat: 10
2068 	}
2069 
2070 	return unitRecno;
2071 }
2072 //--------- End of function Town::create_rebel_unit ---------//
2073 
2074 
2075 //--------- Begin of function Town::assign_unit --------//
2076 //
assign_unit(int unitRecno)2077 void Town::assign_unit(int unitRecno)
2078 {
2079 	//-----------------------------------------//
2080 
2081 	Unit* unitPtr = unit_array[unitRecno];
2082 
2083 	if( population >= MAX_TOWN_POPULATION || unitPtr->rank_id == RANK_KING )
2084 	{
2085 		unitPtr->stop2();
2086 		//----------------------------------------------------------------------//
2087 		// codes for handle_blocked_move
2088 		// set unit_group_id to a different value s.t. the members in this group
2089 		// will not blocked by this unit.
2090 		//----------------------------------------------------------------------//
2091 		unitPtr->unit_group_id = unit_array.cur_group_id++;
2092 		return;
2093 	}
2094 
2095 	//------ if the unit is a general, demote it first -------//
2096 
2097 	if( unitPtr->rank_id == RANK_GENERAL )
2098 		unitPtr->set_rank(RANK_SOLDIER);
2099 
2100 	//-------- increase population -------//
2101 
2102 	inc_pop(unitPtr->race_id, 0, unitPtr->loyalty);
2103 
2104 	//---- free the unit's name from the name database ----//
2105 
2106 	race_res[unitPtr->race_id]->free_name_id( unitPtr->name_id );
2107 
2108 	//----- if it's a town defending unit -----//
2109 
2110 	if( unitPtr->unit_mode == UNIT_MODE_DEFEND_TOWN )
2111 	{
2112 		#define RESISTANCE_INCREASE  2   // if the defender defeat the attackers and return the town with victory, the resistance will further increase
2113 
2114 		//---------------------------------------------//
2115 		//
2116 		// If this unit is a defender of the town, add back the
2117 		// loyalty which was deducted from the defender left the
2118 		// town.
2119 		//
2120 		//---------------------------------------------//
2121 
2122 		if( unitPtr->nation_recno == nation_recno &&
2123 			 unitPtr->unit_mode_para == town_recno )
2124 		{
2125 			//-- if the unit is a town defender, skill.skill_level is temporary used for storing the loyalty that will be added back to the town if the defender returns to the town
2126 
2127 			int loyaltyInc = unitPtr->skill.skill_level;
2128 
2129 			if( nation_recno )			// set the loyalty later for nation_recno > 0
2130 			{
2131 				change_loyalty( unitPtr->race_id, (float) loyaltyInc );
2132 			}
2133 			else
2134 			{
2135 				for( int i=0 ; i<MAX_NATION ; i++ )		// set the resistance
2136 				{
2137 					float newResistance = race_resistance_array[unitPtr->race_id-1][i]
2138 												 + loyaltyInc + RESISTANCE_INCREASE;
2139 
2140 					race_resistance_array[unitPtr->race_id-1][i]	= MIN(newResistance, 100);
2141 				}
2142 			}
2143 		}
2144 	}
2145 
2146 	//------ if the unit is a spy -------//
2147 
2148 	if( unitPtr->spy_recno > 0 )
2149 	{
2150 		spy_array[unitPtr->spy_recno]->set_place(SPY_TOWN, town_recno);
2151 		unitPtr->spy_recno = 0;		// reset it so Unit::deinit() won't delete the spy
2152 	}
2153 
2154 	//----- if this is an independent town -----//
2155 
2156 	if( nation_recno==0 )		// update the town people's combat level with this unit's combat level
2157 	{
2158 		town_combat_level = ( (int)town_combat_level*(population-1) + (int)unitPtr->skill.combat_level ) / population;
2159 	}
2160 
2161 	//--------- delete the unit --------//
2162 
2163 	unit_array.disappear_in_town(unitRecno, town_recno);		// the unit disappear from the map because it has moved into a town
2164 }
2165 //---------- End of function Town::assign_unit --------//
2166 
2167 
2168 //------- Begin of function Town::think_migrate ---------//
2169 //
2170 // Let the town people (only those jobless) think if they want
2171 // to migrate or not.
2172 //
2173 // People who have jobs will think in Firm::think_worker_migrate()
2174 //
2175 // Migration Possibilities:
2176 //
2177 // Independent town people migrate to -> nation town
2178 // Nation town people migrate to -> nation town
2179 //
2180 // But nation town people will NOT migrate to independent towns.
2181 //
think_migrate()2182 void Town::think_migrate()
2183 {
2184 	#define MIGRATE_PROCESS_CYCLE	90
2185 	#define MAX_MIGRATE_PER_DAY	 4			// don't migrate more than 4 units per day
2186 
2187 	if( jobless_population==0 )
2188 		return;
2189 
2190 	int   i, j, raceId, migratedCount, townDistance;
2191 	int   saveTownRecno = town_recno;
2192 	int	saveTownNationRecno = nation_recno;
2193 	Town* townPtr;
2194 
2195 	int cycleId = (info.game_date+town_recno)/MIGRATE_PROCESS_CYCLE;
2196 
2197 	for( i=town_array.size() ; i>0 ; i-- )
2198 	{
2199 		if( i%MIGRATE_PROCESS_CYCLE != cycleId )		// while this function is called every day, it only processes a certain number of towns (not all) once a day
2200 			continue;
2201 
2202 		if( town_array.is_deleted(i) )
2203 			continue;
2204 
2205 		townPtr = town_array[i];
2206 
2207 		if( townPtr->population>=MAX_TOWN_POPULATION )
2208 			continue;
2209 
2210 		townDistance = misc.points_distance(center_x, center_y, townPtr->center_x, townPtr->center_y);
2211 
2212 		//---- scan all jobless population, see if any of them want to migrate ----//
2213 
2214 		raceId = random_race();
2215 
2216 		for( j=0 ; j<MAX_RACE ; j++ )
2217 		{
2218 			if( ++raceId > MAX_RACE )
2219 				raceId = 1;
2220 
2221 			err_when( race_spy_count_array[raceId-1] < 0 );
2222 
2223 			if( recruitable_race_pop(raceId, 0) <= race_spy_count_array[raceId-1] )		// only if there are peasants who are jobless and are not spies
2224 				continue;
2225 
2226 			//--- migrate a number of people of the same race at the same time ---//
2227 
2228 			migratedCount=0;
2229 
2230 			int loopCount=0;
2231 
2232 			while( think_migrate_one(townPtr, raceId, townDistance) )
2233 			{
2234 				err_when( ++loopCount > 100 );
2235 
2236 				migratedCount++;
2237 
2238 				if( townDistance > EFFECTIVE_TOWN_TOWN_DISTANCE )		// don't migrate more than one unit at a time for migrating to non-linked towns
2239 					break;
2240 
2241 				if( migratedCount >= MAX_MIGRATE_PER_DAY )
2242 					break;
2243 			}
2244 
2245 			//------------- add news --------------//
2246 
2247 			if( migratedCount > 0 )
2248 			{
2249 				if( saveTownNationRecno==nation_array.player_recno ||
2250 					 townPtr->nation_recno==nation_array.player_recno )
2251 				{
2252 					news_array.migrate(saveTownRecno, townPtr->town_recno, raceId, migratedCount);
2253 				}
2254 
2255 				return;
2256 			}
2257 		}
2258 	}
2259 }
2260 //-------- End of function Town::think_migrate -----------//
2261 
2262 
2263 //------- Begin of function Town::think_migrate_one ---------//
2264 //
2265 // Think about migrating one person of the given race to the
2266 // given town.
2267 //
2268 //------------------------------------------------//
2269 //
2270 // Calculate the attractive factor, it is based on:
2271 //
2272 // - the reputation of the target nation (+0 to 100)
2273 // - the racial harmony of the race in the target town (+0 to 100)
2274 // - distance between the current town and the target town (-0 to 100)
2275 //
2276 // Attractiveness level range: 0 to 200
2277 //
2278 //------------------------------------------------//
2279 //
think_migrate_one(Town * targetTown,int raceId,int townDistance)2280 int Town::think_migrate_one(Town* targetTown, int raceId, int townDistance)
2281 {
2282 	//-- only if there are peasants who are jobless and are not spies --//
2283 
2284 	if( recruitable_race_pop(raceId,0)==0 )		//0-don't recruit spies
2285 		return 0;
2286 
2287 	//---- if the target town's population has already reached its MAX ----//
2288 
2289 	if( targetTown->population>=MAX_TOWN_POPULATION )
2290 		return 0 ;
2291 
2292 	//-- do not migrate if the target town's population of that race is less than half of the population of the current town --//
2293 
2294 	if( targetTown->race_pop_array[raceId-1] < race_pop_array[raceId-1]/2 )
2295 		return 0;
2296 
2297 	//--- calculate the attractiveness rating of the current town ---//
2298 
2299 	int curAttractLevel = race_harmony(raceId);
2300 
2301 	//--- if the target town is not linked to the current town, reduce attractiveness ---//
2302 
2303 	if( townDistance > EFFECTIVE_TOWN_TOWN_DISTANCE )
2304 	{
2305 		curAttractLevel -= 20 + townDistance/2;		// 20 to 70 negative
2306 	}
2307 
2308 	//------- loyalty/resistance affecting the attractivness ------//
2309 
2310 	if( nation_recno )
2311 	{
2312 		curAttractLevel += (int) nation_array[nation_recno]->reputation +
2313 								 (int) (race_loyalty_array[raceId-1] - 40);  // loyalty > 40 is considered as positive force, < 40 is considered as negative force
2314 	}
2315 	else
2316 	{
2317 		if( targetTown->nation_recno )
2318 			curAttractLevel += (int) race_resistance_array[raceId-1][targetTown->nation_recno-1];
2319 	}
2320 
2321 	//--- calculate the attractiveness rating of the target town ---//
2322 
2323 	int targetAttractLevel = targetTown->race_harmony(raceId);
2324 
2325 	if( targetTown->nation_recno )
2326 		targetAttractLevel += (int) nation_array[targetTown->nation_recno]->reputation;
2327 
2328 	//--------- compare the attractiveness ratings ---------//
2329 
2330 	if( targetAttractLevel > curAttractLevel && targetAttractLevel > 0 )
2331 	{
2332 		//--- if this is non-linked town, there are 50% chance that the migrating units will get lost on their way and never reach the destination ---//
2333 
2334 		if( townDistance > EFFECTIVE_TOWN_TOWN_DISTANCE )
2335 		{
2336 			if( misc.random(2)==0 )
2337 			{
2338 				dec_pop(raceId, 0);
2339 				return 1;
2340 			}
2341 		}
2342 
2343 		//---------- migrate now ----------//
2344 
2345 		int newLoyalty = MAX( targetAttractLevel/2, 40 );
2346 
2347 		migrate(raceId, targetTown->town_recno, newLoyalty);
2348 		return 1;
2349 	}
2350 
2351 	return 0;
2352 }
2353 //-------- End of function Town::think_migrate_one -----------//
2354 
2355 
2356 //------- Begin of function Town::migrate ---------//
2357 //
2358 // People migrate from one town to another.
2359 //
2360 // <int> raceId        - id. of the race that migrates
2361 // <int> destTownRecno - recno of the destination town.
2362 // <int> newLoyalty    - loyalty of the unit in the target town.
2363 //
2364 // return: <int> 1 - migrated successfully
2365 //               0 - no building space in the target town for that race
2366 //
migrate(int raceId,int destTownRecno,int newLoyalty)2367 void Town::migrate(int raceId, int destTownRecno, int newLoyalty)
2368 {
2369 	Town* destTown = town_array[destTownRecno];
2370 
2371 	if(destTown->population>=MAX_TOWN_POPULATION)
2372 		return;
2373 
2374 	//------- decrease the population of this town ------//
2375 
2376 	dec_pop(raceId, 0);
2377 
2378 	//--------- increase the population of the target town ------//
2379 
2380 	destTown->inc_pop(raceId, 0, newLoyalty);
2381 }
2382 //-------- End of function Town::migrate -----------//
2383 
2384 
2385 //------- Begin of function Town::migrate_to ---------//
2386 
migrate_to(int destTownRecno,char remoteAction,int raceId,int count)2387 int Town::migrate_to(int destTownRecno, char remoteAction, int raceId, int count)
2388 {
2389 	if (count <= 0 || count > MAX_TOWN_POPULATION)
2390 	{
2391 		err_here();
2392 		return 0;
2393 	}
2394 
2395 	if( !raceId )
2396 	{
2397 		raceId = browse_selected_race_id();
2398 
2399 		if( !raceId )
2400 			return 0;
2401 	}
2402 
2403 	if( !remoteAction && remote.is_enable() )
2404 	{
2405 		// packet structure : <town recno> <dest town recno> <race id> <count>
2406 		short *shortPtr = (short *)remote.new_send_queue_msg(MSG_TOWN_MIGRATE, 4*sizeof(short));
2407 		shortPtr[0] = town_recno;
2408 		shortPtr[1] = destTownRecno;
2409 		shortPtr[2] = raceId;
2410 		shortPtr[3] = count;
2411 		return 0;
2412 	}
2413 
2414 	bool continueMigrate = true;
2415 	int migrated = 0;
2416 	while( continueMigrate && migrated < count )
2417 	{
2418 		continueMigrate = can_migrate(destTownRecno, 1, raceId); // 1- migrate now, 1-allow migrate spy
2419 		if (continueMigrate) ++migrated;
2420 	}
2421 
2422 	return migrated;
2423 }
2424 //-------- End of function Town::migrate_to -----------//
2425 
2426 
2427 //------- Begin of function Town::can_migrate ---------//
2428 //
2429 // Check if it is okay for migrating one person from
2430 // the current town to the given town.
2431 //
2432 // <int> destTownRecno - the recno of the town the people
2433 //								 will migrate to.
2434 //
2435 // [int] migrateNow 	  - migrate now or not if the result is true
2436 //								 (default: false)
2437 //
2438 // [int] raceId        - race to check migrate
2439 //                       (default: 0, to find from the selected_race_id() )
2440 //
2441 // return: <int> true - migration allowed
2442 //					  false - migration not allowed
2443 //
can_migrate(int destTownRecno,bool migrateNow,int raceId)2444 bool Town::can_migrate(int destTownRecno, bool migrateNow, int raceId)
2445 {
2446 	if(!raceId)
2447 	{
2448 		raceId = browse_selected_race_id();
2449 
2450 		if( !raceId )
2451 			return false;
2452 	}
2453 
2454 	Town* destTown = town_array[destTownRecno];
2455 
2456 	if( destTown->population>=MAX_TOWN_POPULATION )
2457 		return false;
2458 
2459 	//---- if there are still jobless units ----//
2460 
2461 	if( recruitable_race_pop(raceId, 1) > 0 )		// 1-allow migrate spy
2462 	{
2463 		if( migrateNow )
2464 			move_pop(destTown, raceId, 0);		// 0-doesn't have job
2465 
2466 		return true;
2467 	}
2468 
2469 	//--- if there is no jobless units left -----//
2470 
2471 	int 	  i, j;
2472 	Firm*   firmPtr;
2473 	Worker* workerPtr;
2474 
2475 	if( race_pop_array[raceId-1] > 0 )
2476 	{
2477 		//---- scan for firms that are linked to this town ----//
2478 
2479 		for( i=linked_firm_count-1 ; i>=0 ; i-- )
2480 		{
2481 			firmPtr = firm_array[linked_firm_array[i]];
2482 
2483 			//---- only for firms whose workers live in towns ----//
2484 
2485 			if( !firm_res[firmPtr->firm_id]->live_in_town )
2486 				continue;
2487 
2488 			//---- if the target town is within the effective range of this firm ----//
2489 
2490 			if( misc.points_distance( destTown->center_x, destTown->center_y,
2491 				 firmPtr->center_x, firmPtr->center_y ) > EFFECTIVE_FIRM_TOWN_DISTANCE )
2492 			{
2493 				continue;
2494 			}
2495 
2496 			//------- scan for workers -----------//
2497 
2498 			workerPtr=firmPtr->worker_array;
2499 
2500 			for( j=firmPtr->worker_count-1 ; j>=0 ; j--, workerPtr++ )
2501 			{
2502 				//--- if the worker lives in this town ----//
2503 
2504 				if( workerPtr->race_id == raceId &&
2505 					 workerPtr->town_recno == town_recno )
2506 				{
2507 					if( migrateNow )
2508 					{
2509 						if( firm_res[firmPtr->firm_id]->live_in_town )
2510 							workerPtr->town_recno = destTownRecno;
2511 						else
2512 							workerPtr->town_recno = 0;
2513 
2514 						move_pop(destTown, raceId, 1);		// 1-has job
2515 					}
2516 
2517 					return true;
2518 				}
2519 			}
2520 		}
2521 	}
2522 
2523 	return false;
2524 }
2525 //-------- End of function Town::can_migrate -----------//
2526 
2527 
2528 //------- Begin of function Town::move_pop ---------//
2529 //
2530 // This function is called by Town::can_migrate() only to move a unit
2531 // from one town to another.
2532 //
move_pop(Town * destTown,int raceId,int hasJob)2533 void Town::move_pop(Town* destTown, int raceId, int hasJob)
2534 {
2535 	//--- if the only pop of this race in the source town are spies ---//
2536 
2537 	if( !hasJob )		// only for peasant, for job unit, spy_place==SPY_FIRM and it isn't related to race_spy_count_array[]
2538 	{
2539 		err_when( race_spy_count_array[raceId-1] > jobless_race_pop_array[raceId-1] );
2540 
2541 		if( race_spy_count_array[raceId-1] == jobless_race_pop_array[raceId-1] )
2542 		{
2543 			int spySeqId = misc.random( race_spy_count_array[raceId-1] ) + 1;		// randomly pick one of the spies
2544 
2545 			int spyRecno = spy_array.find_town_spy(town_recno, raceId, spySeqId);
2546 
2547 			err_when( !spyRecno );
2548 
2549 			spy_array[spyRecno]->spy_place_para = destTown->town_recno;		// set the place_para of the spy
2550 
2551 			race_spy_count_array[raceId-1]--;
2552 			destTown->race_spy_count_array[raceId-1]++;
2553 		}
2554 	}
2555 
2556 	//------------------------------------------//
2557 
2558 	err_when( destTown->population>MAX_TOWN_POPULATION );
2559 
2560 	destTown->inc_pop( raceId, hasJob, (int) race_loyalty_array[raceId-1] );
2561 
2562 	dec_pop( raceId, hasJob );		// the unit doesn't have a job - this must be called finally as dec_pop() will have the whole town deleted if there is only one pop left
2563 
2564 	err_when( race_spy_count_array[raceId-1] > jobless_race_pop_array[raceId-1] );
2565 	err_when( destTown->race_spy_count_array[raceId-1] > destTown->jobless_race_pop_array[raceId-1] );
2566 }
2567 //-------- End of function Town::move_pop -----------//
2568 
2569 
2570 //-------- Begin of function Town::mobilize_town_people --------//
2571 //
2572 // Call out a citizen of the town population and make it
2573 // as an unit.
2574 //
2575 // <int> raceId - race id. of the unit
2576 // <int> decPop - whether decrease the population or not,
2577 //						if 0, only a unit will be created and no population will
2578 //						be reduced.
2579 // <int> mobileSpyFlag - whether spies will be mobilized
2580 //
2581 // return: <int> recno of the unit created.
2582 //
mobilize_town_people(int raceId,int decPop,int mobileSpyFlag)2583 int Town::mobilize_town_people(int raceId, int decPop, int mobileSpyFlag)
2584 {
2585 	//---- if no jobless people, make workers and overseers jobless ----//
2586 
2587 	if( recruitable_race_pop(raceId, mobileSpyFlag)==0 )
2588 	{
2589 		if( !unjob_town_people(raceId, 0) )		// 0-don't unjob overseer
2590 			return 0;
2591 
2592 		err_when( recruitable_race_pop(raceId, mobileSpyFlag)==0 );
2593 	}
2594 
2595 	//----look for an empty locatino for the unit to stand ----//
2596    //--- scan for the 5 rows right below the building ---//
2597 
2598    int            unitId = race_res[raceId]->basic_unit_id;
2599    SpriteInfo*    spriteInfo = sprite_res[unit_res[unitId]->sprite_id];
2600    int            xLoc=loc_x1, yLoc=loc_y1;     // xLoc & yLoc are used for returning results
2601 
2602    if( !world.locate_space( &xLoc, &yLoc, loc_x2, loc_y2, spriteInfo->loc_width, spriteInfo->loc_height ) )
2603       return 0;
2604 
2605 	//---------- add the unit now -----------//
2606 
2607 	int unitRecno = unit_array.add_unit( unitId,
2608 						 nation_recno, RANK_SOLDIER, (int) race_loyalty_array[raceId-1], xLoc, yLoc );
2609 
2610    //------- set the unit's parameters --------//
2611 
2612 	Unit* unitPtr = unit_array[unitRecno];
2613 
2614 	unitPtr->set_combat_level(CITIZEN_COMBAT_LEVEL);
2615 
2616 	//-------- decrease the town's population ------//
2617 
2618 	if( decPop )
2619 		dec_pop(raceId, 0);
2620 
2621 	return unitRecno;
2622 }
2623 //--------- End of function Town::mobilize_town_people ---------//
2624 
2625 
2626 //--------- Begin of function Town::being_attacked -------//
2627 //
2628 // This function is called by Unit::hit_town()
2629 //
2630 // <int>   attackerUnitRecno - recno of the unit attacking this town.
2631 // <float> attackDamage      - damage caused by the attack
2632 //
being_attacked(int attackerUnitRecno,float attackDamage)2633 void Town::being_attacked(int attackerUnitRecno, float attackDamage)
2634 {
2635 	if( rebel_recno )		// if this town is controlled by a rebel group
2636 		rebel_array[rebel_recno]->town_being_attacked(attackerUnitRecno);
2637 
2638 	if( population==0 )
2639 		return;
2640 
2641 	defend_target_recno = attackerUnitRecno; // store the target recno
2642 
2643 	Unit* attackerUnit = unit_array[attackerUnitRecno];
2644 
2645 	if( attackerUnit->nation_recno == nation_recno )		// this can happen when the unit has just changed nation
2646 		return;
2647 
2648 	int attackerNationRecno = attackerUnit->nation_recno;
2649 
2650 	last_being_attacked_date = info.game_date;
2651 
2652 	//--------- store attacker nation recno -----------//
2653 
2654 	err_when(attackerNationRecno<0 || attackerNationRecno>MAX_NATION);
2655 	set_hostile_nation(attackerNationRecno);
2656 
2657 	//----------- call out defender -----------//
2658 
2659 	// only call out defender when the attacking unit is within the effective defending distance
2660 
2661 	if( misc.points_distance( attackerUnit->cur_x_loc(), attackerUnit->cur_y_loc(),
2662 		 center_x, center_y ) <= EFFECTIVE_DEFEND_TOWN_DISTANCE )
2663 	{
2664 		int loopCount=0;
2665 
2666 		while(1)
2667 		{
2668 			if( !mobilize_defender(attackerNationRecno) )
2669 				break;
2670 
2671 			err_when( loopCount++ > 1000 );
2672 		}
2673 	}
2674 
2675 	auto_defense(attackerUnitRecno);
2676 
2677 	//----- pick a race to be attacked by the attacker randomly -----//
2678 
2679 	int raceId = pick_random_race(1, 1);		// 1-pick has job people, 1-pick spies
2680 
2681 	err_when( !raceId );
2682 
2683 	//-------- town people get killed ---------//
2684 
2685 	received_hit_count += attackDamage;
2686 
2687 	if( received_hit_count >= RECEIVED_HIT_PER_KILL )
2688 	{
2689 		received_hit_count = (float) 0;
2690 
2691 		int townRecno = town_recno;
2692 
2693 		kill_town_people(raceId, attackerNationRecno);		// kill a town people
2694 
2695 		if( town_array.is_deleted(townRecno) )		// the town may have been deleted when all pop are killed
2696 			return;
2697 	}
2698 
2699 	//---- decrease resistance if this is an independent town ----//
2700 
2701 	if( town_defender_count==0 )
2702 	{
2703 		//--- Resistance/loyalty of the town people decrease if the attacking continues ---//
2704 		//
2705 		// Resistance/Loyalty decreases faster:
2706 		//
2707 		// -when there are few people in the town
2708 		// -when there is no defender
2709 		//
2710 		//---------------------------------------//
2711 
2712 		float loyaltyDec;
2713 
2714 		if( nation_recno )		// if the town belongs to a nation
2715 		{
2716 			//---- decrease loyalty of all races in the town ----//
2717 
2718 			for( raceId=1 ; raceId<=MAX_RACE ; raceId++ )
2719 			{
2720 				if( race_pop_array[raceId-1] == 0 )
2721 					continue;
2722 
2723 				if( has_linked_own_camp )		// if it is linked to one of its camp, the loyalty will decrease slower
2724 					loyaltyDec = (float) 5 / race_pop_array[raceId-1];
2725 				else
2726 					loyaltyDec = (float) 10 / race_pop_array[raceId-1];
2727 
2728 				loyaltyDec = MIN( loyaltyDec, (float) 1 );
2729 
2730 				change_loyalty( raceId, -loyaltyDec * attackDamage / (20/ATTACK_SLOW_DOWN) );
2731 			}
2732 
2733 			//--- if the resistance of all the races are zero, think_change_nation() ---//
2734 
2735 			int i;
2736 			for( i=0 ; i<MAX_RACE ; i++ )
2737 			{
2738 				if( race_loyalty_array[i] >= (float) 1 )		// values between 0 and 1 are considered as 0
2739 					break;
2740 			}
2741 
2742 			if( i==MAX_RACE )                  		// if resistance of all races drop to zero
2743 				think_surrender();
2744 		}
2745 		else						// if the town is an independent town
2746 		{
2747 			if( !attackerNationRecno )		// if independent units do not attack independent towns
2748 				return;
2749 
2750 			//---- decrease resistance of all races in the town ----//
2751 
2752 			for( raceId=1 ; raceId<=MAX_RACE ; raceId++ )
2753 			{
2754 				if( race_pop_array[raceId-1] == 0 )
2755 					continue;
2756 
2757 				loyaltyDec = (float) 10 / race_pop_array[raceId-1];		// decrease faster for independent towns than towns belonging to nations
2758 				loyaltyDec = MIN( loyaltyDec, (float) 1 );
2759 
2760 				race_resistance_array[raceId-1][attackerNationRecno-1] -= loyaltyDec * attackDamage / (20/ATTACK_SLOW_DOWN);
2761 
2762 				if( race_resistance_array[raceId-1][attackerNationRecno-1] < 0 )
2763 					race_resistance_array[raceId-1][attackerNationRecno-1] = (float) 0;
2764 			}
2765 
2766 			//--- if the resistance of all the races are zero, think_change_nation() ---//
2767 
2768 			int i;
2769 			for( i=0 ; i<MAX_RACE ; i++ )
2770 			{
2771 				if( race_resistance_array[i][attackerNationRecno-1] >= (float) 1 )
2772 					break;
2773 			}
2774 
2775 			if( i==MAX_RACE )                  		// if resistance of all races drop to zero
2776 				surrender(attackerNationRecno);
2777 		}
2778 	}
2779 
2780 	//------ reinforce troops to defend against the attack ------//
2781 
2782 	if( town_defender_count==0 && nation_recno )
2783 	{
2784 		if( attackerUnit->nation_recno != nation_recno )		// they may become the same when the town has been captured
2785 			nation_array[nation_recno]->ai_defend(attackerUnitRecno);
2786 	}
2787 }
2788 //---------- End of function Town::being_attacked -----//
2789 
2790 
2791 //--------- Begin of function Town::clear_defense_mode -------//
clear_defense_mode()2792 void Town::clear_defense_mode()
2793 {
2794 	//------------------------------------------------------------------//
2795 	// change defense unit's to non-defense mode
2796 	//------------------------------------------------------------------//
2797 	Unit *unitPtr;
2798 	for(int i=unit_array.size(); i>=1; --i)
2799 	{
2800 		if(unit_array.is_deleted(i))
2801 			continue;
2802 
2803 		unitPtr = unit_array[i];
2804 		if(!unitPtr)
2805 			continue;
2806 
2807 		err_when(unitPtr->cur_action==SPRITE_DIE || unitPtr->action_mode==ACTION_DIE || unitPtr->hit_points<=0);
2808 		if(unitPtr->in_defend_town_mode() && unitPtr->action_misc==ACTION_MISC_DEFEND_TOWN_RECNO &&
2809 			unitPtr->action_misc_para==town_recno)
2810 			unitPtr->clear_town_defend_mode(); // note: maybe, unitPtr->nation_recno != nation_recno
2811 	}
2812 }
2813 //---------- End of function Town::clear_defense_mode -----//
2814 
2815 
2816 //--------- Begin of function Town::mobilize_defender -------//
2817 //
mobilize_defender(int attackerNationRecno)2818 int Town::mobilize_defender(int attackerNationRecno)
2819 {
2820 	if( population==1 )		// do not call out defenders any more if there is only one person left in the town, otherwise the town will be gone.
2821 		return 0;
2822 
2823 	//------- pick a race to mobilize randomly --------//
2824 
2825 	int randomPersonId = misc.random(population)+1;
2826 	int popSum=0, raceId=0;
2827 
2828 	int i;
2829 	for( i=0 ; i<MAX_RACE ; i++ )
2830 	{
2831 		popSum += race_pop_array[i];
2832 
2833 		if( randomPersonId <= popSum )
2834 		{
2835 			raceId = i+1;
2836 			break;
2837 		}
2838 	}
2839 
2840 	if( raceId==0 )
2841 		return 0;
2842 
2843 	//---- check if the current loyalty allows additional defender ----//
2844 	//
2845 	// if the loyalty is high, then there will be more town defenders
2846 	//
2847 	//-----------------------------------------------------------------//
2848 
2849 	float curLoyalty;
2850 
2851 	if( nation_recno )
2852 		curLoyalty = race_loyalty_array[raceId-1];
2853 	else
2854 	{
2855 		if( !attackerNationRecno )		// if independent units do not attack independent towns
2856 			return 0;
2857 
2858 		curLoyalty = race_resistance_array[raceId-1][attackerNationRecno-1];
2859 	}
2860 
2861 	//--- only mobilize new defenders when there aren't too many existing ones ---//
2862 
2863 	if( rebel_recno )		// if this town is controlled by rebels
2864 	{
2865 		if( curLoyalty	< town_defender_count*2 )		// rebel towns have more rebel units coming out to defend
2866 			return 0;
2867 	}
2868 	else
2869 	{
2870 		if( curLoyalty	< town_defender_count*5 )		// if no more defenders are allowed for the current loyalty
2871 			return 0;
2872 	}
2873 
2874 	//----- check if the loyalty/resistance is high enough -----//
2875 
2876 	if( nation_recno )
2877 	{
2878 		if( curLoyalty < MIN_NATION_DEFEND_LOYALTY )
2879 			return 0;
2880 	}
2881 	else
2882 	{
2883 		if( curLoyalty < MIN_INDEPENDENT_DEFEND_LOYALTY )
2884 			return 0;
2885 	}
2886 
2887 	//------ check if there are peasants to defend ------//
2888 
2889 	if( recruitable_race_pop(raceId, 0) == 0 ) 	// 0-don't recruit spies
2890 		return 0;
2891 
2892 	//---------- create a defender unit --------------------//
2893 
2894 	//--------------------------------------------------------------//
2895 	//									 loyalty of that race
2896 	// decrease loyalty by: -------------------------------
2897 	//								no. of town people of that race
2898 	//--------------------------------------------------------------//
2899 
2900 	float loyaltyDec = curLoyalty/race_pop_array[raceId-1];  // decrease in loyalty or resistance
2901 
2902 	if( nation_recno )
2903 	{
2904 		change_loyalty( raceId, -loyaltyDec );
2905 	}
2906 	else
2907 	{
2908 		for( i=0 ; i<MAX_NATION ; i++ )
2909 			race_resistance_array[raceId-1][i] -= loyaltyDec;
2910 	}
2911 
2912 	//------- mobilize jobless people if there are any -------//
2913 
2914 	int unitRecno = mobilize_town_people(raceId, 1, 0);		// 1-dec pop, 0-don't mobilize spy town people
2915 
2916 	Unit* unitPtr = unit_array[unitRecno];
2917 
2918 	err_when( town_array.is_deleted(town_recno) );
2919 
2920 	unitPtr->set_mode( UNIT_MODE_DEFEND_TOWN, town_recno );
2921 
2922 	unitPtr->skill.skill_level = (char) loyaltyDec;	// if the unit is a town defender, this var is temporary used for storing the loyalty that will be added back to the town if the defender returns to the town
2923 
2924 	int combatLevel = town_combat_level + misc.random(20) - 10;		// -10 to +10 random difference
2925 
2926 	combatLevel = MIN(combatLevel, 100);
2927 	combatLevel = MAX(combatLevel, 10);
2928 
2929 	unitPtr->set_combat_level(combatLevel);
2930 
2931 	//-----------------------------------------------------//
2932 	// enable unit defend_town mode
2933 	//-----------------------------------------------------//
2934 
2935 	unitPtr->stop2();
2936 	unitPtr->action_mode2 = ACTION_DEFEND_TOWN_DETECT_TARGET;
2937 	unitPtr->action_para2 = UNIT_DEFEND_TOWN_DETECT_COUNT;
2938 
2939 	unitPtr->action_misc 	  = ACTION_MISC_DEFEND_TOWN_RECNO;
2940 	unitPtr->action_misc_para = town_recno;
2941 
2942 	town_defender_count++;
2943 
2944 	//------- if this town is controlled by rebels --------//
2945 
2946 	if( rebel_recno )
2947 		rebel_array[rebel_recno]->mobile_rebel_count++;		// increase the no. of mobile rebel units
2948 
2949 	return unitRecno;
2950 }
2951 //---------- End of function Town::mobilize_defender -----//
2952 
2953 
2954 //--------- Begin of function Town::reduce_defender_count -------//
2955 
reduce_defender_count()2956 void Town::reduce_defender_count()
2957 {
2958 	if( --town_defender_count==0 )
2959 		independ_town_nation_relation = 0;
2960 
2961 	//------- if this town is controlled by rebels --------//
2962 
2963 	if( rebel_recno )
2964 		rebel_array[rebel_recno]->mobile_rebel_count--;		// decrease the no. of mobile rebel units
2965 }
2966 //---------- End of function Town::reduce_defender_count -----//
2967 
2968 
2969 //--------- Begin of function Town::kill_town_people -------//
2970 //
kill_town_people(int raceId,int attackerNationRecno)2971 void Town::kill_town_people(int raceId, int attackerNationRecno)
2972 {
2973 	if( !raceId )
2974 		raceId = pick_random_race(1, 1);		// 1-pick has job unit, 1-pick spies
2975 
2976 	if( !raceId )
2977 		return ;
2978 
2979 	//---- jobless town people get killed first, if all jobless are killed, then kill workers ----//
2980 
2981 	if( recruitable_race_pop(raceId,1)==0 )
2982 	{
2983 		if( !unjob_town_people(raceId, 1) )				// unjob overseer if the only person left is a overseer
2984 			return;
2985 
2986 		err_when( recruitable_race_pop(raceId,1)==0 );
2987 	}
2988 
2989 	//------ the killed unit can be a spy -----//
2990 
2991 	if( misc.random(recruitable_race_pop(raceId,1)) < race_spy_count_array[raceId-1] )
2992 	{
2993 		int spyRecno = spy_array.find_town_spy(town_recno, raceId, misc.random(race_spy_count_array[raceId-1])+1 );
2994 
2995 		spy_array.del_spy(spyRecno);
2996 	}
2997 
2998 	//---- killing civilian people decreases loyalty -----//
2999 
3000 	if( nation_recno && attackerNationRecno )					// your people's loyalty decreases because you cannot protect them.
3001 		nation_array[nation_recno]->civilian_killed(raceId, -1);		// but only when your units are killed by enemies, neutral disasters are not counted
3002 
3003 	if( attackerNationRecno )        //	the attacker's people's loyalty decreases because of the killing actions.
3004 		nation_array[attackerNationRecno]->civilian_killed(raceId, 2);		// the nation is the attacking one
3005 
3006 	// -------- sound effect ---------//
3007 
3008 	se_res.sound( center_x, center_y, 1, 'R', raceId, "DIE" );
3009 
3010 	//-------- decrease population now --------//
3011 
3012 	dec_pop( raceId, 0 );		// 0-doesn't have a job
3013 }
3014 //---------- End of function Town::kill_town_people -----//
3015 
3016 
3017 //--------- Begin of function Town::unjob_town_people -------//
3018 //
3019 // Make one town people of the specific race jobless.
3020 // Workers are processed first, overseers are processed next.
3021 //
3022 // <int> raceId		  - race id.
3023 // <int> unjobOverseer - whether unjob overseer or not
3024 // <int> killOverseer  - kill the overseer if possible
3025 //
3026 // return: <int> a town person has been made jobless
3027 //
unjob_town_people(int raceId,int unjobOverseer,int killOverseer)3028 int Town::unjob_town_people(int raceId, int unjobOverseer, int killOverseer)
3029 {
3030 	//---- if no jobless people, workers will then get killed -----//
3031 
3032 	int 	i, workerId;
3033 	Firm* firmPtr;
3034 	Worker* workerPtr;
3035 
3036 	int racePop = jobless_race_pop_array[raceId-1];
3037 
3038 	for( i=linked_firm_count-1 ; i>=0 ; i-- )
3039 	{
3040 		firmPtr = firm_array[linked_firm_array[i]];
3041 
3042 		//------- scan for workers -----------//
3043 
3044 		workerPtr=firmPtr->worker_array;
3045 
3046 		for( workerId=1 ; workerId<=firmPtr->worker_count ; workerId++, workerPtr++ )
3047 		{
3048 			//--- if the worker lives in this town ----//
3049 
3050 			if( workerPtr->race_id == raceId &&
3051 				 workerPtr->town_recno == town_recno )
3052 			{
3053 				if(!firmPtr->resign_worker(workerId))
3054 					return 0;
3055 
3056 				err_when(population>MAX_TOWN_POPULATION);
3057 				err_when( jobless_race_pop_array[raceId-1] != racePop+1 );
3058 				return 1;
3059 			}
3060 		}
3061 	}
3062 
3063 	//----- if no worker killed, try to kill overseers ------//
3064 
3065 	if( unjobOverseer )
3066 	{
3067 		Unit* overseerUnit;
3068 
3069 		for( i=linked_firm_count-1 ; i>=0 ; i-- )
3070 		{
3071 			firmPtr = firm_array[linked_firm_array[i]];
3072 
3073 			//------- scan for overseer -----------//
3074 
3075 			if( firmPtr->overseer_recno )
3076 			{
3077 				//--- if the overseer lives in this town ----//
3078 
3079 				overseerUnit = unit_array[firmPtr->overseer_recno];
3080 
3081 				if( overseerUnit->race_id == raceId &&
3082 					 firmPtr->overseer_town_recno == town_recno )
3083 				{
3084 					if(killOverseer)
3085 						firmPtr->kill_overseer();
3086 					else
3087 					{
3088 						int overseerUnitRecno = firmPtr->overseer_recno;
3089 						Unit *unitPtr = unit_array[overseerUnitRecno];
3090 						firmPtr->assign_overseer(0);
3091 						if(!unit_array.is_deleted(overseerUnitRecno) && unitPtr->is_visible())
3092 							unit_array.disappear_in_town(overseerUnitRecno, town_recno);
3093 					}
3094 					err_when( jobless_race_pop_array[raceId-1] != racePop+1 );
3095 					return 1;
3096 				}
3097 			}
3098 		}
3099 	}
3100 
3101 	return 0;
3102 }
3103 //---------- End of function Town::unjob_town_people -----//
3104 
3105 
3106 //--------- Begin of function Town::distribute_demand ---------//
3107 //
3108 // Distribute demands among
3109 //
distribute_demand()3110 void Town::distribute_demand()
3111 {
3112 	#define MAX_ACTIVE_MARKET_COUNT     20
3113 
3114 	//------------ define struct MarketInfo --------------//
3115 
3116 	struct MarketGoodsInfo
3117 	{
3118 		FirmMarket* market_ptr[MAX_ACTIVE_MARKET_COUNT];
3119 		float			total_supply;
3120 		float			total_own_supply;
3121 		short			market_count;
3122 	};
3123 
3124    //------ scan for a firm to input raw materials --------//
3125 
3126    int					i, j;
3127 	Firm*					firmPtr;
3128 	MarketGoodsInfo	marketGoodsInfoArray[MAX_PRODUCT];
3129 	MarketGoodsInfo*  marketGoodsInfo;
3130 	float					thisSupply;
3131 	MarketGoods*		marketGoods;
3132 
3133 	memset( marketGoodsInfoArray, 0, sizeof(marketGoodsInfoArray) );
3134 
3135 	//------- count the no. of market place that are near to this town ----//
3136 
3137 	for( int linkedFirmId=0 ; linkedFirmId<linked_firm_count ; linkedFirmId++ )
3138 	{
3139 		firmPtr = firm_array[ linked_firm_array[linkedFirmId] ];
3140 
3141 		if( firmPtr->firm_id != FIRM_MARKET )
3142 			continue;
3143 
3144 		if( linked_firm_enable_array[linkedFirmId] != LINK_EE )
3145 			continue;
3146 
3147 		firmPtr = firm_array[linked_firm_array[linkedFirmId]];
3148 
3149 		//---------- process market -------------//
3150 
3151 		for( i=0 ; i<MAX_PRODUCT ; i++ )
3152 		{
3153 			marketGoods = ((FirmMarket*)firmPtr)->market_product_array[i];
3154 			marketGoodsInfo = marketGoodsInfoArray+i;
3155 
3156 			if( marketGoods && marketGoodsInfo->market_count < MAX_ACTIVE_MARKET_COUNT )
3157 			{
3158 				thisSupply  = marketGoods->stock_qty;
3159 
3160 				marketGoodsInfo->market_ptr[marketGoodsInfo->market_count] = (FirmMarket*) firmPtr;
3161 
3162 				marketGoodsInfo->total_supply += thisSupply;
3163 
3164 				if( firmPtr->nation_recno == nation_recno )				// vars for later use, so that towns will always try to buy goods from their own markets first.
3165 					marketGoodsInfo->total_own_supply += thisSupply;
3166 
3167 				marketGoodsInfo->market_count++;
3168 			}
3169 		}
3170 	}
3171 
3172 	//-- set the monthly demand of the town on each product --//
3173 
3174 	float townDemand = (float) jobless_population * (float) PEASANT_GOODS_MONTH_DEMAND
3175 							 + (float) worker_population() * (float) WORKER_GOODS_MONTH_DEMAND;
3176 
3177 	float ownShareDemand;		// the share of demand for own markets
3178 
3179 	//---------- sell goods now -----------//
3180 
3181 	FirmMarket* firmMarket;
3182 
3183 	for( i=0 ; i<MAX_PRODUCT ; i++ )
3184 	{
3185 		marketGoodsInfo = marketGoodsInfoArray+i;
3186 
3187 		for( j=0 ; j<marketGoodsInfo->market_count ; j++ )
3188 		{
3189 			//----------------------------------//
3190 			//
3191 			// If the totalSupply < town demand:
3192 			// a market's demand = its_supply + (town_demand-totalSupply) / market_count
3193 			//
3194 			// If the totalSupply > town demand:
3195 			// a market's demand = town_demand * its_supply / totalSupply
3196 			//
3197 			//----------------------------------//
3198 
3199 			firmMarket = marketGoodsInfo->market_ptr[j];
3200 
3201 			marketGoods = firmMarket->market_product_array[i];
3202 
3203 			if( marketGoods )
3204 			{
3205 				//---- if the demand is larger than the supply -----//
3206 
3207 				if( marketGoodsInfo->total_supply <= townDemand )
3208 				{
3209 					marketGoods->month_demand += marketGoods->stock_qty +
3210 														 (townDemand - marketGoodsInfo->total_supply)
3211 														 / marketGoodsInfo->market_count;				// evenly distribute the excessive demand on all markets
3212 				}
3213 				else //---- if the supply is larger than the demand -----//
3214 				{
3215 					//--- towns always try to buy goods from their own markets first ---//
3216 
3217 					ownShareDemand = MIN(townDemand, marketGoodsInfo->total_own_supply);
3218 
3219 					if( firmMarket->nation_recno == nation_recno )
3220 					{
3221 						if (marketGoodsInfo->total_own_supply > 0.0f) // if total_own_supply is 0 then ownShareDemand is also 0 and we put no demand on the product
3222 							marketGoods->month_demand += ownShareDemand * marketGoods->stock_qty / marketGoodsInfo->total_own_supply;
3223 					}
3224 					else
3225 					{
3226 						// Note: total_supply > 0.0f, because else the first case above (demand larger than supply) will be triggered
3227 						marketGoods->month_demand += (townDemand-ownShareDemand) * marketGoods->stock_qty / marketGoodsInfo->total_supply;
3228 					}
3229 				}
3230 			}
3231 		}
3232 	}
3233 }
3234 //----------- End of function Town::distribute_demand -----------//
3235 
3236 
3237 //------- Begin of function Town::setup_link ---------//
3238 //
setup_link()3239 void Town::setup_link()
3240 {
3241 	//-----------------------------------------------------------------------------//
3242 	// check the connected firms location and structure if ai_link_checked is true
3243 	//-----------------------------------------------------------------------------//
3244 	if(ai_town)
3245 		ai_link_checked = 0;
3246 
3247 	//----- build town-to-firm link relationship -------//
3248 
3249 	int   firmRecno, defaultLinkStatus;
3250 	Firm* firmPtr;
3251 	FirmInfo* firmInfo;
3252 
3253 	linked_firm_count = 0;
3254 
3255 	for( firmRecno=firm_array.size() ; firmRecno>0 ; firmRecno-- )
3256 	{
3257 		if( firm_array.is_deleted(firmRecno) )
3258 			continue;
3259 
3260 		firmPtr  = firm_array[firmRecno];
3261 		firmInfo = firm_res[firmPtr->firm_id];
3262 
3263 		if( !firmInfo->is_linkable_to_town )
3264 			continue;
3265 
3266 		//---------- check if the firm is close enough to this firm -------//
3267 
3268 		if( misc.points_distance( firmPtr->center_x, firmPtr->center_y,
3269 			 center_x, center_y ) > EFFECTIVE_FIRM_TOWN_DISTANCE )
3270 		{
3271 			continue;
3272 		}
3273 
3274 		//------ check if both are on the same terrain type ------//
3275 
3276 		if( (world.get_loc(firmPtr->center_x, firmPtr->center_y)->is_plateau()==1)
3277 			 != (world.get_loc(center_x, center_y)->is_plateau()==1) )
3278 		{
3279 			continue;
3280 		}
3281 
3282 		//------- determine the default link status ------//
3283 
3284 		if( firmPtr->nation_recno == nation_recno )   // if the two firms are of the same nation, get the default link status which is based on the types of the firms
3285 			defaultLinkStatus = LINK_EE;
3286 		else
3287 			defaultLinkStatus = LINK_DD;			//	if the two firms are of different nations, default link status is both side disabled
3288 
3289 		//----- a town cannot disable a camp's link to it ----//
3290 
3291 		if( firmPtr->firm_id==FIRM_CAMP ) 		// for capturing the town
3292 			defaultLinkStatus = LINK_EE;
3293 
3294 		//-------- add the link now -------//
3295 
3296 		if( linked_firm_count < MAX_LINKED_FIRM_TOWN )
3297 		{
3298 			linked_firm_array[linked_firm_count] = firmRecno;
3299 			linked_firm_enable_array[linked_firm_count] = defaultLinkStatus;
3300 
3301 			linked_firm_count++;
3302 		}
3303 		else
3304 		{
3305 			err_here();
3306 		}
3307 
3308 		if( firmPtr->linked_town_count < MAX_LINKED_TOWN_TOWN )
3309 		{
3310 			if( defaultLinkStatus==LINK_ED )		// Reverse the link status for the opposite linker
3311 				defaultLinkStatus=LINK_DE;
3312 
3313 			else if( defaultLinkStatus==LINK_DE )
3314 				defaultLinkStatus=LINK_ED;
3315 
3316 			firmPtr->linked_town_array[firmPtr->linked_town_count] = town_recno;
3317 			firmPtr->linked_town_enable_array[firmPtr->linked_town_count] = defaultLinkStatus;
3318 
3319 			firmPtr->linked_town_count++;
3320 			if(firmPtr->firm_ai)
3321 				firmPtr->ai_link_checked = 0;
3322 		}
3323 		else
3324 		{
3325 			err_here();
3326 		}
3327 	}
3328 
3329 	//----- build town-to-town link relationship -------//
3330 
3331 	linked_town_count = 0;
3332 
3333 	int   townRecno;
3334 	Town* townPtr;
3335 
3336 	for( townRecno=town_array.size() ; townRecno>0 ; townRecno-- )
3337 	{
3338 		if( town_array.is_deleted(townRecno) || townRecno==town_recno )
3339 			continue;
3340 
3341 		townPtr = town_array[townRecno];
3342 
3343 		//------ check if the town is close enough to this firm -------//
3344 
3345 		if( misc.points_distance( townPtr->center_x, townPtr->center_y,
3346 			 center_x, center_y ) > EFFECTIVE_TOWN_TOWN_DISTANCE )
3347 		{
3348 			continue;
3349 		}
3350 
3351 		//------ check if both are on the same terrain type ------//
3352 
3353 		if( (world.get_loc(townPtr->center_x, townPtr->center_y)->is_plateau()==1)
3354 			 != (world.get_loc(center_x, center_y)->is_plateau()==1) )
3355 		{
3356 			continue;
3357 		}
3358 
3359 		//------- determine the default link status ------//
3360 
3361 		defaultLinkStatus = LINK_EE;
3362 
3363 		//-------- add the link now -------//
3364 
3365 		if( linked_town_count < MAX_LINKED_TOWN_TOWN )
3366 		{
3367 			linked_town_array[linked_town_count] = townRecno;
3368 			linked_town_enable_array[linked_town_count] = defaultLinkStatus;
3369 
3370 			linked_town_count++;
3371 		}
3372 		else
3373 		{
3374 			err_here();
3375 		}
3376 
3377 		if( townPtr->linked_town_count < MAX_LINKED_TOWN_TOWN )
3378 		{
3379 			if( defaultLinkStatus==LINK_ED )		// Reverse the link status for the opposite linker
3380 				defaultLinkStatus=LINK_DE;
3381 
3382 			else if( defaultLinkStatus==LINK_DE )
3383 				defaultLinkStatus=LINK_ED;
3384 
3385 			townPtr->linked_town_array[townPtr->linked_town_count] = town_recno;
3386 			townPtr->linked_town_enable_array[townPtr->linked_town_count] = defaultLinkStatus;
3387 
3388 			townPtr->linked_town_count++;
3389 			if(townPtr->ai_town)
3390 				townPtr->ai_link_checked = 0;
3391 		}
3392 		else
3393 		{
3394 			err_here();
3395 		}
3396 	}
3397 }
3398 //-------- End of function Town::setup_link -----------//
3399 
3400 
3401 //------- Begin of function Town::release_link ---------//
3402 //
release_link()3403 void Town::release_link()
3404 {
3405    int i;
3406 	Firm *firmPtr;
3407 	Town *townPtr;
3408 
3409    //------ release linked firms ------//
3410 
3411 	for( i=0 ; i<linked_firm_count ; i++ )
3412 	{
3413 		firmPtr = firm_array[linked_firm_array[i]];
3414 		firmPtr->release_town_link(town_recno);
3415 
3416 		if(firmPtr->firm_ai)
3417 			firmPtr->ai_link_checked = 0;
3418    }
3419 
3420    //------ release linked towns ------//
3421 
3422    for( i=0 ; i<linked_town_count ; i++ )
3423    {
3424 		townPtr = town_array[linked_town_array[i]];
3425 		townPtr->release_town_link(town_recno);
3426 
3427 		if(townPtr->ai_town)
3428 			townPtr->ai_link_checked = 0;
3429    }
3430 }
3431 //-------- End of function Town::release_link -----------//
3432 
3433 
3434 //------- Begin of function Town::release_firm_link ---------//
3435 //
release_firm_link(int releaseFirmRecno)3436 void Town::release_firm_link(int releaseFirmRecno)
3437 {
3438 	//-----------------------------------------------------------------------------//
3439 	// check the connected firms location and structure if ai_link_checked is true
3440 	//-----------------------------------------------------------------------------//
3441 	if(ai_town)
3442 		ai_link_checked = 0;
3443 
3444 	for( int i=0 ; i<linked_firm_count ; i++ )
3445    {
3446       if( linked_firm_array[i] == releaseFirmRecno )
3447       {
3448 			err_when( linked_firm_count > MAX_LINKED_FIRM_TOWN );
3449 
3450 			misc.del_array_rec( linked_firm_array		  , linked_firm_count, sizeof(linked_firm_array[0]), i+1 );
3451 			misc.del_array_rec( linked_firm_enable_array, linked_firm_count, sizeof(linked_firm_enable_array[0]), i+1 );
3452 			linked_firm_count--;
3453 			return;
3454 		}
3455 	}
3456 
3457 	err_here();
3458 }
3459 //------- End of function Town::release_firm_link ---------//
3460 
3461 
3462 //------- Begin of function Town::release_town_link ---------//
3463 //
release_town_link(int releaseTownRecno)3464 void Town::release_town_link(int releaseTownRecno)
3465 {
3466 	//-----------------------------------------------------------------------------//
3467 	// check the connected firms location and structure if ai_link_checked is true
3468 	//-----------------------------------------------------------------------------//
3469 	if(ai_town)
3470 		ai_link_checked = 0;
3471 
3472 	for( int i=0 ; i<linked_town_count ; i++ )
3473 	{
3474 		if( linked_town_array[i] == releaseTownRecno )
3475 		{
3476 			err_when( linked_town_count > MAX_LINKED_TOWN_TOWN );
3477 
3478 			misc.del_array_rec( linked_town_array		  , linked_town_count, sizeof(linked_town_array[0]), i+1 );
3479 			misc.del_array_rec( linked_town_enable_array, linked_town_count, sizeof(linked_town_enable_array[0]), i+1 );
3480 			linked_town_count--;
3481 			return;
3482 		}
3483 	}
3484 
3485 	err_here();
3486 }
3487 //------- End of function Town::release_town_link ---------//
3488 
3489 
3490 //------- Begin of function Town::toggle_firm_link ---------//
3491 //
3492 // Toggle the firm link of the current town.
3493 //
3494 // <int> linkId - id. of the link
3495 // <int> toggleFlag - 1-enable, 0-disable
3496 // <char> remoteAction - remote action type
3497 // [int] setBoth - if this is 1, it will set the link to either LINK_EE or LINK_DD (and no LINK_ED or LINK_DD)
3498 //						 if this is -1, the only one side will be set even though the nation recno of the firm and town are the same
3499 //					    (default: 0)
3500 //
toggle_firm_link(int linkId,int toggleFlag,char remoteAction,int setBoth)3501 void Town::toggle_firm_link(int linkId, int toggleFlag, char remoteAction, int setBoth)
3502 {
3503 	if( !remoteAction && remote.is_enable() )
3504 	{
3505 		// packet structure : <town recno> <link Id> <toggle Flag>
3506 		short *shortPtr = (short *)remote.new_send_queue_msg(MSG_TOWN_TOGGLE_LINK_FIRM, 3*sizeof(short));
3507 		shortPtr[0] = town_recno;
3508 		shortPtr[1] = linkId;
3509 		shortPtr[2] = toggleFlag;
3510 		return;
3511 	}
3512 
3513 	Firm* linkedFirm = firm_array[linked_firm_array[linkId-1]];
3514 	int 	linkedNationRecno = linkedFirm->nation_recno;
3515 
3516 	int sameNation = linkedNationRecno == nation_recno ||		// if one of the linked end is an indepdendent firm/nation, consider this link as a single nation link
3517 						  linkedNationRecno == 0 ||
3518 						  nation_recno == 0;
3519 
3520 	if( toggleFlag )
3521 	{
3522 		if( (sameNation && setBoth==0) || setBoth==1 )		// 0 if setBoth == -1
3523 			linked_firm_enable_array[linkId-1] = LINK_EE;
3524 		else
3525 			linked_firm_enable_array[linkId-1] |= LINK_ED;
3526 	}
3527 	else
3528 	{
3529 		if( (sameNation && setBoth==0) || setBoth==1 )
3530 			linked_firm_enable_array[linkId-1] = LINK_DD;
3531 		else
3532 			linked_firm_enable_array[linkId-1] &= ~LINK_ED;
3533 	}
3534 
3535 	//------ set the linked flag of the opposite firm -----//
3536 
3537 	Firm* firmPtr = firm_array[ linked_firm_array[linkId-1] ];
3538 	int   i;
3539 
3540 	for(i=firmPtr->linked_town_count-1; i>=0; i--)
3541 	{
3542 		if( firmPtr->linked_town_array[i] == town_recno )
3543 		{
3544 			if( toggleFlag )
3545 			{
3546 				if( (sameNation && setBoth==0) || setBoth==1 )
3547 					firmPtr->linked_town_enable_array[i]  = LINK_EE;
3548 				else
3549 					firmPtr->linked_town_enable_array[i] |= LINK_DE;
3550 			}
3551 			else
3552 			{
3553 				if( (sameNation && setBoth==0) || setBoth==1 )
3554 					firmPtr->linked_town_enable_array[i]  = LINK_DD;
3555 				else
3556 					firmPtr->linked_town_enable_array[i] &= ~LINK_DE;
3557 			}
3558 
3559 			break;
3560 		}
3561 	}
3562 
3563 	//-------- update the town's influence --------//
3564 
3565 	if( nation_recno==0 )
3566 		update_target_resistance();
3567 
3568 	//--- redistribute demand if a link to market place has been toggled ---//
3569 
3570 	if( linkedFirm->firm_id == FIRM_MARKET )
3571 		town_array.distribute_demand();
3572 }
3573 //-------- End of function Town::toggle_firm_link ---------//
3574 
3575 
3576 //------- Begin of function Town::toggle_town_link ---------//
3577 //
3578 // Toggle the town link of the current town.
3579 //
3580 // NOTE: This function is not used
3581 //
3582 // <int> linkId - id. of the link
3583 // <int> toggleFlag - 1-enable, 0-disable
3584 // [int] setBoth - if this is 1, it will set the link to either LINK_EE or LINK_DD (and no LINK_ED or LINK_DD)
3585 //						 if this is -1, the only one side will be set even though the nation recno of the firm and town are the same
3586 //					    (default: 0)
3587 //
toggle_town_link(int linkId,int toggleFlag,char remoteAction,int setBoth)3588 void Town::toggle_town_link(int linkId, int toggleFlag, char remoteAction, int setBoth)
3589 {
3590 	// Function is unused, and not updated to support town networks.
3591 	return;
3592 
3593 	if( !remoteAction && remote.is_enable() )
3594 	{
3595 		// packet structure : <town recno> <link Id> <toggle Flag>
3596 		short *shortPtr = (short *)remote.new_send_queue_msg(MSG_TOWN_TOGGLE_LINK_TOWN, 3*sizeof(short));
3597 		shortPtr[0] = town_recno;
3598 		shortPtr[1] = linkId;
3599 		shortPtr[2] = toggleFlag;
3600 		return;
3601 	}
3602 
3603 	int linkedNationRecno = town_array[linked_town_array[linkId-1]]->nation_recno == nation_recno;
3604 
3605 	int sameNation = linkedNationRecno == nation_recno ||		// if one of the linked end is an indepdendent firm/nation, consider this link as a single nation link
3606 						  linkedNationRecno == 0 ||
3607 						  nation_recno == 0;
3608 
3609 	if( toggleFlag )
3610 	{
3611 		if( (sameNation && setBoth==0) || setBoth==1 )
3612 			linked_town_enable_array[linkId-1]  = LINK_EE;
3613 		else
3614 			linked_town_enable_array[linkId-1] |= LINK_ED;
3615 	}
3616 	else
3617 	{
3618 		if( (sameNation && setBoth==0) || setBoth==1 )
3619 			linked_town_enable_array[linkId-1]  = LINK_DD;
3620 		else
3621 			linked_town_enable_array[linkId-1] &= ~LINK_ED;
3622 	}
3623 
3624 	//------ set the linked flag of the opposite town -----//
3625 
3626 	Town* townPtr = town_array[ linked_town_array[linkId-1] ];
3627 	int   i;
3628 
3629 	for(i=townPtr->linked_town_count-1; i>=0; i--)
3630 	{
3631 		if( townPtr->linked_town_array[i] == town_recno )
3632 		{
3633 			if( toggleFlag )
3634 			{
3635 				if( (sameNation && setBoth==0) || setBoth==1 )
3636 					townPtr->linked_town_enable_array[i]  = LINK_EE;
3637 				else
3638 					townPtr->linked_town_enable_array[i] |= LINK_DE;
3639 			}
3640 			else
3641 			{
3642 				if( (sameNation && setBoth==0) || setBoth==1 )
3643 					townPtr->linked_town_enable_array[i]  = LINK_DD;
3644 				else
3645 					townPtr->linked_town_enable_array[i] &= ~LINK_DE;
3646 			}
3647 
3648 			break;
3649 		}
3650 	}
3651 }
3652 //-------- End of function Town::toggle_town_link ---------//
3653 
3654 
3655 //-------- Begin of function Town::linked_active_camp_count ------//
3656 //
3657 // No. of linked military camp to this town which has a general in it.
3658 //
linked_active_camp_count()3659 int Town::linked_active_camp_count()
3660 {
3661 	int 	i, linkedCount=0;
3662 	Firm* firmPtr;
3663 
3664 	for( i=0 ; i<linked_firm_count ; i++ )
3665 	{
3666 		if( linked_firm_enable_array[i] == LINK_EE )
3667 		{
3668 			firmPtr = firm_array[linked_firm_array[i]];
3669 
3670 			if( firmPtr->firm_id == FIRM_CAMP &&
3671 				 firmPtr->overseer_recno )
3672 			{
3673 				linkedCount++;
3674 			}
3675 		}
3676 	}
3677 
3678 	return linkedCount;
3679 }
3680 //---------- End of function Town::linked_active_camp_count --------//
3681 
3682 
3683 //------- Begin of function Town::auto_defense ---------//
3684 //
auto_defense(short targetRecno)3685 void Town::auto_defense(short targetRecno)
3686 {
3687 	Firm *firmPtr;
3688 	FirmCamp *campPtr;
3689 	short townRecno = town_recno;
3690 
3691 	for(int i=linked_firm_count-1; i>=0; i--)
3692 	{
3693 		err_when(!linked_firm_array[i] || firm_array.is_deleted(linked_firm_array[i]));
3694 		firmPtr = firm_array[linked_firm_array[i]];
3695 
3696 		if(firmPtr->nation_recno!=nation_recno || firmPtr->firm_id!=FIRM_CAMP)
3697 			continue;
3698 
3699 		//-------------------------------------------------------//
3700 		// the firm is a military camp of our nation
3701 		//-------------------------------------------------------//
3702 		campPtr = firmPtr->cast_to_FirmCamp();
3703 		campPtr->defense(targetRecno);
3704 
3705 		if(town_array.is_deleted(townRecno))
3706 			break; // the last unit in the town has be mobilized
3707 	}
3708 }
3709 //-------- End of function Town::auto_defense ---------//
3710 
3711 
3712 //-------- Begin of function Town::cancel_train_unit ------//
cancel_train_unit()3713 void Town::cancel_train_unit()
3714 {
3715 	if( train_unit_recno )
3716 	{
3717 		//### begin alex 17/3 ###//
3718 		//unit_array.disappear_in_town(train_unit_recno, town_recno);
3719 		//train_unit_recno = 0;
3720 
3721 		err_when(train_unit_recno==0);
3722 		Unit *unitPtr = unit_array[train_unit_recno];
3723 		if(unitPtr->spy_recno && unitPtr->skill.skill_id) // check whether the unit is already a spy before training
3724 		{
3725 			spy_array[unitPtr->spy_recno]->set_place(SPY_TOWN, town_recno);
3726 			unitPtr->spy_recno = 0;		// reset it so Unit::deinit() won't delete the spy
3727 		}
3728 
3729 		unit_array.disappear_in_town(train_unit_recno, town_recno);
3730 		train_unit_recno = 0;
3731 		//#### end alex 17/3 ####//
3732 	}
3733 }
3734 //----------- End of function Town::cancel_train_unit -----------//
3735 
3736 
3737 //-------- Begin of function Town::auto_set_layout ------//
3738 //
auto_set_layout()3739 void Town::auto_set_layout()
3740 {
3741 /*
3742 	//------ debugging code -----//
3743 
3744 	static int lastLayoutId=0;
3745 
3746 	if( ++lastLayoutId > town_res.town_layout_count )
3747 		lastLayoutId=1;
3748 
3749 	layout_id = lastLayoutId;
3750 */
3751 	//------------------//
3752 
3753 	layout_id = think_layout_id();
3754 
3755 	err_when( !layout_id );
3756 
3757 	TownLayout* townLayout = town_res.get_layout(layout_id);
3758 	TownSlot*   firstTownSlot = town_res.get_slot(townLayout->first_slot_recno);
3759 	short			raceNeedBuildCount[MAX_RACE];
3760 
3761 	memset( slot_object_id_array, 0, sizeof(slot_object_id_array) );
3762 	memset( max_race_pop_array , 0, sizeof(max_race_pop_array) );
3763 	memset( raceNeedBuildCount, 0, sizeof(raceNeedBuildCount) );
3764 
3765 	int i;
3766 	for( i=0 ; i<MAX_RACE ; i++ )
3767 	{
3768 		if( race_pop_array[i] > 0 )
3769 			raceNeedBuildCount[i] += (race_pop_array[i]-1)/POPULATION_PER_HOUSE+1;
3770 	}
3771 
3772 	//--- assign the first house to each race, each present race will at least have one house ---//
3773 
3774 	int firstRaceId = random_race();		// random match
3775 	int raceId = firstRaceId;
3776 
3777 	for( i=0 ; i<townLayout->slot_count ; i++ )
3778 	{
3779 		if( firstTownSlot[i].build_type == TOWN_OBJECT_HOUSE )
3780 		{
3781 			int loopCount=0;
3782 
3783 			while(1)	// next race
3784 			{
3785 				if( ++raceId > MAX_RACE )
3786 					raceId = 1;
3787 
3788 				if( raceId == (firstRaceId==MAX_RACE)?1:(firstRaceId+1) )		// finished the first house for all races
3789 					goto label_distribute_house;
3790 
3791 				if( raceNeedBuildCount[raceId-1] > 0 )  // if this race need buildings, skip all races that do not need buildings
3792 					break;
3793 
3794 				err_when( loopCount++ > 1000 );
3795 			}
3796 
3797 			slot_object_id_array[i] = town_res.scan_build( townLayout->first_slot_recno+i, raceId);
3798 
3799 			raceNeedBuildCount[raceId-1]--;
3800 			max_race_pop_array[raceId-1] += POPULATION_PER_HOUSE;
3801 		}
3802 	}
3803 
3804 	err_when( raceId != firstRaceId );		// some races are not assigned with a house
3805 
3806 	//------- distribute the remaining houses -------//
3807 
3808 label_distribute_house:
3809 
3810 	int bestRaceId, maxNeedBuildCount;
3811 
3812 	for( i=0 ; i<townLayout->slot_count ; i++ )
3813 	{
3814 		if( firstTownSlot[i].build_type == TOWN_OBJECT_HOUSE && !slot_object_id_array[i] )
3815 		{
3816 			bestRaceId=0;
3817 			maxNeedBuildCount=0;
3818 
3819 			for( raceId=1 ; raceId<=MAX_RACE ; raceId++ )
3820 			{
3821 				if( raceNeedBuildCount[raceId-1] > maxNeedBuildCount )
3822 				{
3823 					bestRaceId = raceId;
3824 					maxNeedBuildCount = raceNeedBuildCount[raceId-1];
3825 				}
3826 			}
3827 
3828 			if( !bestRaceId )		// all races have assigned with their needed houses
3829 				break;
3830 
3831 			slot_object_id_array[i] = town_res.scan_build( townLayout->first_slot_recno+i, bestRaceId);
3832 			raceNeedBuildCount[bestRaceId-1]--;
3833 			max_race_pop_array[bestRaceId-1] += POPULATION_PER_HOUSE;
3834 		}
3835 	}
3836 
3837 	//------- set plants in the town layout -------//
3838 
3839 	for( i=0 ; i<townLayout->slot_count ; i++ )
3840 	{
3841 		switch(firstTownSlot[i].build_type)
3842 		{
3843 			case TOWN_OBJECT_PLANT:
3844 				slot_object_id_array[i] = plant_res.scan(0, 'T', 0);    // 'T'-town only, 1st 0-any zone area, 2nd 0-any terain type, 3rd-age level
3845 				break;
3846 
3847 			case TOWN_OBJECT_FARM:
3848 				slot_object_id_array[i] = firstTownSlot[i].build_code;
3849 				err_when( slot_object_id_array[i] < 1 || slot_object_id_array[i] > 9 );
3850 				break;
3851 
3852 			case TOWN_OBJECT_HOUSE:
3853 				if( !slot_object_id_array[i] )
3854 					slot_object_id_array[i] = town_res.scan_build( townLayout->first_slot_recno+i, random_race() );
3855 				break;
3856 		}
3857 	}
3858 }
3859 //---------- End of function Town::auto_set_layout --------//
3860 
3861 
3862 //-------- Begin of function Town::think_layout_id ------//
3863 //
think_layout_id()3864 int Town::think_layout_id()
3865 {
3866 	int i, countDiff;
3867 	int needBuildCount=0;		// basic buildings needed
3868 	int extraBuildCount=0;		// extra buildings needed beside the basic one
3869 
3870 	//---- count the needed buildings of each race ----//
3871 
3872 	for( i=0 ; i<MAX_RACE ; i++ )
3873 	{
3874 		if( race_pop_array[i] == 0 )
3875 			continue;
3876 
3877 		needBuildCount++;		// essential buildings needed
3878 
3879 		if( race_pop_array[i] > POPULATION_PER_HOUSE )		// extra buildings, which are not necessary, but will look better if the layout plan fits with this number
3880 			extraBuildCount += (race_pop_array[i]-POPULATION_PER_HOUSE-1)/POPULATION_PER_HOUSE+1;
3881 	}
3882 
3883 	//---------- scan the town layout ---------//
3884 
3885 	int 		   layoutId;
3886 	TownLayout* townLayout;
3887 
3888 	for( layoutId=town_res.town_layout_count ; layoutId>0 ; layoutId-- )	// scan from the most densed layout to the least densed layout
3889 	{
3890 		townLayout = town_res.get_layout(layoutId);
3891 
3892 		//--- if this plan has less than the essential need ---//
3893 
3894 		countDiff = townLayout->build_count - (needBuildCount+extraBuildCount);
3895 
3896 		if( countDiff==0 )		// the match is perfect, return now
3897 			break;
3898 
3899 		if( countDiff < 0 )		// since we scan from the most densed town layout to the least densed one, if cannot find anyone matched now, there won't be any in the lower positions of the array
3900 		{
3901 			layoutId = town_res.town_layout_count;
3902 			break;
3903 		}
3904 	}
3905 
3906 	err_when( layoutId==0 );
3907 
3908 	//--- if there are more than one layout with the same number of building, pick one randomly ---//
3909 
3910 	int layoutBuildCount = town_res.get_layout(layoutId)->build_count;
3911 	int layoutId2;
3912 
3913 	for( layoutId2=layoutId-1 ; layoutId2>0 ; layoutId2-- )
3914 	{
3915 		townLayout = town_res.get_layout(layoutId2);
3916 
3917 		if( layoutBuildCount != townLayout->build_count )
3918 			break;
3919 	}
3920 
3921 	layoutId2++;		// the lowest layout id. that has the same no. of buildings
3922 
3923 	err_when( layoutId2<1 || layoutId2>town_res.town_layout_count );
3924 
3925 	//------- return the result layout id -------//
3926 
3927 	return layoutId2 + misc.random(layoutId-layoutId2+1);
3928 }
3929 //---------- End of function Town::think_layout_id --------//
3930 
3931 
3932 //-------- Begin of function Town::average_loyalty ------//
3933 //
average_loyalty()3934 int Town::average_loyalty()
3935 {
3936 	int i, totalLoyalty=0;
3937 
3938 	for( i=0 ; i<MAX_RACE ; i++ )
3939 		totalLoyalty += (int) race_loyalty_array[i] * race_pop_array[i];
3940 
3941 	return totalLoyalty / population;
3942 }
3943 //---------- End of function Town::average_loyalty --------//
3944 
3945 
3946 //-------- Begin of function Town::average_target_loyalty ------//
3947 //
average_target_loyalty()3948 int Town::average_target_loyalty()
3949 {
3950 	int i, totalLoyalty=0;
3951 
3952 	for( i=0 ; i<MAX_RACE ; i++ )
3953 		totalLoyalty += (int) race_target_loyalty_array[i] * race_pop_array[i];
3954 
3955 	return totalLoyalty / population;
3956 }
3957 //---------- End of function Town::average_target_loyalty --------//
3958 
3959 
3960 //------- Begin of function Town::average_resistance --------//
3961 //
3962 // Return the average resistance of all the races in the town
3963 // against a specific nation.
3964 //
average_resistance(int nationRecno)3965 int Town::average_resistance(int nationRecno)
3966 {
3967 	int   thisPop;
3968 	float totalResistance=(float)0;
3969 
3970 	for( int i=0 ; i<MAX_RACE ; i++ )
3971 	{
3972 		thisPop = race_pop_array[i];
3973 
3974 		if( thisPop > 0 )
3975 			totalResistance += race_resistance_array[i][nationRecno-1] * thisPop;
3976 	}
3977 
3978 	return int(totalResistance / population);
3979 }
3980 //-------- End of function Town::average_resistance ---------//
3981 
3982 
3983 //------- Begin of function Town::average_target_resistance --------//
3984 //
3985 // Return the average target resistance of all the races in the town
3986 // against a specific nation.
3987 //
average_target_resistance(int nationRecno)3988 int Town::average_target_resistance(int nationRecno)
3989 {
3990 	int   thisPop, t, totalResistance=0;
3991 
3992 	for( int i=0 ; i<MAX_RACE ; i++ )
3993 	{
3994 		thisPop = race_pop_array[i];
3995 
3996 		if( thisPop > 0 )
3997 		{
3998 			t = race_target_resistance_array[i][nationRecno-1];
3999 
4000 			if( t >= 0 ) 		// -1 means no target
4001 				totalResistance += t * thisPop;
4002 			else
4003 				totalResistance += (int) race_resistance_array[i][nationRecno-1] * thisPop;
4004 		}
4005 	}
4006 
4007 	return int(totalResistance / population);
4008 }
4009 //-------- End of function Town::average_target_resistance ---------//
4010 
4011 
4012 //-------- Begin of function Town::can_recruit ------//
4013 //
can_recruit(int raceId)4014 int Town::can_recruit(int raceId)
4015 {
4016 	//----------------------------------------------------//
4017 	// Cannot recruit when you have none of your own camps
4018 	// linked to this town, but your enemies have camps
4019 	// linked to it.
4020 	//----------------------------------------------------//
4021 
4022 	if( !has_linked_own_camp && has_linked_enemy_camp )
4023 		return 0;
4024 
4025 	if( recruitable_race_pop(raceId,1)==0 )
4026 		return 0;
4027 
4028 	err_when( recruitable_race_pop(raceId,1) < 0 );
4029 
4030 	//---------------------------------//
4031 
4032 	int minRecruitLoyalty = MIN_RECRUIT_LOYALTY;
4033 
4034 	//--- for the AI, only recruit if the loyalty still stay at 30 after recruiting the unit ---//
4035 
4036 	if(ai_town && nation_recno)
4037 		minRecruitLoyalty += 3+recruit_dec_loyalty(raceId, 0);		// 0-don't actually decrease it, just return the loyalty to be decreased.
4038 
4039 	return race_loyalty_array[raceId-1] >= minRecruitLoyalty;
4040 }
4041 //---------- End of function Town::can_recruit --------//
4042 
4043 
4044 //-------- Begin of function Town::can_train ------//
4045 //
can_train(int raceId)4046 int Town::can_train(int raceId)
4047 {
4048 	int recruitableCount = jobless_race_pop_array[raceId-1];
4049 
4050 	return has_linked_own_camp && recruitableCount > 0 &&
4051 			 nation_array[nation_recno]->cash > TRAIN_SKILL_COST;
4052 }
4053 //---------- End of function Town::can_train --------//
4054 
4055 
4056 //-------- Begin of function Town::pick_random_race ------//
4057 //
4058 // Randonly pick a race of town people who live in the town.
4059 //
4060 // <int> pickNonRecruitableAlso - whether also pick units that have jobs.
4061 // <int> pickSpyFlag            - whether will pick spies or not.
4062 //
4063 // return: <int> id. of the race picked.
4064 //					  0 - no race picked.
4065 //
pick_random_race(int pickNonRecruitableAlso,int pickSpyFlag)4066 int Town::pick_random_race(int pickNonRecruitableAlso, int pickSpyFlag)
4067 {
4068 	int totalPop;
4069 
4070 	if( pickNonRecruitableAlso )
4071 		totalPop = population;
4072 	else
4073 	{
4074 		totalPop = jobless_population - (train_unit_recno>0);
4075 
4076 		if( !pickSpyFlag )		// if don't pick spies
4077 		{
4078 			for( int i=0 ; i<MAX_RACE ; i++ )
4079 				totalPop -= race_spy_count_array[i];
4080 
4081 			if( totalPop == -1 )		// it can be -1 if the unit being trained is a spy
4082 				totalPop = 0;
4083 		}
4084 
4085 		err_when( totalPop < 0 );
4086 	}
4087 
4088 	if( totalPop==0 )
4089 		return 0;
4090 
4091 	int randomPersonId = misc.random(totalPop)+1;
4092 	int popSum=0;
4093 
4094 	for( int i=0 ; i<MAX_RACE ; i++ )
4095 	{
4096 		if( pickNonRecruitableAlso )
4097 			popSum += race_pop_array[i];
4098 		else
4099 			popSum += recruitable_race_pop(i+1, pickSpyFlag);
4100 
4101 		if( randomPersonId <= popSum )
4102 			return i+1;
4103 	}
4104 
4105 	err_here();
4106 	return 0;
4107 }
4108 //---------- End of function Town::pick_random_race --------//
4109 
4110 
4111 //-------- Begin of function Town::get_most_populated_race ------//
4112 //
4113 // <int&> raceId1, raceId2 - return the id. of the most and
4114 //									  2nd most populated races.
4115 //
get_most_populated_race(int & mostRaceId1,int & mostRaceId2)4116 void Town::get_most_populated_race(int& mostRaceId1, int& mostRaceId2)
4117 {
4118 	//--- find the two races with most population in the town ---//
4119 
4120 	int	racePop;
4121 	int   mostRacePop1=0, mostRacePop2=0;
4122 
4123 	mostRaceId1=0;
4124 	mostRaceId2=0;
4125 
4126 	if( population==0 )
4127 		return;
4128 
4129 	for( int i=0 ; i<MAX_RACE ; i++ )
4130 	{
4131 		racePop = race_pop_array[i];
4132 
4133 		if( racePop==0 )
4134 			continue;
4135 
4136 		if( racePop >= mostRacePop1 )
4137 		{
4138 			mostRacePop2 = mostRacePop1;
4139 			mostRacePop1 = racePop;
4140 
4141 			mostRaceId2 = mostRaceId1;
4142 			mostRaceId1 = i+1;
4143 		}
4144 		else if( racePop >= mostRaceId2 )
4145 		{
4146 			mostRacePop2 = racePop;
4147 			mostRaceId2  = i+1;
4148 		}
4149 	}
4150 }
4151 //---------- End of function Town::get_most_populated_race --------//
4152 
4153 
4154 //-------- Begin of function Town::majority_race ------//
4155 //
majority_race()4156 int Town::majority_race()
4157 {
4158 	int mostRaceCount=0, mostRaceId=0;
4159 
4160 	for( int i=0 ; i<MAX_RACE ; i++ )
4161 	{
4162 		if( race_pop_array[i] > mostRaceCount )
4163 		{
4164 			mostRaceCount = race_pop_array[i];
4165 			mostRaceId 	  = i+1;
4166 		}
4167 	}
4168 
4169 	return mostRaceId;
4170 }
4171 //---------- End of function Town::majority_race --------//
4172 
4173 
4174 //-------- Begin of function Town::recruitable_race_pop ------//
4175 //
4176 // Return the number of units can be recruited from this town.
4177 //
4178 // <int> raceId	  - id. of the race to recruit
4179 //
4180 // <int> recruitSpy - whether spies will be recruited or not.
4181 //							 if no, spies are not counted in the
4182 //							 total no. of units that can be recruited.
4183 //
recruitable_race_pop(int raceId,int recruitSpy)4184 int Town::recruitable_race_pop(int raceId, int recruitSpy)
4185 {
4186 	err_when( raceId<1 || raceId>MAX_RACE );
4187 
4188 	short recruitableCount = jobless_race_pop_array[raceId-1];
4189 
4190 	if( train_unit_recno && unit_array[train_unit_recno]->race_id==raceId )
4191 		recruitableCount--;
4192 
4193 	if( !recruitSpy )
4194 	{
4195 		recruitableCount -= race_spy_count_array[raceId-1];
4196 
4197 		if( recruitableCount == -1 )		// it may have been reduced twice if the unit being trained is a spy
4198 			recruitableCount = 0;
4199 	}
4200 
4201 	err_when( recruitableCount < 0 );
4202 
4203 	return recruitableCount;
4204 }
4205 //---------- End of function Town::recruitable_race_pop --------//
4206 
4207 
4208 //------ Begin of function Town::verify_slot_object_id_array ------//
4209 //
4210 // This function is for debugging only.
4211 //
verify_slot_object_id_array()4212 void Town::verify_slot_object_id_array()
4213 {
4214 	TownLayout* townLayout = town_res.get_layout(layout_id);
4215 	TownSlot*   townSlot   = town_res.get_slot(townLayout->first_slot_recno);
4216 
4217 	for( int i=0 ; i<townLayout->slot_count ; i++, townSlot++ )
4218 	{
4219 		//----- build_type==0 if plants -----//
4220 
4221 		switch(townSlot->build_type)
4222 		{
4223 			//----- build_type>0 if town buildings -----//
4224 
4225 			case TOWN_OBJECT_HOUSE:
4226 				town_res.get_build( slot_object_id_array[i] );
4227 				break;
4228 
4229 			case TOWN_OBJECT_PLANT:
4230 				plant_res.get_bitmap( slot_object_id_array[i] );
4231 				break;
4232 
4233 			case TOWN_OBJECT_FARM:
4234 				err_when( slot_object_id_array[i]<1 || slot_object_id_array[i]>9 );
4235 				break;
4236 		}
4237 	}
4238 }
4239 //-------- End of function Town::verify_slot_object_id_array ------//
4240 
4241 
4242 //----- Begin of function Town::set_auto_collect_tax_loyalty -----//
4243 //
4244 // Note:
4245 //
4246 // Auto collect tax loyalty must always be higher than the auto grant
4247 // loyalty. If the player has set it incorrectly, the program
4248 // will automatically adjust it. e.g. If the player sets the auto
4249 // grant level to 80 while the auto tax level is currently 60,
4250 // the program will adjust auto tax level to 90. And if the player
4251 // sets the auto grant level to 100, auto tax will be disabled.
4252 //
set_auto_collect_tax_loyalty(int loyaltyLevel)4253 void Town::set_auto_collect_tax_loyalty(int loyaltyLevel)
4254 {
4255 	auto_collect_tax_loyalty = loyaltyLevel;
4256 
4257 	if( loyaltyLevel && auto_grant_loyalty >= auto_collect_tax_loyalty )
4258 	{
4259 		auto_grant_loyalty = auto_collect_tax_loyalty-10;
4260 	}
4261 }
4262 //------ End of function Town::set_auto_collect_tax_loyalty -----//
4263 
4264 
4265 //----- Begin of function Town::set_auto_grant_loyalty -----//
4266 //
set_auto_grant_loyalty(int loyaltyLevel)4267 void Town::set_auto_grant_loyalty(int loyaltyLevel)
4268 {
4269 	auto_grant_loyalty = loyaltyLevel;
4270 
4271 	if( loyaltyLevel && auto_grant_loyalty >= auto_collect_tax_loyalty )
4272 	{
4273 		auto_collect_tax_loyalty = auto_grant_loyalty+10;
4274 
4275 		if( auto_collect_tax_loyalty > 100 )
4276 			auto_collect_tax_loyalty = 0;					// disable auto collect tax if it's over 100
4277 	}
4278 }
4279 //------ End of function Town::set_auto_grant_loyalty -----//
4280 
4281 
4282 //------ Begin of function Town::update_quality_of_life -------//
4283 //
4284 // Quality of life is determined by:
4285 //
4286 // - The provision of goods to the villagers. A more constant
4287 //	  supply and a bigger variety of goods give to high quality of life.
4288 //
update_quality_of_life()4289 void Town::update_quality_of_life()
4290 {
4291 	Firm* 		firmPtr;
4292 	FirmMarket* firmMarket;
4293 
4294 	//--- calculate the estimated total purchase from this town ----//
4295 
4296 	float townDemand = (float) jobless_population * (float) PEASANT_GOODS_MONTH_DEMAND
4297 							 + (float) worker_population() * (float) WORKER_GOODS_MONTH_DEMAND;
4298 
4299 	float totalPurchase = (float) 0;
4300 
4301 	for( int i=0 ; i<linked_firm_count ; i++ )
4302 	{
4303 		if( linked_firm_enable_array[i] != LINK_EE )
4304 			continue;
4305 
4306 		firmPtr = firm_array[ linked_firm_array[i] ];
4307 
4308 		if( firmPtr->firm_id != FIRM_MARKET )
4309 			continue;
4310 
4311 		firmMarket = (FirmMarket*) firmPtr;
4312 
4313 		//-------------------------------------//
4314 
4315 		MarketGoods* marketGoods = firmMarket->market_goods_array;
4316 
4317 		for( int j=0 ; j<MAX_MARKET_GOODS ; j++, marketGoods++ )
4318 		{
4319 			if( !marketGoods->product_raw_id || marketGoods->month_demand==0 )
4320 				continue;
4321 
4322 			float monthSaleQty = marketGoods->sale_qty_30days();
4323 
4324 			if( monthSaleQty > marketGoods->month_demand )
4325 			{
4326 				totalPurchase += townDemand;
4327 			}
4328 			else if( marketGoods->month_demand > townDemand )
4329 			{
4330 				totalPurchase += monthSaleQty * townDemand / marketGoods->month_demand;
4331 			}
4332 			else
4333 				totalPurchase += monthSaleQty;
4334 		}
4335 	}
4336 
4337 	//------ return the quality of life ------//
4338 
4339 	quality_of_life = int( (float)100 * totalPurchase / (townDemand * MAX_PRODUCT) );
4340 }
4341 //----------- End of function Town::update_quality_of_life ---------//
4342 
4343 
4344 //----- Begin of function Town::has_linked_camp -----//
4345 //
4346 // Return whether there is a camp of the specific nation
4347 // linked to this town.
4348 //
4349 // <int> nationRecno  - recno of the nation.
4350 // <int> needOverseer - whether only count camps with overseers or not.
4351 //
has_linked_camp(int nationRecno,int needOverseer)4352 int Town::has_linked_camp(int nationRecno, int needOverseer)
4353 {
4354 	Firm* firmPtr;
4355 
4356 	for( int i=0 ; i<linked_firm_count ; i++ )
4357 	{
4358 		firmPtr = firm_array[ linked_firm_array[i] ];
4359 
4360 		if( firmPtr->firm_id == FIRM_CAMP &&
4361 			 firmPtr->nation_recno == nationRecno )
4362 		{
4363 			if( !needOverseer || firmPtr->overseer_recno )
4364 				return 1;
4365 		}
4366 	}
4367 
4368 	return 0;
4369 }
4370 //------ End of function Town::has_linked_camp -----//
4371 
4372 
4373 //----- Begin of function Town::can_grant_to_non_own_town -----//
4374 //
4375 // Return whether the given nation is allowed to grant to
4376 // this independent town. Only when the nation has a camp (with
4377 // an overseer) linked to the town, the nation will be able
4378 // to grant the independent village.
4379 //
4380 // <int> grantNationRecno - the recno of the nation that
4381 //									 is going to grant this town.
4382 //
can_grant_to_non_own_town(int grantNationRecno)4383 int Town::can_grant_to_non_own_town(int grantNationRecno)
4384 {
4385 	if( nation_recno == grantNationRecno )		// only for independent town
4386 		return 0;
4387 
4388 	if( nation_recno == 0 )		// independent town
4389 	{
4390 		return has_linked_camp( grantNationRecno, 1 );		// 1-only count camps with overseers
4391 	}
4392 	else  // for nation town, when the enemy doesn't have camps linked to it and the granting nation has camps linked to it
4393 	{
4394 		return has_linked_camp( nation_recno, 0 )==0 &&		// 0-count camps regardless of the presence of overseers
4395 				 has_linked_camp( grantNationRecno, 1 );		// 1-only count camps with overseers
4396 	}
4397 }
4398 //------ End of function Town::can_grant_to_non_own_town -----//
4399 
4400 
4401 //----- Begin of function Town::grant_to_non_own_town -----//
4402 //
4403 // <int> grantNationRecno - the recno of the nation that
4404 //									 is going to grant this town.
4405 //
grant_to_non_own_town(int grantNationRecno,int remoteAction)4406 int Town::grant_to_non_own_town(int grantNationRecno, int remoteAction)
4407 {
4408 	if( !can_grant_to_non_own_town(grantNationRecno) )
4409 		return 0;
4410 
4411 	Nation* grantNation = nation_array[grantNationRecno];
4412 
4413 	if( grantNation->cash < 0 )
4414 		return 0;
4415 
4416 	if( !remoteAction && remote.is_enable() )
4417 	{
4418 		short *shortPtr = (short *)remote.new_send_queue_msg(MSG_TOWN_GRANT_INDEPENDENT, 2*sizeof(short) );
4419 		shortPtr[0] = town_recno;
4420 		shortPtr[1] = grantNationRecno;
4421 		return 1;
4422 	}
4423 
4424 	//---- calculate the resistance to be decreased -----//
4425 
4426 	int resistanceDec = IND_TOWN_GRANT_RESISTANCE_DECREASE - accumulated_enemy_grant_penalty/5;
4427 
4428 	resistanceDec = MAX(3, resistanceDec);
4429 
4430 	accumulated_enemy_grant_penalty += 10;
4431 
4432 	//------ decrease the resistance of the independent villagers ------//
4433 
4434 	for( int i=0 ; i<MAX_RACE ; i++ )
4435 	{
4436 		if( race_pop_array[i]==0 )
4437 			continue;
4438 
4439 		//----- if this is an independent town ------//
4440 
4441 		if( nation_recno==0 )
4442 		{
4443 			race_resistance_array[i][grantNationRecno-1] -= resistanceDec;
4444 
4445 			if( race_resistance_array[i][grantNationRecno-1] < 0 )
4446 				race_resistance_array[i][grantNationRecno-1] = (float) 0;
4447 		}
4448 		else  //----- if this is an nation town ------//
4449 		{
4450 			race_loyalty_array[i] -= resistanceDec;
4451 
4452 			if( race_loyalty_array[i] < 0 )
4453 				race_loyalty_array[i] = (float) 0;
4454 		}
4455 	}
4456 
4457 	//----------- decrease cash ------------//
4458 
4459 	grantNation->add_expense(EXPENSE_GRANT_OTHER_TOWN, (float)population * IND_TOWN_GRANT_PER_PERSON );
4460 
4461 	return 1;
4462 }
4463 //------ End of function Town::grant_to_non_own_town -----//
4464 
4465 
4466 //----- Begin of function Town::update_camp_link -----//
4467 //
4468 // Update the status of links from this town to camps.
4469 //
update_camp_link()4470 void Town::update_camp_link()
4471 {
4472 	//--- enable the link of the town's side to all linked camps ---//
4473 
4474 	Firm* firmPtr;
4475 
4476 	int i;
4477 	for( i=0 ; i<linked_firm_count ; i++ )
4478 	{
4479 		 firmPtr = firm_array[linked_firm_array[i]];
4480 
4481 		 if( firmPtr->firm_id != FIRM_CAMP )
4482 			 continue;
4483 
4484 		 //--- don't set it if the town and camp both belong to a human player, the player will set it himself ---//
4485 
4486 		 if( firmPtr->nation_recno == nation_recno &&
4487 			  nation_recno && !nation_array[nation_recno]->is_ai() )
4488 		 {
4489 			 continue;
4490 		 }
4491 
4492 		 //--------------------------------------------//
4493 
4494 		 toggle_firm_link( i+1, 1, COMMAND_AUTO );
4495 	}
4496 
4497 	//------- update camp link status -------//
4498 
4499 	has_linked_own_camp = 0;
4500 	has_linked_enemy_camp = 0;
4501 
4502 	for( i=0 ; i<linked_firm_count ; i++ )
4503 	{
4504 		if( linked_firm_enable_array[i] != LINK_EE )
4505 			continue;
4506 
4507 		firmPtr = firm_array[linked_firm_array[i]];
4508 
4509 		if( firmPtr->firm_id!=FIRM_CAMP || !firmPtr->overseer_recno )
4510 			continue;
4511 
4512 		if( firmPtr->nation_recno == nation_recno )
4513 			has_linked_own_camp = 1;
4514 		else
4515 			has_linked_enemy_camp = 1;
4516 	}
4517 }
4518 //------ End of function Town::update_camp_link -----//
4519 
4520 
4521 //------- Begin of function Town::closest_own_camp -------//
4522 //
4523 // Return the firm recno of the camp that is closest to this town.
4524 //
closest_own_camp()4525 int Town::closest_own_camp()
4526 {
4527 	Firm *firmPtr;
4528 	int  curDistance, minDistance=1000, closestFirmRecno=0;
4529 
4530 	for( int i=linked_firm_count-1 ; i>=0 ; i-- )
4531 	{
4532 		firmPtr = firm_array[ linked_firm_array[i] ];
4533 
4534 		if( firmPtr->firm_id != FIRM_CAMP ||
4535 			 firmPtr->nation_recno != nation_recno )
4536 		{
4537 			continue;
4538 		}
4539 
4540 		curDistance = misc.points_distance( center_x, center_y,
4541 						  firmPtr->center_x, firmPtr->center_y );
4542 
4543 		if( curDistance < minDistance )
4544 		{
4545 			minDistance = curDistance;
4546 			closestFirmRecno = firmPtr->firm_recno;
4547 		}
4548 	}
4549 
4550 	return closestFirmRecno;
4551 }
4552 //-------- End of function Town::closest_own_camp ---------//
4553 
4554 
4555 //-------- Begin of static function random_race --------//
4556 //
4557 // Uses misc.random() for random race
4558 //
random_race()4559 static char random_race()
4560 {
4561 	int num = misc.random(config_adv.race_random_list_max);
4562 	return config_adv.race_random_list[num];
4563 }
4564 //--------- End of static function random_race ---------//
4565