1 /*
2  * Seven Kingdoms: Ancient Adversaries
3  *
4  * Copyright 1997,1998 Enlight Software Ltd.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 //Filename    : OUNITIND.CPP
22 //Description : Object independent Unit AI
23 
24 #include <OSYS.h>
25 #include <OSPY.h>
26 #include <OREBEL.h>
27 #include <OUNIT.h>
28 #include <OCONFIG.h>
29 #include <OF_CAMP.h>
30 #include <ONATION.h>
31 
32 //--------- Begin of function Unit::think_independent_unit --------//
33 //
34 // Think about the action of an independent unit. It first tries to
35 // settle to a town. If not successful, it will disband itself.
36 //
think_independent_unit()37 void Unit::think_independent_unit()
38 {
39 	if( !is_ai_all_stop() )
40 		return;
41 
42 	//--- don't process if it's a spy and the notify cloak flag is on ---//
43 
44 	if( spy_recno )
45 	{
46 		//---------------------------------------------//
47 		//
48 		// If notify_cloaked_nation_flag is 0, the AI
49 		// won't control the unit.
50 		//
51 		// If notify_cloaked_nation_flag is 1, the AI
52 		// will control the unit. But not immediately,
53 		// it will do it once 5 days so the player can
54 		// have a chance to select the unit and set its
55 		// notify_cloaked_nation_flag back to 0 if the
56 		// player wants.
57 		//
58 		//---------------------------------------------//
59 
60 		if( spy_array[spy_recno]->notify_cloaked_nation_flag==0 )
61 			return;
62 
63 		if( info.game_date%5 != sprite_recno%5 )
64 			return;
65 	}
66 
67 	//-------- if this is a rebel ----------//
68 
69 	if( unit_mode == UNIT_MODE_REBEL )
70 	{
71 		Rebel* rebelPtr = rebel_array[unit_mode_para];
72 
73 		//--- if the group this rebel belongs to already has a rebel town, assign to it now ---//
74 
75 		if( rebelPtr->town_recno )
76 		{
77 			if( !town_array.is_deleted(rebelPtr->town_recno) )
78 			{
79 				Town* townPtr = town_array[rebelPtr->town_recno];
80 
81 				err_when( townPtr->rebel_recno != rebelPtr->rebel_recno );
82 
83 				assign(townPtr->loc_x1, townPtr->loc_y1);
84 			}
85 
86 			return;			// don't do anything if the town has been destroyed, Rebel::next_day() will take care of it.
87 		}
88 	}
89 	//---- look for towns to assign to -----//
90 
91 	Town *townPtr, *bestTown=NULL;
92 	int  regionId = world.get_region_id( next_x_loc(), next_y_loc() );
93 	int  curRating, bestRating=0;
94 	int  curXLoc = next_x_loc(), curYLoc = next_y_loc();
95 
96 	for( int i=town_array.size() ; i>0 ; i-- )
97 	{
98 		if( town_array.is_deleted(i) )
99 			continue;
100 
101 		townPtr = town_array[i];
102 
103 		if( townPtr->nation_recno ||
104 			 townPtr->population >= MAX_TOWN_POPULATION ||
105 			 townPtr->region_id != regionId )
106 		{
107 			continue;
108 		}
109 
110 		//-------------------------------------//
111 
112 		curRating = world.distance_rating(curXLoc, curYLoc,
113 						townPtr->center_x, townPtr->center_y );
114 
115 		curRating += 100 * townPtr->race_pop_array[race_id-1] / townPtr->population;
116 
117 		//-------------------------------------//
118 
119 		if( curRating > bestRating )
120 		{
121 			bestRating = curRating;
122 			bestTown   = townPtr;
123 		}
124 	}
125 
126 	if( bestTown )
127 	{
128 		err_when( unit_mode==UNIT_MODE_REBEL && rebel_array[unit_mode_para]->town_recno &&
129 					 rebel_array[unit_mode_para]->town_recno != bestTown->town_recno );
130 
131 		//--- drop its rebel identity and becomes a normal unit if he decides to settle to a town ---//
132 
133 		if( unit_mode == UNIT_MODE_REBEL )
134 			rebel_array.drop_rebel_identity(sprite_recno);
135 
136 		assign(bestTown->loc_x1, bestTown->loc_y1);
137 	}
138 	else
139 		resign(COMMAND_AI);
140 }
141 //---------- End of function Unit::think_independent_unit --------//
142 
143