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_CARA2.CPP
22 //Description : Unit Caravan - AI functions
23 
24 #include <OINFO.h>
25 #include <ONATION.h>
26 #include <OF_FACT.h>
27 #include <OU_CARA.h>
28 
29 
30 //------- Begin of function UnitCaravan::init_derived --------//
31 
init_derived()32 void UnitCaravan::init_derived()
33 {
34 	last_load_goods_date = info.game_date;
35 }
36 //------- End of function UnitCaravan::init_derived --------//
37 
38 
39 //------- Begin of function UnitCaravan::process_ai --------//
40 //
process_ai()41 void UnitCaravan::process_ai()
42 {
43 	//-- Think about removing stops whose owner nation is at war with us. --//
44 
45 	if( info.game_date%30 == sprite_recno%30 )
46 	{
47 		if( think_del_stop() )
48 			return;
49 
50 		//------ think about setting pickup goods type -----//
51 
52 		think_set_pick_up_type();
53 	}
54 
55 	//------ Think about resigning this caravan -------//
56 
57 	think_resign();
58 }
59 //------- End of function UnitCaravan::process_ai --------//
60 
61 
62 //------- Begin of function UnitCaravan::think_resign --------//
63 
think_resign()64 int UnitCaravan::think_resign()
65 {
66 	if( !is_visible() )		// can only resign when the caravan is not in a stop
67 		return 0;
68 
69 	//---- resign this caravan if it has only one stop ----//
70 
71 	if( stop_defined_num < 2 )
72 	{
73 		resign(COMMAND_AI);
74 		return 1;
75 	}
76 
77 	//---- if the caravan hasn't loaded any goods for a year ----//
78 
79 	if( info.game_date > last_load_goods_date + 365 &&
80 		 info.game_date%30 == sprite_recno%30 )			// don't call too often as the action may fail and it takes a while to call the function each time
81 	{
82 		//--- don't resign if this caravan carries any goods ---//
83 
84 		for( int i=0 ; i<MAX_RAW ; i++ )
85 		{
86 			if( raw_qty_array[i] > 0 || product_raw_qty_array[i] > 0 )
87 				return 0;
88 		}
89 
90 		//------ resign now --------//
91 
92 		resign(COMMAND_AI);
93 		return 1;
94 	}
95 
96 	//--- if this caravan is travelling between two retail markets ---//
97 	//--- (neither of them has any direct supplies) ------//
98 
99 	if( info.game_date%30 == sprite_recno%30 )			// don't call too often as the action may fail and it takes a while to call the function each time
100 	{
101 		for( int i=stop_defined_num ; i>0 ; i-- )
102 		{
103 			int firmRecno = stop_array[i-1].firm_recno;
104 
105 			if( firm_array.is_deleted(firmRecno) ||
106 				 firm_array[firmRecno]->firm_id != FIRM_MARKET )
107 			{
108 				del_stop(i, COMMAND_AI);
109 				return 1;
110 			}
111 
112 			//--- see if this market has any direct supply ---//
113 
114 			FirmMarket* firmMarket = (FirmMarket*) firm_array[firmRecno];
115 
116 			MarketGoods* marketGoods = firmMarket->market_goods_array;
117 
118 			for( int j=0 ; j<MAX_MARKET_GOODS ; j++, marketGoods++ )
119 			{
120 				if( marketGoods->supply_30days() > 0 )
121 					return 0;
122 			}
123 		}
124 
125 		//--- resign now if none of the linked markets have any direct supplies ---//
126 
127 		resign(COMMAND_AI);
128 		return 1;
129 	}
130 
131 	return 0;
132 }
133 //------- End of function UnitCaravan::think_resign --------//
134 
135 
136 //------- Begin of function UnitCaravan::think_del_stop --------//
137 //
138 // Think about removing stops whose owner nation is at war with us.
139 //
think_del_stop()140 int UnitCaravan::think_del_stop()
141 {
142 	if( !is_visible() )		// cannot del stop if the caravan is inside a market place.
143 		return 0;
144 
145 	Firm*	  firmPtr;
146 	Nation* nationPtr = nation_array[nation_recno];
147 
148 	int i;
149 	for( i=stop_defined_num ; i>0 ; i-- )
150 	{
151 		int firmRecno = stop_array[i-1].firm_recno;
152 
153 		if( firm_array.is_deleted(firmRecno) )
154 		{
155 			del_stop(i, COMMAND_AI);
156 			return 1;
157 		}
158 
159 		//---- AI only knows how to trade from a market to another ------//
160 
161 		firmPtr = firm_array[firmRecno];
162 
163 		if( firmPtr->firm_id != FIRM_MARKET ||
164 			 nationPtr->get_relation(firmPtr->nation_recno)->trade_treaty==0 )		// if the treaty trade has been terminated, delete the stop
165 		{
166 			del_stop(i, COMMAND_AI);
167 			return 1;
168 		}
169 
170 		//--- If this market is not linked to any towns ---//
171 
172 		FirmMarket* firmMarket = (FirmMarket*) firm_array[stop_array[i-1].firm_recno];
173 
174 		if( !firmMarket->is_market_linked_to_town() )
175 		{
176 			//--- and the caravan is not currently picking up goods from the market ---//
177 
178 			int hasPickUp=0;
179 			TradeStop* tradeStop = stop_array + i - 1;
180 
181 			int j;
182 			for( j=PICK_UP_RAW_FIRST ; j<=PICK_UP_RAW_LAST ; j++ )
183 			{
184 				if( tradeStop->pick_up_array[j] )
185 					hasPickUp = 1;
186 			}
187 
188 			for( j=PICK_UP_PRODUCT_FIRST ; j<=PICK_UP_PRODUCT_LAST ; j++ )
189 			{
190 				if( tradeStop->pick_up_array[j] )
191 					hasPickUp = 1;
192 			}
193 
194 			//---- then delete the stop -----//
195 
196 			if( !hasPickUp )
197 			{
198 				del_stop(i, COMMAND_AI);
199 				return 1;
200 			}
201 		}
202 
203 		//----------------------------------------------//
204 
205 		int nationRecno = firmMarket->nation_recno;
206 
207 		if( nationPtr->get_relation_status(nationRecno) == NATION_HOSTILE )
208 		{
209 			del_stop(i, COMMAND_AI);
210 			return 1;
211 		}
212 	}
213 
214 	//----------- debug code ----------//
215 
216 #ifdef DEBUG
217 	for( i=stop_defined_num ; i>0 ; i-- )
218 	{
219 		err_when( firm_array.is_deleted(stop_array[i-1].firm_recno) );
220 	}
221 #endif
222 
223 	return 0;
224 }
225 //------- End of function UnitCaravan::think_del_stop --------//
226 
227 
228 //------- Begin of function UnitCaravan::think_set_pick_up_type --------//
229 //
230 // Think about setting the pick up types of this caravan's stops.
231 //
think_set_pick_up_type()232 void UnitCaravan::think_set_pick_up_type()
233 {
234 	if( !is_visible() )		// cannot change pickup type if the caravan is inside a market place.
235 		return;
236 
237 	if( stop_defined_num < 2 )
238 		return;
239 
240 	//------------------------------------------//
241 
242 	err_when( firm_array.is_deleted(stop_array[0].firm_recno) );
243 	err_when( firm_array.is_deleted(stop_array[1].firm_recno) );
244 
245 	Firm* firmPtr1 = firm_array[stop_array[0].firm_recno];
246 	Firm* firmPtr2 = firm_array[stop_array[1].firm_recno];
247 
248 	if( firmPtr1->firm_id != FIRM_MARKET ||		// only when both firms are markets
249 		 firmPtr2->firm_id != FIRM_MARKET )
250 	{
251 		return;
252 	}
253 
254 	if( firmPtr2->nation_recno == nation_recno &&		// only when the market is our own, we can use it as a TO market
255 		 ((FirmMarket*)firmPtr2)->is_retail_market )
256 	{
257 		think_set_pick_up_type2( 1, 2 );
258 	}
259 
260 	if( firmPtr1->nation_recno == nation_recno &&
261 		 ((FirmMarket*)firmPtr1)->is_retail_market )
262 	{
263 		think_set_pick_up_type2( 2, 1 );
264 	}
265 }
266 //------- End of function UnitCaravan::think_set_pick_up_type --------//
267 
268 
269 //------- Begin of function UnitCaravan::think_set_pick_up_type2 --------//
270 //
271 // Think about importing products from one firm to another
272 //
think_set_pick_up_type2(int fromStopId,int toStopId)273 void UnitCaravan::think_set_pick_up_type2(int fromStopId, int toStopId)
274 {
275 	FirmMarket* fromMarket = (FirmMarket*) firm_array[stop_array[fromStopId-1].firm_recno];
276 	FirmMarket* toMarket   = (FirmMarket*) firm_array[stop_array[toStopId-1].firm_recno];
277 
278 	//----- AI only knows about market to market trade -----//
279 
280 	if( fromMarket->firm_id != FIRM_MARKET || toMarket->firm_id != FIRM_MARKET )
281 		return;
282 
283 	//---- think about adding new pick up types -----//
284 
285 	MarketGoods* marketGoods = fromMarket->market_goods_array;
286 	TradeStop* tradeStop = stop_array+fromStopId-1;
287 
288 	int i;
289 	for( i=0 ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
290 	{
291 		if( !marketGoods->product_raw_id )
292 			continue;
293 
294 		//----- only if this market has direct supplies -----//
295 
296 		if( marketGoods->supply_30days()==0 )
297 			continue;
298 
299 		//-- when the from market has the product and the to market does not have the product, then trade this good --//
300 
301 		int pickUpType = PICK_UP_PRODUCT_FIRST+marketGoods->product_raw_id-1;
302 
303 		//------ toggle it if the current flag and the flag we need are different ----//
304 
305 		if( !tradeStop->pick_up_array[pickUpType-1] )
306 			set_stop_pick_up(fromStopId, pickUpType, COMMAND_AI);
307 	}
308 
309 	//---- think about droping existing pick up types -----//
310 
311 	for( i=PICK_UP_RAW_FIRST ; i<=PICK_UP_RAW_LAST ; i++ )
312 	{
313 		if( !tradeStop->pick_up_array[i-1] )
314 			continue;
315 
316 		marketGoods = fromMarket->market_raw_array[i-PICK_UP_RAW_FIRST];
317 
318 		//----- if there is no supply, drop the pick up type -----//
319 
320 		if( !marketGoods || marketGoods->supply_30days() == 0 )
321 			set_stop_pick_up(fromStopId, i, COMMAND_AI);
322 	}
323 
324 	for( i=PICK_UP_PRODUCT_FIRST ; i<=PICK_UP_PRODUCT_LAST ; i++ )
325 	{
326 		if( !tradeStop->pick_up_array[i-1] )
327 			continue;
328 
329 		marketGoods = fromMarket->market_product_array[i-PICK_UP_PRODUCT_FIRST];
330 
331 		//--- if the supply is not enough, drop the pick up type ---//
332 
333 		if( !marketGoods || marketGoods->supply_30days()==0 )
334 			set_stop_pick_up(fromStopId, i, COMMAND_AI);
335 	}
336 }
337 //------- End of function UnitCaravan::think_set_pick_up_type2 --------//
338 
339