OU_CARA2.cpp 8.7 KB

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