OF_MARK.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  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 : OF_MARK.CPP
  21. //Description : Firm Market Place
  22. #include <OINFO.h>
  23. #include <OVGA.h>
  24. #include <OSTR.h>
  25. #include <OBUTTON.h>
  26. #include <OBUTT3D.h>
  27. #include <OFONT.h>
  28. #include <ORAWRES.h>
  29. #include <OIMGRES.h>
  30. #include <ORACERES.h>
  31. #include <OTOWN.h>
  32. #include <OGAME.h>
  33. #include <ONATION.h>
  34. #include <OU_CARA.h>
  35. #include <OWORLD.h>
  36. #include <OSYS.h>
  37. #include <OF_FACT.h>
  38. #include <OF_MINE.h>
  39. #include <OF_MARK.h>
  40. #include <OREMOTE.h>
  41. #include <OSE.h>
  42. //------- define static vars -------//
  43. struct Point
  44. {
  45. short x;
  46. short y;
  47. };
  48. static Point section_point_array[] =
  49. {
  50. { 40, 30 },
  51. { 29, 42 },
  52. { 24, 56 },
  53. };
  54. static Point slot_point_array[] =
  55. {
  56. { 0, 0 },
  57. { 6, 1 },
  58. { 12, 2 },
  59. { 8, 6 },
  60. { 14, 7 },
  61. { 20, 8 },
  62. { 16, 12 },
  63. { 22, 13 },
  64. { 28, 14 },
  65. };
  66. static Button3D button_hire_caravan;
  67. static Button button_clear_stock[MAX_MARKET_GOODS];
  68. //--------- Begin of function FirmMarket::FirmMarket ---------//
  69. //
  70. FirmMarket::FirmMarket()
  71. {
  72. max_stock_qty = (float) MAX_MARKET_STOCK;
  73. memset( market_goods_array , 0, sizeof(MarketGoods) * MAX_MARKET_GOODS );
  74. memset( market_raw_array , 0, sizeof(market_raw_array) );
  75. memset( market_product_array, 0, sizeof(market_product_array) );
  76. next_output_link_id = 0;
  77. next_output_firm_recno = 0;
  78. no_linked_town_since_date = 0;
  79. last_import_new_goods_date = 0;
  80. // ####### patch begin Gilbert 23/1 #######//
  81. is_retail_market = 0;
  82. // ####### end begin Gilbert 23/1 #######//
  83. }
  84. //----------- End of function FirmMarket::FirmMarket -----------//
  85. //--------- Begin of function FirmMarket::~FirmMarket ---------//
  86. //
  87. FirmMarket::~FirmMarket()
  88. {
  89. }
  90. //----------- End of function FirmMarket::~FirmMarket -----------//
  91. //--------- Begin of function FirmMarket::init_derived ---------//
  92. //
  93. void FirmMarket::init_derived()
  94. {
  95. //------ redistribute town demand --------//
  96. town_array.distribute_demand();
  97. //-------- set is_retail_market (for AI only) --------//
  98. if( firm_ai )
  99. {
  100. Firm *firmPtr, *otherFirm;
  101. is_retail_market = 1; // set it to 1 first
  102. for( int i=0 ; i<linked_firm_count ; i++ )
  103. {
  104. firmPtr = firm_array[ linked_firm_array[i] ];
  105. //------ if this is our mine -------//
  106. if( firmPtr->firm_id != FIRM_MINE ||
  107. firmPtr->nation_recno != nation_recno )
  108. {
  109. continue;
  110. }
  111. //--- if the mine doesn't have links to other market ---//
  112. int j;
  113. for( j=firmPtr->linked_firm_count-1 ; j>=0 ; j-- )
  114. {
  115. otherFirm = firm_array[ firmPtr->linked_firm_array[j] ];
  116. if( otherFirm->nation_recno == nation_recno &&
  117. otherFirm->firm_recno != firm_recno &&
  118. otherFirm->firm_id == FIRM_MARKET &&
  119. ((FirmMarket*)otherFirm)->is_retail_market==0 )
  120. {
  121. break;
  122. }
  123. }
  124. if( j<0 ) // if the mine doesn't have any links to other markets
  125. {
  126. is_retail_market = 0;
  127. break;
  128. }
  129. }
  130. }
  131. }
  132. //----------- End of function FirmMarket::init_derived -----------//
  133. //--------- Begin of function FirmMarket::next_day ---------//
  134. //
  135. void FirmMarket::next_day()
  136. {
  137. //----- call next_day() of the base class -----//
  138. Firm::next_day();
  139. //---- update trade link to harbors to towns -----//
  140. update_trade_link();
  141. //-------- input goods ----------//
  142. if( info.game_date%PROCESS_GOODS_INTERVAL == firm_recno%PROCESS_GOODS_INTERVAL )
  143. {
  144. input_goods(50); // input maximum 50 qty of goods per day
  145. set_next_output_firm(); // set next output firm
  146. }
  147. //-------- sell goods --------//
  148. sell_goods();
  149. //------- free up unused slots -------//
  150. //### begin alex 24/10 ###//
  151. //if( info.game_date%30 == firm_recno%30 )
  152. // free_unused_slot();
  153. //#### end alex 24/10 ####//
  154. }
  155. //----------- End of function FirmMarket::next_day -----------//
  156. //--------- Begin of function FirmMarket::next_month ---------//
  157. //
  158. void FirmMarket::next_month()
  159. {
  160. Firm::next_month();
  161. //------ post goods supply data ------//
  162. MarketGoods* marketGoods = market_goods_array;
  163. for( int i=0 ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  164. {
  165. marketGoods->last_month_supply = marketGoods->cur_month_supply;
  166. marketGoods->cur_month_supply = (float) 0;
  167. marketGoods->last_month_sale_qty = marketGoods->cur_month_sale_qty;
  168. marketGoods->cur_month_sale_qty = (float) 0;
  169. }
  170. }
  171. //----------- End of function FirmMarket::next_month -----------//
  172. //--------- Begin of function FirmMarket::next_year ---------//
  173. //
  174. void FirmMarket::next_year()
  175. {
  176. Firm::next_year();
  177. //------ post goods supply data ------//
  178. MarketGoods* marketGoods = market_goods_array;
  179. for( int i=0 ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  180. {
  181. marketGoods->last_year_sales = marketGoods->cur_year_sales;
  182. marketGoods->cur_year_sales = (float) 0;
  183. }
  184. }
  185. //----------- End of function FirmMarket::next_year -----------//
  186. //--------- Begin of function FirmMarket::put_info ---------//
  187. //
  188. void FirmMarket::put_info(int refreshFlag)
  189. {
  190. disp_basic_info(INFO_Y1, refreshFlag);
  191. //--- only display market info if the player is allowed to trade with this market ---//
  192. put_market_info(INFO_Y1+50, refreshFlag);
  193. //------------------------------------------------//
  194. if( !config.show_ai_info && nation_recno!=nation_array.player_recno )
  195. return;
  196. disp_income(INFO_Y1+209, refreshFlag ); // 1-display income figure
  197. if( refreshFlag == INFO_REPAINT )
  198. button_hire_caravan.paint( INFO_X1, INFO_Y1+236, 'A', "HIRECARA" );
  199. if( can_hire_caravan() )
  200. button_hire_caravan.enable();
  201. else
  202. button_hire_caravan.disable();
  203. }
  204. //----------- End of function FirmMarket::put_info -----------//
  205. //--------- Begin of function FirmMarket::detect_info ---------//
  206. //
  207. void FirmMarket::detect_info()
  208. {
  209. if( detect_basic_info() )
  210. return;
  211. if( !config.show_ai_info && nation_recno!=nation_array.player_recno )
  212. return;
  213. if( nation_recno != nation_array.player_recno ) // the following controls are only available for player's firms
  214. return;
  215. //----- detect clear stock buttons -------//
  216. for( int i=0 ; i<MAX_MARKET_GOODS ; i++ )
  217. {
  218. if( button_clear_stock[i].detect() )
  219. {
  220. if( !remote.is_enable() )
  221. {
  222. MarketGoods* marketGoods = market_goods_array+i;
  223. clear_market_goods(i+1);
  224. info.disp();
  225. return;
  226. }
  227. else
  228. {
  229. // message structure : <firm recno> <cell no 0-3>
  230. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_F_MARKET_SCRAP, sizeof(short)+sizeof(short) );
  231. shortPtr[0] = firm_recno;
  232. shortPtr[1] = i;
  233. }
  234. se_ctrl.immediate_sound("TURN_OFF");
  235. }
  236. }
  237. //----- detect hire caravan button -------//
  238. if( button_hire_caravan.detect() )
  239. hire_caravan(COMMAND_PLAYER);
  240. }
  241. //----------- End of function FirmMarket::detect_info -----------//
  242. //------- Begin of function FirmMarket::can_hire_caravan -------//
  243. //
  244. // return: <int> 0 - if there is no more caravan we can hire
  245. // >0 - the number of new caravans we can hire.
  246. //
  247. int FirmMarket::can_hire_caravan()
  248. {
  249. Nation* nationPtr = nation_array[nation_recno];
  250. if( nationPtr->cash < 0 )
  251. return 0;
  252. int supportedCaravan = nationPtr->total_population / POPULATION_PER_CARAVAN;
  253. int caravanCount = unit_res[UNIT_CARAVAN]->nation_unit_count_array[nation_recno-1];
  254. if( supportedCaravan > caravanCount )
  255. return supportedCaravan - caravanCount;
  256. else
  257. return 0;
  258. }
  259. //-------- End of function FirmMarket::can_hire_caravan --------//
  260. //--------- Begin of function FirmMarket::hire_caravan ---------//
  261. //
  262. short FirmMarket::hire_caravan(char remoteAction)
  263. {
  264. if( !can_hire_caravan() )
  265. return 0;
  266. //---------------------------------------//
  267. Nation *nationPtr = nation_array[nation_recno];
  268. if(!remoteAction && remote.is_enable())
  269. {
  270. // packet structure : <town recno>
  271. short *shortPtr = (short *) remote.new_send_queue_msg(MSG_F_MARKET_HIRE_CARA, sizeof(short));
  272. *shortPtr = firm_recno;
  273. return 0;
  274. }
  275. //---------- add the unit now -----------//
  276. int unitRecno = create_unit( UNIT_CARAVAN );
  277. UnitCaravan* unitCaravan = (UnitCaravan*)unit_array[unitRecno];
  278. unitCaravan->loyalty = 100;
  279. unitCaravan->set_stop( 1, loc_x1, loc_y1, COMMAND_AUTO );
  280. //---------- deduct cash for the caravan's cost ----------//
  281. if(unitCaravan)
  282. return unitCaravan->sprite_recno;
  283. else
  284. return 0;
  285. }
  286. //----------- End of function FirmMarket::hire_caravan -----------//
  287. //--------- Begin of function FirmMarket::put_market_info ---------//
  288. //
  289. void FirmMarket::put_market_info(int dispY1, int refreshFlag)
  290. {
  291. static char lastNoTrade;
  292. //--- only display market info if the player is allowed to trade with this market ---//
  293. char noTrade;
  294. if( nation_array.player_recno )
  295. noTrade = nation_array[nation_recno]->get_relation(nation_array.player_recno)->trade_treaty==0;
  296. else
  297. noTrade = 0; // the player has been destroyed
  298. if( config.show_ai_info )
  299. noTrade = 0;
  300. if( lastNoTrade != noTrade )
  301. {
  302. lastNoTrade = noTrade;
  303. if( refreshFlag == INFO_UPDATE )
  304. {
  305. info.disp();
  306. return;
  307. }
  308. }
  309. if( noTrade )
  310. {
  311. if( refreshFlag == INFO_REPAINT )
  312. {
  313. vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+51 );
  314. font_san.center_put( INFO_X1, dispY1+3 , INFO_X2, dispY1+25, "You're not permitted to" );
  315. font_san.center_put( INFO_X1, dispY1+23, INFO_X2, dispY1+51, "trade with this market." );
  316. }
  317. return;
  318. }
  319. //-----------------------------------------------------//
  320. int i, x, y=dispY1;
  321. static char* last_bitmap_array[MAX_MARKET_GOODS];
  322. MarketGoods* marketGoods;
  323. String str;
  324. char* bitmapPtr;
  325. for( i=0, marketGoods=market_goods_array ; i<MAX_MARKET_GOODS ; i++, marketGoods++, y+=53 )
  326. {
  327. if( refreshFlag == INFO_REPAINT )
  328. vga.d3_panel_up( INFO_X1, y, INFO_X2, y+51 );
  329. if( marketGoods->raw_id )
  330. {
  331. str = raw_res[marketGoods->raw_id]->name;
  332. bitmapPtr = raw_res.small_raw_icon(marketGoods->raw_id);
  333. }
  334. else if( marketGoods->product_raw_id )
  335. {
  336. #ifdef FRENCH
  337. char productName[20];
  338. strcpy(productName, raw_res[marketGoods->product_raw_id]->name);
  339. strcat(productName, " Products");
  340. str = translate.process(productName);
  341. #else
  342. str = raw_res[marketGoods->product_raw_id]->name;
  343. str += translate.process(" Products");
  344. #endif
  345. bitmapPtr = raw_res.small_product_icon(marketGoods->product_raw_id);
  346. }
  347. else
  348. {
  349. button_clear_stock[i].reset();
  350. continue;
  351. }
  352. //----- if product type changed, refresh info ----//
  353. if( bitmapPtr != last_bitmap_array[i] )
  354. {
  355. refreshFlag = INFO_REPAINT;
  356. last_bitmap_array[i] = bitmapPtr;
  357. }
  358. //------------ display info --------------//
  359. x=INFO_X1+2;
  360. if( refreshFlag == INFO_REPAINT )
  361. {
  362. vga_front.put_bitmap_trans( x+3, y+4, bitmapPtr );
  363. font_san.put( x+19, y+4, str );
  364. if( nation_recno == nation_array.player_recno )
  365. {
  366. button_clear_stock[i].paint_text( INFO_X2-46, y+2, INFO_X2-3, y+19, "Clear" ); // Clear Stock
  367. button_clear_stock[i].set_help_code( "MK_CLEAR" );
  368. }
  369. }
  370. x+=3;
  371. int ty=y+18;
  372. str = (int) marketGoods->stock_qty;
  373. str += "/";
  374. str += (int) max_stock_qty;
  375. font_san.field( x, ty, "Stock", x+60, str, x+119, refreshFlag, "MK_STOCK" );
  376. font_san.field( x, ty+16, "Sales", x+60, (int) marketGoods->sales_365days(), 2,
  377. x+104, refreshFlag, "MK_SALES" );
  378. x+=105;
  379. // ####### patch begin Gilbert 16/3 #########//
  380. //font_san.field( x, ty+16, "Demand", x+70, (int) marketGoods->month_demand, 1,
  381. // INFO_X2-2, refreshFlag, "MK_DEMAN" );
  382. font_san.field( x, ty+16, "Demand", x+67, (int) marketGoods->month_demand, 1,
  383. INFO_X2-1, refreshFlag, "MK_DEMAN" );
  384. // ####### patch end Gilbert 16/3 #########//
  385. }
  386. }
  387. //----------- End of function FirmMarket::put_market_info -----------//
  388. //--------- Begin of function FirmMarket::disp_income ---------//
  389. //
  390. // Display monthly expense information.
  391. //
  392. void FirmMarket::disp_income(int dispY1, int refreshFlag)
  393. {
  394. if( refreshFlag == INFO_REPAINT )
  395. vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+23 );
  396. int x=INFO_X1+4, y=dispY1+4;
  397. font_san.field( x, y, "Yearly Income", x+110, (int) income_365days(), 2, x+200, refreshFlag, "MK_INCOM" );
  398. }
  399. //----------- End of function FirmMarket::disp_income -----------//
  400. //------- Begin of function FirmMarket::draw -----------//
  401. //
  402. // Draw product stocks.
  403. //
  404. void FirmMarket::draw(int displayLayer)
  405. {
  406. Firm::draw(displayLayer);
  407. if( under_construction )
  408. return;
  409. if( displayLayer == 1)
  410. {
  411. //------- draw market goods cargoes ---------//
  412. int i, j, x, y, cargoCount, sectionId=0;
  413. MarketGoods* marketGoods;
  414. char* iconPtr;
  415. for( i=0, marketGoods=market_goods_array ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  416. {
  417. if( marketGoods->raw_id )
  418. iconPtr = raw_res.small_raw_icon(marketGoods->raw_id);
  419. else if( marketGoods->product_raw_id )
  420. iconPtr = raw_res.small_product_icon(marketGoods->product_raw_id);
  421. else
  422. continue;
  423. //------- draw cargo on the firm bitmap buffer --------//
  424. cargoCount = MAX_CARGO * (int)marketGoods->stock_qty/(int)max_stock_qty;
  425. cargoCount = max(1, cargoCount);
  426. x = ZOOM_X1 + (loc_x1-world.zoom_matrix->top_x_loc) * ZOOM_LOC_WIDTH + section_point_array[sectionId].x;
  427. y = ZOOM_Y1 + (loc_y1-world.zoom_matrix->top_y_loc) * ZOOM_LOC_HEIGHT + section_point_array[sectionId].y;
  428. sectionId++;
  429. for( j=0 ; j<cargoCount ; j++ )
  430. {
  431. world.zoom_matrix->put_bitmap_clip(x+slot_point_array[j].x, y+slot_point_array[j].y, iconPtr );
  432. }
  433. }
  434. }
  435. }
  436. //--------- End of function FirmMarket::draw -----------//
  437. //--------- Begin of function FirmMarket::input_goods ---------//
  438. //
  439. // Input goods from factories and mines.
  440. //
  441. // <int> maxInputQty - maximum goods can be inputed in this call.
  442. //
  443. void FirmMarket::input_goods(int maxInputQty)
  444. {
  445. //------ scan for a firm to input raw materials --------//
  446. int i, t;
  447. float inputQty;
  448. Firm* firmPtr;
  449. FirmMine* firmMine;
  450. FirmFactory* firmFactory;
  451. MarketGoods* marketGoods;
  452. Nation* nationPtr = nation_array[nation_recno];
  453. char is_inputing_array[MAX_MARKET_GOODS];
  454. short queued_firm_recno=0;
  455. memset( is_inputing_array, 0, sizeof(is_inputing_array) );
  456. for( t=0 ; t<linked_firm_count ; t++ )
  457. {
  458. if( linked_firm_enable_array[t] != LINK_EE )
  459. continue;
  460. firmPtr = firm_array[linked_firm_array[t]];
  461. //----------- check if the firm is a mine ----------//
  462. if( firmPtr->firm_id != FIRM_MINE && firmPtr->firm_id != FIRM_FACTORY )
  463. continue;
  464. //--------- if it's a mine ------------//
  465. if( firmPtr->firm_id == FIRM_MINE &&
  466. (!firm_ai || !is_retail_market ) )
  467. {
  468. firmMine = (FirmMine*) firmPtr;
  469. if( firmMine->raw_id )
  470. {
  471. for( i=0, marketGoods=market_goods_array ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  472. {
  473. //--- only assign a slot to the product if it comes from a firm of our own ---//
  474. if( marketGoods->raw_id == firmMine->raw_id )
  475. {
  476. is_inputing_array[i] = 1;
  477. if( firmMine->next_output_firm_recno == firm_recno &&
  478. firmMine->stock_qty > 0 && marketGoods->stock_qty < max_stock_qty )
  479. {
  480. inputQty = min( firmMine->stock_qty, maxInputQty );
  481. inputQty = min( inputQty, max_stock_qty - marketGoods->stock_qty );
  482. firmMine->stock_qty -= inputQty;
  483. marketGoods->stock_qty += inputQty;
  484. marketGoods->cur_month_supply += inputQty;
  485. if( firmPtr->nation_recno != nation_recno )
  486. nationPtr->import_goods(IMPORT_RAW, firmPtr->nation_recno, inputQty*RAW_PRICE );
  487. }
  488. else if( marketGoods->stock_qty == max_stock_qty )
  489. {
  490. marketGoods->cur_month_supply++; // add it so the other functions can know that this market has direct supply links
  491. }
  492. break;
  493. }
  494. }
  495. //----- no matched slot for this goods -----//
  496. if( i==MAX_MARKET_GOODS && firmMine->stock_qty>0 && !queued_firm_recno )
  497. queued_firm_recno = firmPtr->firm_recno;
  498. }
  499. }
  500. //--------- if it's a factory ------------//
  501. else if( firmPtr->firm_id == FIRM_FACTORY &&
  502. (!firm_ai || is_retail_market ) )
  503. {
  504. firmFactory = (FirmFactory*) firmPtr;
  505. if( firmFactory->product_raw_id )
  506. {
  507. for( i=0, marketGoods=market_goods_array ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  508. {
  509. if( marketGoods->product_raw_id == firmFactory->product_raw_id )
  510. {
  511. is_inputing_array[i] = 1;
  512. if( firmFactory->next_output_firm_recno == firm_recno &&
  513. firmFactory->stock_qty > 0 && marketGoods->stock_qty < max_stock_qty )
  514. {
  515. inputQty = min( firmFactory->stock_qty, maxInputQty );
  516. inputQty = min( inputQty, max_stock_qty - marketGoods->stock_qty );
  517. firmFactory->stock_qty -= inputQty;
  518. marketGoods->stock_qty += inputQty;
  519. marketGoods->cur_month_supply += inputQty;
  520. if( firmPtr->nation_recno != nation_recno )
  521. nationPtr->import_goods(IMPORT_PRODUCT, firmPtr->nation_recno, inputQty*PRODUCT_PRICE );
  522. }
  523. else if( marketGoods->stock_qty == max_stock_qty )
  524. {
  525. marketGoods->cur_month_supply++; // add it so the other functions can know that this market has direct supply links
  526. }
  527. break;
  528. }
  529. }
  530. //----- no matched slot for this goods -----//
  531. if( i==MAX_MARKET_GOODS && firmFactory->stock_qty>0 && !queued_firm_recno )
  532. queued_firm_recno = firmPtr->firm_recno;
  533. }
  534. }
  535. }
  536. //---- if there are any empty slots for new goods -----//
  537. if( queued_firm_recno > 0 )
  538. {
  539. firmPtr = firm_array[queued_firm_recno];
  540. for( i=0, marketGoods=market_goods_array ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  541. {
  542. if( !is_inputing_array[i] && marketGoods->stock_qty==0 )
  543. {
  544. if( firmPtr->firm_id == FIRM_MINE )
  545. {
  546. set_goods(1, ((FirmMine*)firmPtr)->raw_id, i);
  547. break;
  548. }
  549. else if( firmPtr->firm_id == FIRM_FACTORY )
  550. {
  551. set_goods(0, ((FirmFactory*)firmPtr)->product_raw_id, i);
  552. break;
  553. }
  554. }
  555. }
  556. }
  557. }
  558. //----------- End of function FirmMarket::input_goods -----------//
  559. //------- Begin of function FirmMarket::set_goods -----------//
  560. void FirmMarket::set_goods(int isRaw, int goodsId, int position)
  561. {
  562. MarketGoods *marketGoods = market_goods_array+position;
  563. if(isRaw)
  564. {
  565. if(marketGoods->raw_id)
  566. market_raw_array[marketGoods->raw_id-1] = NULL;
  567. else if(marketGoods->product_raw_id)
  568. market_product_array[marketGoods->product_raw_id-1] = NULL;
  569. marketGoods->raw_id = goodsId;
  570. marketGoods->product_raw_id = 0;
  571. market_raw_array[goodsId-1] = marketGoods;
  572. }
  573. else
  574. {
  575. if(marketGoods->product_raw_id)
  576. market_product_array[marketGoods->product_raw_id-1] = NULL;
  577. else if(marketGoods->raw_id)
  578. market_raw_array[marketGoods->raw_id-1] = NULL;
  579. marketGoods->raw_id = 0;
  580. marketGoods->product_raw_id = goodsId;
  581. market_product_array[goodsId-1] = marketGoods;
  582. }
  583. if( firm_array.selected_recno == firm_recno )
  584. info.disp();
  585. }
  586. //----------- End of function FirmMarket::set_goods -----------//
  587. //------- Begin of function FirmMarket::sell_goods -----------//
  588. //
  589. // Sell products to consumers. Called by Town::sell_goods()
  590. //
  591. void FirmMarket::sell_goods()
  592. {
  593. //----------- sell products now ------------//
  594. int i;
  595. float saleQty;
  596. MarketGoods* marketGoods;
  597. for( i=0, marketGoods=market_goods_array ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  598. {
  599. if( marketGoods->product_raw_id && marketGoods->stock_qty > 0 )
  600. {
  601. saleQty = min(marketGoods->month_demand/30, marketGoods->stock_qty);
  602. marketGoods->stock_qty -= saleQty;
  603. marketGoods->cur_month_sale_qty += saleQty;
  604. marketGoods->cur_year_sales += saleQty * CONSUMER_PRICE;
  605. add_income(INCOME_SELL_GOODS, saleQty * CONSUMER_PRICE);
  606. }
  607. }
  608. }
  609. //--------- End of function FirmMarket::sell_goods -----------//
  610. //------- Begin of function FirmMarket::free_unused_slot -----------//
  611. //
  612. // Free up unused slots (those with sales==0 and stock_qty==0)
  613. //
  614. void FirmMarket::free_unused_slot()
  615. {
  616. int i;
  617. MarketGoods* marketGoods;
  618. for( i=0, marketGoods=market_goods_array ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  619. {
  620. if( marketGoods->product_raw_id || marketGoods->raw_id )
  621. {
  622. if( marketGoods->sales_365days()==0 &&
  623. marketGoods->supply_30days()==0 &&
  624. marketGoods->stock_qty==0 )
  625. {
  626. clear_market_goods(i+1);
  627. }
  628. }
  629. }
  630. }
  631. //--------- End of function FirmMarket::free_unused_slot -----------//
  632. //------- Begin of function FirmMarket::clear_market_goods ------//
  633. void FirmMarket::clear_market_goods(int position)
  634. {
  635. MarketGoods *marketGoods = market_goods_array + position - 1;
  636. err_when((marketGoods->raw_id && marketGoods->product_raw_id) ||
  637. (!marketGoods->raw_id && !marketGoods->product_raw_id));
  638. marketGoods->stock_qty = (float) 0;
  639. if(marketGoods->raw_id)
  640. {
  641. market_raw_array[marketGoods->raw_id-1] = NULL;
  642. marketGoods->raw_id = 0;
  643. }
  644. else
  645. {
  646. market_product_array[marketGoods->raw_id-1] = NULL;
  647. marketGoods->product_raw_id = 0;
  648. }
  649. }
  650. //--------- End of function FirmMarket::clear_market_goods -----------//
  651. //------- Begin of function FirmMarket::set_next_output_firm ------//
  652. //
  653. // Set next_output_firm_recno, the recno of the linked firm
  654. // to which this firm is going to output goods.
  655. //
  656. void FirmMarket::set_next_output_firm()
  657. {
  658. int i, firmRecno, firmId;
  659. for( i=0 ; i<linked_firm_count ; i++ ) // max tries
  660. {
  661. if( ++next_output_link_id > linked_firm_count ) // next firm in the link
  662. next_output_link_id = 1;
  663. if( linked_firm_enable_array[next_output_link_id-1] == LINK_EE )
  664. {
  665. firmRecno = linked_firm_array[next_output_link_id-1];
  666. firmId = firm_array[firmRecno]->firm_id;
  667. if( firmId==FIRM_FACTORY )
  668. {
  669. next_output_firm_recno = firmRecno;
  670. return;
  671. }
  672. }
  673. }
  674. next_output_firm_recno = 0; // this mine has no linked output firms
  675. }
  676. //-------- End of function FirmMarket::set_next_output_firm ---------//
  677. //------- Begin of function FirmMarket::stock_value_index ------//
  678. //
  679. // For AI, return a 0-100 index number telling the total value
  680. // of the market's stock.
  681. //
  682. int FirmMarket::stock_value_index()
  683. {
  684. int i;
  685. float totalValue = (float) 0;
  686. MarketGoods* marketGoods;
  687. for( i=0, marketGoods=market_goods_array ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  688. {
  689. if( marketGoods->raw_id )
  690. {
  691. totalValue += marketGoods->stock_qty * RAW_PRICE;
  692. }
  693. else if( marketGoods->product_raw_id )
  694. {
  695. totalValue += marketGoods->stock_qty * PRODUCT_PRICE;
  696. }
  697. }
  698. return 100 * (int)totalValue / (MAX_MARKET_GOODS * PRODUCT_PRICE * MAX_MARKET_STOCK);
  699. }
  700. //-------- End of function FirmMarket::stock_value_index ---------//
  701. //--------- Begin of function FirmMarket::free_slot_count ---------//
  702. //
  703. // Count the number of free slots available in the market.
  704. //
  705. int FirmMarket::free_slot_count()
  706. {
  707. MarketGoods* marketGoods = market_goods_array;
  708. int freeSlotCount = 0;
  709. for( int i=0 ; i<MAX_MARKET_GOODS ; i++, marketGoods++ )
  710. {
  711. if( !marketGoods->raw_id && !marketGoods->product_raw_id )
  712. freeSlotCount++;
  713. }
  714. return freeSlotCount;
  715. }
  716. //----------- End of function FirmMarket::free_slot_count -----------//
  717. //--------- Begin of function FirmMarket::read_derived_file ---------//
  718. //
  719. int FirmMarket::read_derived_file(File* filePtr)
  720. {
  721. if( !Firm::read_derived_file(filePtr) )
  722. return 0;
  723. //----- reset market_raw_array[] & market_product_array[] ----//
  724. int i;
  725. for( i=0 ; i<MAX_RAW ; i++ )
  726. {
  727. market_raw_array[i] = NULL;
  728. market_product_array[i] = NULL;
  729. }
  730. //------- rebuild market_product_array --------//
  731. int rawId, productId;
  732. for( i=0 ; i<MAX_MARKET_GOODS ; i++ )
  733. {
  734. rawId = market_goods_array[i].raw_id;
  735. productId = market_goods_array[i].product_raw_id;
  736. if( rawId )
  737. market_raw_array[rawId-1] = market_goods_array + i;
  738. if( productId )
  739. market_product_array[productId-1] = market_goods_array + i;
  740. }
  741. return 1;
  742. }
  743. //----------- End of function FirmMarket::read_derived_file -----------//
  744. //----- Begin of function FirmMarket::update_trade_link -----//
  745. //
  746. // Update the status of links to harbors and towns based
  747. // on the current trade treaty status.
  748. //
  749. void FirmMarket::update_trade_link()
  750. {
  751. Nation* ownNation = nation_array[nation_recno];
  752. int tradeTreaty;
  753. //------ update links to harbors -----//
  754. Firm* firmPtr;
  755. int i;
  756. for( i=0 ; i<linked_firm_count ; i++ )
  757. {
  758. firmPtr = firm_array[linked_firm_array[i]];
  759. if( firmPtr->firm_id != FIRM_HARBOR )
  760. continue;
  761. tradeTreaty = ownNation->get_relation(firmPtr->nation_recno)->trade_treaty || firmPtr->nation_recno==nation_recno;
  762. if( linked_firm_enable_array[i] != (tradeTreaty ? LINK_EE : LINK_DD) )
  763. toggle_firm_link( i+1, tradeTreaty, COMMAND_AUTO, 1 ); // 1-toggle both side
  764. }
  765. //------ update links to towns -----//
  766. Town* townPtr;
  767. for( i=0 ; i<linked_town_count ; i++ )
  768. {
  769. townPtr = town_array[linked_town_array[i]];
  770. if( !townPtr->nation_recno )
  771. continue;
  772. tradeTreaty = ownNation->get_relation(townPtr->nation_recno)->trade_treaty || townPtr->nation_recno==nation_recno;
  773. if( linked_town_enable_array[i] != (tradeTreaty ? LINK_EE : LINK_DD) )
  774. toggle_town_link( i+1, tradeTreaty, COMMAND_AUTO, 1 ); // 1-toggle both side
  775. }
  776. }
  777. //------ End of function FirmMarket::update_trade_link -----//