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    : OU_MARI2.CPP
22 //Description : Marine Units AI functions
23 
24 #include <OINFO.h>
25 #include <ONATION.h>
26 #include <OF_HARB.h>
27 #include <OU_MARI.h>
28 
29 
30 //------- Begin of function UnitMarine::init_derived --------//
31 
init_derived()32 void UnitMarine::init_derived()
33 {
34 	last_load_goods_date = info.game_date;
35 }
36 //------- End of function UnitMarine::init_derived --------//
37 
38 
39 //------- Begin of function UnitMarine::process_ai --------//
40 //
process_ai()41 void UnitMarine::process_ai()
42 {
43 	//-- Think about removing stops whose owner nation is at war with us. --//
44 
45 	// AI does do any sea trade
46 
47 //	if( info.game_date%30 == sprite_recno%30 )
48 //		think_del_stop();
49 
50 	//---- Think about setting new trade route -------//
51 
52 	if( info.game_date%15 == sprite_recno%15 )
53 	{
54 		if( stop_defined_num < 2 && is_visible() && is_ai_all_stop() )
55 			ai_sail_to_nearby_harbor();
56 	}
57 
58 	//------ Think about resigning this caravan -------//
59 
60 	if( info.game_date%60 == sprite_recno%60 )
61 		think_resign();
62 }
63 //------- End of function UnitMarine::process_ai --------//
64 
65 
66 //--------- Begin of function UnitMarine::is_ai_all_stop --------//
67 
is_ai_all_stop()68 int UnitMarine::is_ai_all_stop()
69 {
70 	if( cur_action != SPRITE_IDLE || ai_action_id )
71 		return 0;
72 
73 	//---- if the ship is on the beach, it's action mode is always ACTION_SHIP_TO_BEACH, so we can't check it against ACTION_STOP ---//
74 
75 	if( action_mode2 == ACTION_SHIP_TO_BEACH )
76 	{
77 		if( in_beach && (extra_move_in_beach==NO_EXTRA_MOVE || extra_move_in_beach==EXTRA_MOVE_FINISH) )
78 			return 1;
79 	}
80 
81 	return action_mode==ACTION_STOP && action_mode2==ACTION_STOP;
82 }
83 //---------- End of function UnitMarine::is_ai_all_stop --------//
84 
85 
86 //------- Begin of function UnitMarine::think_resign --------//
87 
think_resign()88 int UnitMarine::think_resign()
89 {
90 	//---- only resign when the ship has stopped ----//
91 
92 	if( !is_ai_all_stop() )
93 		return 0;
94 
95 	//--- retire this ship if we have better ship technology available ---//
96 
97 	if( unit_id == UNIT_TRANSPORT )
98 	{
99 		if( unit_res[UNIT_CARAVEL]->get_nation_tech_level(nation_recno) > 0 ||
100 			 unit_res[UNIT_GALLEON]->get_nation_tech_level(nation_recno) > 0 )
101 		{
102 			if( !nation_array[nation_recno]->ai_is_sea_travel_safe() )
103 			{
104 				resign(COMMAND_AI);
105 				return 1;
106 			}
107 		}
108 	}
109 
110 	return 0;
111 }
112 //------- End of function UnitMarine::think_resign --------//
113 
114 
115 //------- Begin of function UnitMarine::think_del_stop --------//
116 //
117 // Think about removing stops whose owner nation is at war with us.
118 //
think_del_stop()119 void UnitMarine::think_del_stop()
120 {
121 	if( !is_visible() )		// cannot del stop if the caravan is inside a market place.
122 		return;
123 
124 	Nation* nationPtr = nation_array[nation_recno];
125 
126 	for( int i=stop_defined_num ; i>0 ; i-- )
127 	{
128 		if( firm_array.is_deleted(stop_array[i-1].firm_recno) )
129 		{
130 			del_stop(i, COMMAND_AI);
131 			continue;
132 		}
133 
134 		//----------------------------------------------//
135 
136 		int nationRecno = firm_array[ stop_array[i-1].firm_recno ]->nation_recno;
137 
138 		if( nationPtr->get_relation_status(nationRecno) == NATION_HOSTILE )
139 		{
140 			del_stop(i, COMMAND_AI);
141 		}
142 	}
143 }
144 //------- End of function UnitMarine::think_del_stop --------//
145 
146 
147 //--------- Begin of function UnitMarine::ai_sail_to_nearby_harbor --------//
148 
ai_sail_to_nearby_harbor()149 void UnitMarine::ai_sail_to_nearby_harbor()
150 {
151 	Nation		*ownNation = nation_array[nation_recno];
152 	FirmHarbor  *firmHarbor, *bestHarbor=NULL;
153 	int			curRating, bestRating=0;
154 	int			curXLoc=cur_x_loc(), curYLoc=cur_y_loc();
155 	int			curRegionId=region_id();
156 
157 	for( int i=0 ; i<ownNation->ai_harbor_count ; i++ )
158 	{
159 		firmHarbor = (FirmHarbor*) firm_array[ ownNation->ai_harbor_array[i] ];
160 
161 		if( firmHarbor->sea_region_id != curRegionId )
162 			continue;
163 
164 		curRating = world.distance_rating( curXLoc, curYLoc, firmHarbor->center_x, firmHarbor->center_y );
165 
166 		curRating += (MAX_SHIP_IN_HARBOR - firmHarbor->ship_count) * 100;
167 
168 		if( curRating > bestRating )
169 		{
170 			bestRating = curRating;
171 			bestHarbor = firmHarbor;
172 		}
173 	}
174 
175 	if( bestHarbor )
176 		assign(bestHarbor->loc_x1, bestHarbor->loc_y1);
177 }
178 //---------- End of function UnitMarine::ai_sail_to_nearby_harbor --------//
179 
180 
181 //--------- Begin of function UnitMarine::ai_ship_being_attacked --------//
182 //
183 // This function is called by Unit::hit_target() when the king is
184 // under attack.
185 //
186 // <int> attackerUnitRecno - recno of the attacker unit.
187 //
ai_ship_being_attacked(int attackerUnitRecno)188 void UnitMarine::ai_ship_being_attacked(int attackerUnitRecno)
189 {
190 	Unit* attackerUnit = unit_array[attackerUnitRecno];
191 
192 	if( attackerUnit->nation_recno == nation_recno )		// this can happen when the unit has just changed nation
193 		return;
194 
195 	if( info.game_date%5 == sprite_recno%5 )
196 	{
197 		nation_array[nation_recno]->ai_sea_attack_target( attackerUnit->next_x_loc(), attackerUnit->next_y_loc() );
198 	}
199 }
200 //---------- End of function UnitMarine::ai_ship_being_attacked --------//
201 
202