OU_MARIT.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405
  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_MARI3.CPP
  21. //Description: UnitMarine - functions for loading/unloading goods, trading
  22. #include <ALL.h>
  23. #include <OREMOTE.h>
  24. #include <OU_CARA.h>
  25. #include <OU_MARI.h>
  26. #include <OF_HARB.h>
  27. #include <ONATION.h>
  28. #include <OF_FACT.h>
  29. #include <OF_MINE.h>
  30. #include <OCONFIG.h>
  31. static char mprocessed_raw_qty_array[MAX_LINKED_FIRM_FIRM][MAX_RAW]; // 1 for not unload but can up load, 2 for unload but not up load
  32. static char mprocessed_product_raw_qty_array[MAX_LINKED_FIRM_FIRM][MAX_PRODUCT]; // ditto
  33. static char linked_mine_num;
  34. static char linked_factory_num;
  35. static char linked_market_num;
  36. static short linked_mine_array[MAX_LINKED_FIRM_FIRM];
  37. static short linked_factory_array[MAX_LINKED_FIRM_FIRM];
  38. static short linked_market_array[MAX_LINKED_FIRM_FIRM];
  39. static char empty_slot_position_array[MAX_LINKED_FIRM_FIRM];
  40. static char firm_selected_array[MAX_LINKED_FIRM_FIRM];
  41. //--------- Begin of function UnitMarine::del_stop ---------//
  42. void UnitMarine::del_stop(int stopId, char remoteAction)
  43. {
  44. // ####### begin Gilbert 30/7 #######//
  45. if(!remoteAction && remote.is_enable())
  46. {
  47. // packet structure : <unit recno> <stop id>
  48. short *shortPtr = (short *) remote.new_send_queue_msg(MSG_U_SHIP_DEL_STOP, 2*sizeof(short));
  49. *shortPtr = sprite_recno;
  50. shortPtr[1] = stopId;
  51. return;
  52. }
  53. // ####### end Gilbert 30/7 #######//
  54. if(remote.is_enable() && stop_array[stopId-1].firm_recno==0)
  55. return;
  56. stop_array[stopId-1].firm_recno = 0;
  57. stop_defined_num--;
  58. update_stop_list();
  59. if(unit_array.selected_recno==sprite_recno)
  60. {
  61. if(!remote.is_enable() || nation_recno==nation_array.player_recno || config.show_ai_info)
  62. info.disp();
  63. }
  64. }
  65. //---------- End of function UnitMarine::del_stop ----------//
  66. //--------- Begin of function UnitMarine::update_stop_list ---------//
  67. void UnitMarine::update_stop_list()
  68. {
  69. //------------- used to debug for multiplayer game ------------------//
  70. #ifdef DEBUG
  71. m.random(100);
  72. #endif
  73. //-------------------------------------------------------//
  74. // backup original destination stop firm recno
  75. //-------------------------------------------------------//
  76. err_when(stop_defined_num<0 || stop_defined_num>MAX_STOP_FOR_SHIP);
  77. short nextStopRecno = dest_stop_id ? stop_array[dest_stop_id-1].firm_recno : 0;
  78. //----------------------------------------------------------------------//
  79. // check stop existence and the relationship between firm's nation
  80. //----------------------------------------------------------------------//
  81. ShipStop *nodePtr = stop_array;
  82. Firm *firmPtr;
  83. int i;
  84. for(i=0; i<MAX_STOP_FOR_SHIP; i++, nodePtr++)
  85. {
  86. if(!nodePtr->firm_recno)
  87. continue;
  88. if(firm_array.is_deleted(nodePtr->firm_recno))
  89. {
  90. nodePtr->firm_recno = 0; // clear the recno
  91. stop_defined_num--;
  92. continue;
  93. }
  94. firmPtr = firm_array[nodePtr->firm_recno];
  95. if( !can_set_stop(firmPtr->firm_recno) ||
  96. firmPtr->loc_x1 != nodePtr->firm_loc_x1 ||
  97. firmPtr->loc_y1 != nodePtr->firm_loc_y1 )
  98. {
  99. nodePtr->firm_recno = 0;
  100. stop_defined_num--;
  101. continue;
  102. }
  103. }
  104. //-------------------------------------------------------//
  105. // remove duplicate node
  106. //-------------------------------------------------------//
  107. ShipStop *insertNodePtr = stop_array;
  108. if(stop_defined_num<1)
  109. {
  110. memset(stop_array, 0, sizeof(ShipStop)*MAX_STOP_FOR_SHIP);
  111. dest_stop_id = 0;
  112. return; // no stop
  113. }
  114. //-------------------------------------------------------//
  115. // move the only firm_recno to the beginning of the array
  116. //-------------------------------------------------------//
  117. short compareRecno;
  118. for(i=0, nodePtr=stop_array; i<MAX_STOP_FOR_SHIP; i++, nodePtr++)
  119. {
  120. if(nodePtr->firm_recno)
  121. {
  122. compareRecno = nodePtr->firm_recno;
  123. break;
  124. }
  125. }
  126. if(i++) // else, the first record is already in the beginning of the array
  127. memcpy(insertNodePtr, nodePtr, sizeof(ShipStop));
  128. if(stop_defined_num==1)
  129. {
  130. memset(insertNodePtr+1, 0, sizeof(ShipStop)*(MAX_STOP_FOR_SHIP-1));
  131. dest_stop_id = 1;
  132. return;
  133. }
  134. short unprocessed = stop_defined_num-1;
  135. err_when(i==MAX_STOP_FOR_SHIP); // error if only one record
  136. err_when(!unprocessed);
  137. insertNodePtr++;
  138. nodePtr++;
  139. for(; i<MAX_STOP_FOR_SHIP && unprocessed; i++, nodePtr++)
  140. {
  141. if(!nodePtr->firm_recno)
  142. continue; // empty
  143. err_when(!nodePtr->firm_recno);
  144. if(nodePtr->firm_recno==compareRecno)
  145. {
  146. nodePtr->firm_recno = 0;
  147. stop_defined_num--;
  148. }
  149. else
  150. {
  151. compareRecno = nodePtr->firm_recno;
  152. if(insertNodePtr!=nodePtr)
  153. memcpy(insertNodePtr++, nodePtr, sizeof(ShipStop));
  154. else
  155. insertNodePtr++;
  156. }
  157. unprocessed--;
  158. }
  159. if(stop_defined_num>2)
  160. {
  161. //-------- compare the first and the end record -------//
  162. nodePtr = stop_array + stop_defined_num - 1; // point to the end
  163. if(nodePtr->firm_recno == stop_array[0].firm_recno)
  164. {
  165. nodePtr->firm_recno = 0; // remove the end record
  166. stop_defined_num--;
  167. }
  168. }
  169. if(stop_defined_num<MAX_STOP_FOR_SHIP)
  170. memset(stop_array+stop_defined_num, 0, sizeof(ShipStop)*(MAX_STOP_FOR_SHIP-stop_defined_num));
  171. #ifdef DEBUG
  172. int debugCount;
  173. for(debugCount=0; debugCount<stop_defined_num; debugCount++)
  174. err_when(!stop_array[debugCount].firm_recno);
  175. for(; debugCount<MAX_STOP_FOR_SHIP; debugCount++)
  176. err_when(stop_array[debugCount].firm_recno);
  177. for(debugCount=0; debugCount<stop_defined_num; debugCount++)
  178. err_when(stop_array[debugCount].firm_recno &&
  179. stop_array[debugCount].firm_recno==stop_array[(debugCount+1)%MAX_STOP_FOR_SHIP].firm_recno);
  180. #endif
  181. //-----------------------------------------------------------------------------------------//
  182. // There should be at least one stop in the list. Otherwise, clear all the stops
  183. //-----------------------------------------------------------------------------------------//
  184. int ourFirmExist = 0;
  185. for(i=0, nodePtr=stop_array; i<stop_defined_num; i++, nodePtr++)
  186. {
  187. err_when(firm_array.is_deleted(nodePtr->firm_recno));
  188. firmPtr = firm_array[nodePtr->firm_recno];
  189. if(firmPtr->nation_recno==nation_recno)
  190. {
  191. ourFirmExist++;
  192. break;
  193. }
  194. }
  195. if(!ourFirmExist) // none of the markets belong to our nation
  196. {
  197. memset(stop_array, 0, MAX_STOP_FOR_SHIP * sizeof(ShipStop));
  198. journey_status = ON_WAY_TO_FIRM;
  199. dest_stop_id = 0;
  200. stop_defined_num = 0;
  201. return;
  202. }
  203. //-----------------------------------------------------------------------------------------//
  204. // reset dest_stop_id since the order of the stop may be changed
  205. //-----------------------------------------------------------------------------------------//
  206. int xLoc = next_x_loc();
  207. int yLoc = next_y_loc();
  208. int dist, minDist=0x7FFF;
  209. for(i=0, dest_stop_id=0, nodePtr=stop_array; i<stop_defined_num; i++, nodePtr++)
  210. {
  211. if(nodePtr->firm_recno==nextStopRecno)
  212. {
  213. dest_stop_id = i+1;
  214. break;
  215. }
  216. else
  217. {
  218. firmPtr = firm_array[nodePtr->firm_recno];
  219. dist = m.points_distance(xLoc, yLoc, firmPtr->center_x, firmPtr->center_y);
  220. if(dist<minDist)
  221. {
  222. dist = minDist;
  223. dest_stop_id = i+1;
  224. }
  225. }
  226. }
  227. err_when(dest_stop_id<0 || dest_stop_id>MAX_STOP_FOR_SHIP);
  228. }
  229. //----------- End of function UnitMarine::update_stop_list -----------//
  230. //--------- Begin of function UnitMarine::get_next_stop_id ---------//
  231. // Get the id. of the next defined stop.
  232. //
  233. // [int] curStopId - the id. of the current stop.
  234. // if it is MAX_STOP_FOR_SHIP, this function will return
  235. // the id. of the first valid stop.
  236. //
  237. // (default: MAX_STOP_FOR_SHIP)
  238. // return : 0 ~ MAX_STOP_FOR_SHIP, where 0 for no valid stop
  239. //
  240. int UnitMarine::get_next_stop_id(int curStopId)
  241. {
  242. int nextStopId = (curStopId>=stop_defined_num) ? 1 : curStopId+1;
  243. ShipStop *stopPtr = stop_array+nextStopId-1;
  244. int needUpdate = 0;
  245. if(firm_array.is_deleted(stopPtr->firm_recno))
  246. needUpdate++;
  247. else
  248. {
  249. Firm *firmPtr = firm_array[stopPtr->firm_recno];
  250. if( !can_set_stop(firmPtr->firm_recno) ||
  251. firmPtr->loc_x1 != stopPtr->firm_loc_x1 ||
  252. firmPtr->loc_y1 != stopPtr->firm_loc_y1 )
  253. {
  254. needUpdate++;
  255. }
  256. }
  257. if(needUpdate)
  258. {
  259. short preStopRecno = stop_array[curStopId-1].firm_recno;
  260. update_stop_list();
  261. if(!stop_defined_num)
  262. return 0; // no stop is valid
  263. int i;
  264. for(i=1, stopPtr=stop_array; i<=stop_defined_num; i++, stopPtr++)
  265. {
  266. if(stopPtr->firm_recno==preStopRecno)
  267. nextStopId = (i>=stop_defined_num) ? 1 : i+1;
  268. }
  269. }
  270. return nextStopId;
  271. }
  272. //----------- End of function UnitMarine::get_next_stop_id -----------//
  273. //--------- Begin of function UnitMarine::can_set_stop ---------//
  274. //
  275. // Whether can set a caravan's stop on the given firm.
  276. //
  277. int UnitMarine::can_set_stop(int firmRecno)
  278. {
  279. Firm* firmPtr = firm_array[firmRecno];
  280. if( firmPtr->under_construction )
  281. return 0;
  282. if( firmPtr->firm_id != FIRM_HARBOR )
  283. return 0;
  284. return nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty;
  285. }
  286. //----------- End of function UnitMarine::can_set_stop -----------//
  287. //--------- Begin of function UnitMarine::pre_process ---------//
  288. void UnitMarine::pre_process()
  289. {
  290. #define SURROUND_FIRM_WAIT_FACTOR 10
  291. Unit::pre_process();
  292. if(hit_points<=0 || action_mode==ACTION_DIE || cur_action==SPRITE_DIE)
  293. return;
  294. err_when(action_mode==ACTION_DIE || cur_action==SPRITE_DIE || hit_points<=0);
  295. if(action_mode2>=ACTION_ATTACK_UNIT && action_mode2<=ACTION_ATTACK_WALL)
  296. return; // don't process trading if unit is attacking
  297. if(auto_mode) // process trading automatically, same as caravan
  298. {
  299. if(!stop_defined_num)
  300. return;
  301. //----------------- if there is only one defined stop --------------------//
  302. if(stop_defined_num==1)
  303. {
  304. if( firm_array.is_deleted(stop_array[0].firm_recno) )
  305. {
  306. update_stop_list();
  307. return;
  308. }
  309. Firm *firmPtr = firm_array[stop_array[0].firm_recno];
  310. if(firmPtr->loc_x1!=stop_array[0].firm_loc_x1 || firmPtr->loc_y1!=stop_array[0].firm_loc_y1)
  311. {
  312. update_stop_list();
  313. return;
  314. }
  315. int curXLoc = next_x_loc();
  316. int curYLoc = next_y_loc();
  317. int moveStep = move_step_magn();
  318. if(curXLoc<firmPtr->loc_x1-moveStep || curXLoc>firmPtr->loc_x2+moveStep ||
  319. curYLoc<firmPtr->loc_y1-moveStep || curYLoc>firmPtr->loc_y2+moveStep)
  320. {
  321. //### begin alex 6/10 ###//
  322. /*if((move_to_x_loc>=firmPtr->loc_x1-moveStep || move_to_x_loc<=firmPtr->loc_x2+moveStep) &&
  323. (move_to_y_loc>=firmPtr->loc_y1-moveStep || move_to_y_loc<=firmPtr->loc_y2+moveStep))
  324. return;
  325. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
  326. journey_status = ON_WAY_TO_FIRM;*/
  327. if(cur_action==SPRITE_IDLE)
  328. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
  329. else
  330. journey_status = ON_WAY_TO_FIRM;
  331. //#### end alex 6/10 ####//
  332. }
  333. else
  334. {
  335. if(cur_x==next_x && cur_y==next_y && cur_action==SPRITE_IDLE)
  336. {
  337. journey_status = SURROUND_FIRM;
  338. if(nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty)
  339. {
  340. if(wait_count<=0)
  341. {
  342. //---------- unloading goods -------------//
  343. cur_firm_recno = stop_array[0].firm_recno;
  344. get_harbor_linked_firm_info();
  345. harbor_unload_goods();
  346. wait_count = MAX_SHIP_WAIT_TERM*SURROUND_FIRM_WAIT_FACTOR;
  347. cur_firm_recno = 0;
  348. }
  349. else
  350. wait_count--;
  351. }
  352. }
  353. }
  354. return;
  355. }
  356. //------------ if there are more than one defined stop ---------------//
  357. err_when(stop_defined_num<=1);
  358. if(journey_status==INSIDE_FIRM)
  359. ship_in_firm();
  360. else
  361. ship_on_way();
  362. }
  363. else if(journey_status==INSIDE_FIRM)
  364. ship_in_firm(0); // autoMode is off
  365. }
  366. //---------- End of function UnitMarine::pre_process ----------//
  367. //--------- Begin of function UnitMarine::ship_in_firm ---------//
  368. // journey_status : INSIDE_FIRM --> ON_WAY_TO_FIRM
  369. // NO_STOP_DEFINED if no valid stop
  370. // SURROUND_FIRM if only one stop
  371. //
  372. // <int> autoMode - 1 if autoMode is on
  373. // - 0 otherwise
  374. //
  375. void UnitMarine::ship_in_firm(int autoMode)
  376. {
  377. //-----------------------------------------------------------------------------//
  378. // the harbor is deleted while the ship is in harbor
  379. //-----------------------------------------------------------------------------//
  380. if(cur_firm_recno && firm_array.is_deleted(cur_firm_recno))
  381. {
  382. hit_points = (float) 0; // ship also die if the harbor is deleted
  383. unit_array.disappear_in_firm(sprite_recno); // ship also die if the harnor is deleted
  384. return;
  385. }
  386. //-----------------------------------------------------------------------------//
  387. // waiting (time to upload/download cargo)
  388. //-----------------------------------------------------------------------------//
  389. if(wait_count>0)
  390. {
  391. wait_count--;
  392. return;
  393. }
  394. //-----------------------------------------------------------------------------//
  395. // leave the harbor and go to another harbor if possible
  396. //-----------------------------------------------------------------------------//
  397. ShipStop *stopPtr = stop_array + dest_stop_id - 1;
  398. int xLoc = stop_x_loc;
  399. int yLoc = stop_y_loc;
  400. Location *locPtr = world.get_loc(xLoc, yLoc);
  401. Firm *firmPtr;
  402. if(xLoc%2==0 && yLoc%2==0 && locPtr->can_move(mobile_type))
  403. init_sprite(xLoc, yLoc); // appear in the location the unit disappeared before
  404. else
  405. {
  406. //---- the entering location is blocked, select another location to leave ----//
  407. err_when(cur_firm_recno==0);
  408. firmPtr = firm_array[cur_firm_recno];
  409. if(appear_in_firm_surround(xLoc, yLoc, firmPtr))
  410. {
  411. init_sprite(xLoc, yLoc);
  412. stop();
  413. }
  414. else
  415. {
  416. wait_count = MAX_SHIP_WAIT_TERM*10; //********* BUGHERE, continue to wait or ....
  417. return;
  418. }
  419. }
  420. //-------------- get next stop id. ----------------//
  421. int nextStopId = get_next_stop_id(dest_stop_id);
  422. if(!nextStopId || dest_stop_id==nextStopId)
  423. {
  424. dest_stop_id = nextStopId;
  425. journey_status = (!nextStopId) ? NO_STOP_DEFINED : SURROUND_FIRM;
  426. return; // no stop or only one stop is valid
  427. }
  428. dest_stop_id = nextStopId;
  429. firmPtr = firm_array[stop_array[dest_stop_id-1].firm_recno];
  430. cur_firm_recno = 0;
  431. journey_status = ON_WAY_TO_FIRM;
  432. if(autoMode) // move to next firm only if autoMode is on
  433. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, FIRM_HARBOR);
  434. }
  435. //---------- End of function UnitMarine::ship_in_firm ----------//
  436. //--------- Begin of function UnitMarine::ship_on_way ---------//
  437. void UnitMarine::ship_on_way()
  438. {
  439. //### begin alex 6/10 ###//
  440. //FirmInfo *firmInfo = firm_res[FIRM_HARBOR];
  441. //#### end alex 6/10 ####//
  442. if(cur_action==SPRITE_IDLE && journey_status!=SURROUND_FIRM)
  443. {
  444. if(!firm_array.is_deleted(stop_array[dest_stop_id-1].firm_recno))
  445. {
  446. Firm *firmPtr = firm_array[stop_array[dest_stop_id-1].firm_recno];
  447. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, FIRM_HARBOR);
  448. int nextXLoc = next_x_loc();
  449. int nextYLoc = next_y_loc();
  450. int moveStep = move_step_magn();
  451. if(nextXLoc>=firmPtr->loc_x1-moveStep && nextXLoc<=firmPtr->loc_x2+moveStep &&
  452. nextYLoc>=firmPtr->loc_y1-moveStep && nextYLoc<=firmPtr->loc_y2+moveStep)
  453. journey_status = SURROUND_FIRM;
  454. return;
  455. }
  456. }
  457. err_when(cur_action==SPRITE_ATTACK || action_mode==ACTION_ATTACK_UNIT || action_mode==ACTION_ATTACK_FIRM ||
  458. action_mode==ACTION_ATTACK_TOWN || action_mode==ACTION_ATTACK_WALL);
  459. if(unit_array.is_deleted(sprite_recno))
  460. return; //-***************** BUGHERE ***************//
  461. if(firm_array.is_deleted(stop_array[dest_stop_id-1].firm_recno))
  462. {
  463. update_stop_list();
  464. if(stop_defined_num) // move to next stop
  465. {
  466. Firm *firmPtr = firm_array[stop_array[dest_stop_id-1].firm_recno];
  467. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
  468. }
  469. return;
  470. }
  471. ShipStop *stopPtr = stop_array + dest_stop_id - 1;
  472. Firm *firmPtr = firm_array[stopPtr->firm_recno];
  473. int nextXLoc = next_x_loc();
  474. int nextYLoc = next_y_loc();
  475. int moveStep = move_step_magn();
  476. if(journey_status==SURROUND_FIRM ||
  477. ( nextXLoc==move_to_x_loc && nextYLoc==move_to_y_loc && cur_x==next_x && cur_y==next_y && // move in a tile exactly
  478. (nextXLoc>=firmPtr->loc_x1-moveStep && nextXLoc<=firmPtr->loc_x2+moveStep &&
  479. nextYLoc>=firmPtr->loc_y1-moveStep && nextYLoc<=firmPtr->loc_y2+moveStep) ))
  480. {
  481. extra_move_in_beach = NO_EXTRA_MOVE; // since the ship may enter the firm in odd location
  482. stopPtr->update_pick_up();
  483. //-------------------------------------------------------//
  484. // load/unload goods
  485. //-------------------------------------------------------//
  486. cur_firm_recno = stopPtr->firm_recno;
  487. if(nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty)
  488. {
  489. get_harbor_linked_firm_info();
  490. harbor_unload_goods();
  491. if(stopPtr->pick_up_type == AUTO_PICK_UP)
  492. harbor_auto_load_goods();
  493. else if(stopPtr->pick_up_type!=NO_PICK_UP)
  494. harbor_load_goods();
  495. }
  496. //-------------------------------------------------------//
  497. //-------------------------------------------------------//
  498. stop_x_loc = move_to_x_loc; // store entering location
  499. stop_y_loc = move_to_y_loc;
  500. wait_count = MAX_SHIP_WAIT_TERM; // set waiting term
  501. reset_path();
  502. deinit_sprite(1); // the ship enters the harbor now. 1-keep it selected if it is currently selected
  503. err_when(cur_x!=-1);
  504. cur_x--; // set cur_x to -2, such that invisible but still process pre_process()
  505. journey_status = INSIDE_FIRM;
  506. }
  507. else
  508. {
  509. if(cur_action!=SPRITE_MOVE)
  510. {
  511. //----------------------------------------------------//
  512. // blocked by something, go to the destination again
  513. // note: if return value is 0, cannot reach the firm. //*********BUGHERE
  514. //----------------------------------------------------//
  515. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, FIRM_HARBOR);
  516. journey_status = ON_WAY_TO_FIRM;
  517. }
  518. }
  519. }
  520. //---------- End of function UnitMarine::ship_on_way ----------//
  521. //--------- Begin of function UnitMarine::appear_in_firm_surround ---------//
  522. int UnitMarine::appear_in_firm_surround(int& xLoc, int& yLoc, Firm* firmPtr)
  523. {
  524. FirmInfo *firmInfo = firm_res[FIRM_HARBOR];
  525. int firmWidth = firmInfo->loc_width;
  526. int firmHeight = firmInfo->loc_height;
  527. int smallestCount = firmWidth * firmHeight + 1;
  528. int largestCount = (firmWidth+2) * (firmHeight+2);
  529. int countLimit = largestCount - smallestCount;
  530. int count = m.random(countLimit)+smallestCount;
  531. int checkXLoc, checkYLoc, xOffset, yOffset, found=0;
  532. Location *locPtr;
  533. //-----------------------------------------------------------------//
  534. for(int i=0; i<countLimit; i++)
  535. {
  536. m.cal_move_around_a_point(count, firmWidth, firmHeight, xOffset, yOffset);
  537. checkXLoc = firmPtr->loc_x1 + xOffset;
  538. checkYLoc = firmPtr->loc_y1 + yOffset;
  539. if(checkXLoc%2 || checkYLoc%2||
  540. checkXLoc<0 || checkXLoc>=MAX_WORLD_X_LOC || checkYLoc<0 || checkYLoc>=MAX_WORLD_Y_LOC)
  541. {
  542. count++;
  543. continue;
  544. }
  545. locPtr = world.get_loc(checkXLoc, checkYLoc);
  546. if(locPtr->can_move(mobile_type))
  547. {
  548. found++;
  549. break;
  550. }
  551. count++;
  552. if(count > largestCount)
  553. count = smallestCount;
  554. }
  555. //-----------------------------------------------------------------//
  556. if(found)
  557. {
  558. xLoc = checkXLoc;
  559. yLoc = checkYLoc;
  560. return 1;
  561. }
  562. return 0;
  563. }
  564. //---------- End of function UnitMarine::appear_in_firm_surround ----------//
  565. //--------- Begin of function UnitMarine::get_harbor_linked_firm_info ---------//
  566. void UnitMarine::get_harbor_linked_firm_info()
  567. {
  568. FirmHarbor *firmHarborPtr = (FirmHarbor*) firm_array[cur_firm_recno];
  569. err_when(firmHarborPtr->firm_id!=FIRM_HARBOR);
  570. firmHarborPtr->update_linked_firm_info();
  571. linked_mine_num = firmHarborPtr->get_linked_mine_num();
  572. linked_factory_num = firmHarborPtr->get_linked_factory_num();
  573. linked_market_num = firmHarborPtr->get_linked_market_num();
  574. memcpy(linked_mine_array, firmHarborPtr->linked_mine_array, sizeof(short)*MAX_LINKED_FIRM_FIRM);
  575. memcpy(linked_factory_array, firmHarborPtr->linked_factory_array, sizeof(short)*MAX_LINKED_FIRM_FIRM);
  576. memcpy(linked_market_array, firmHarborPtr->linked_market_array, sizeof(short)*MAX_LINKED_FIRM_FIRM);
  577. }
  578. //---------- End of function UnitMarine::get_harbor_linked_firm_info ----------//
  579. //--------- Begin of function UnitMarine::harbor_unload_goods ---------//
  580. void UnitMarine::harbor_unload_goods()
  581. {
  582. if(!linked_mine_num && !linked_factory_num && !linked_market_num)
  583. return; // no linked firm requires or supplys raw and product
  584. for(int i=0; i<MAX_LINKED_FIRM_FIRM; i++)
  585. {
  586. memset(mprocessed_raw_qty_array[i], 0, sizeof(char)*MAX_RAW);
  587. memset(mprocessed_product_raw_qty_array[i], 0, sizeof(char)*MAX_PRODUCT);
  588. }
  589. harbor_unload_product();
  590. harbor_unload_raw();
  591. }
  592. //----------- End of function UnitMarine::harbor_unload_goods -----------//
  593. //--------- Begin of function UnitMarine::harbor_unload_product ---------//
  594. // Product --> market
  595. //
  596. void UnitMarine::harbor_unload_product()
  597. {
  598. if(!linked_market_num)
  599. return;
  600. err_when(linked_market_num>MAX_LINKED_FIRM_FIRM);
  601. int i, j, k;
  602. short totalDemand;
  603. short *marketNodePtr; // point to linked_market_array
  604. char *firmSelectedPtr; // mark which firm is used
  605. FirmMarket *marketPtr;
  606. MarketGoods *marketProductPtr;
  607. MarketGoods *marketGoodsPtr; // used to find empty slot
  608. short curStock, unloadQty, useEmptySlot;
  609. for(i=0; i<MAX_PRODUCT; i++)
  610. {
  611. if(!product_raw_qty_array[i])
  612. continue; // without this goods
  613. //----------------------------------------------------------------------//
  614. // calculate the demand of this goods in market
  615. //----------------------------------------------------------------------//
  616. totalDemand = 0;
  617. memset(empty_slot_position_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
  618. memset(firm_selected_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
  619. marketNodePtr = linked_market_array;
  620. firmSelectedPtr = firm_selected_array;
  621. for(j=0; j<linked_market_num; j++, marketNodePtr++, firmSelectedPtr++)
  622. {
  623. err_when(firm_array.is_deleted(*marketNodePtr));
  624. marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
  625. err_when(marketPtr->firm_id != FIRM_MARKET);
  626. if(marketPtr->nation_recno!=nation_recno)
  627. continue; // don't unload goods to market of other nation
  628. if(marketPtr->ai_status==MARKET_FOR_SELL)
  629. continue; // clearing the market stock, so no unloading
  630. //---------- check the demand of this goods in the market ---------//
  631. marketProductPtr = marketPtr->market_product_array[i];
  632. if(marketProductPtr)
  633. {
  634. err_when(marketProductPtr->product_raw_id && marketProductPtr->raw_id);
  635. totalDemand += (short)(marketPtr->max_stock_qty - marketProductPtr->stock_qty);
  636. ++*firmSelectedPtr;
  637. }
  638. else // don't have this product, clear for empty slot
  639. {
  640. marketGoodsPtr = marketPtr->market_goods_array;
  641. for(k=0; k<MAX_MARKET_GOODS; k++, marketGoodsPtr++)
  642. {
  643. err_when(marketGoodsPtr->product_raw_id && marketGoodsPtr->raw_id);
  644. if(!marketGoodsPtr->stock_qty && !marketGoodsPtr->supply_30days())
  645. {
  646. empty_slot_position_array[j] = k;
  647. totalDemand += (short)marketPtr->max_stock_qty;
  648. ++*firmSelectedPtr;
  649. break;
  650. }
  651. }
  652. }
  653. }
  654. //----------------------------------------------------------------------//
  655. // distribute the stock into each market
  656. //----------------------------------------------------------------------//
  657. curStock = product_raw_qty_array[i];
  658. marketNodePtr = linked_market_array;
  659. firmSelectedPtr = firm_selected_array;
  660. for(j=0; j<linked_market_num; j++, marketNodePtr++, firmSelectedPtr++)
  661. {
  662. if(!(*firmSelectedPtr))
  663. continue;
  664. err_when(firm_array.is_deleted(*marketNodePtr));
  665. marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
  666. err_when(marketPtr->firm_id != FIRM_MARKET);
  667. marketProductPtr = marketPtr->market_product_array[i];
  668. if(!marketProductPtr) // using empty slot, don't set the pointer to the market_goods_array until unloadQty>0
  669. {
  670. useEmptySlot = 1;
  671. marketProductPtr = marketPtr->market_goods_array + empty_slot_position_array[j];
  672. }
  673. else
  674. useEmptySlot = 0;
  675. unloadQty = totalDemand ? (short)((marketPtr->max_stock_qty-marketProductPtr->stock_qty)*curStock/totalDemand + 0.5) : 0;
  676. unloadQty = min((short)(marketPtr->max_stock_qty-marketProductPtr->stock_qty), unloadQty);
  677. unloadQty = min(product_raw_qty_array[i], unloadQty);
  678. if(unloadQty)
  679. {
  680. if(useEmptySlot)
  681. marketPtr->set_goods(0, i+1, empty_slot_position_array[j]);
  682. marketProductPtr->stock_qty += unloadQty;
  683. err_when(marketProductPtr->stock_qty > marketPtr->max_stock_qty);
  684. product_raw_qty_array[i] -= unloadQty;
  685. err_when(product_raw_qty_array[i] < 0);
  686. mprocessed_product_raw_qty_array[linked_mine_num+linked_factory_num+j][i] += 2;
  687. }
  688. }
  689. }
  690. }
  691. //----------- End of function UnitMarine::harbor_unload_product -----------//
  692. //--------- Begin of function UnitMarine::harbor_unload_raw ---------//
  693. // Raw material --> market and factory
  694. //
  695. void UnitMarine::harbor_unload_raw()
  696. {
  697. if(!linked_factory_num && !linked_market_num)
  698. return;
  699. err_when(linked_factory_num+linked_market_num > MAX_LINKED_FIRM_FIRM);
  700. int i, j, k;
  701. short totalDemand;
  702. short *factoryNodePtr; // point to linked_factory_array
  703. short *marketNodePtr; // point to linked_market_array
  704. char *firmSelectedPtr; // mark which firm is used (for factory and market)
  705. FirmFactory *factoryPtr;
  706. FirmMarket *marketPtr;
  707. MarketGoods *marketRawPtr;
  708. MarketGoods *marketGoodsPtr; // used to find empty slot
  709. short curStock, unloadQty, useEmptySlot;
  710. for(i=0; i<MAX_RAW; i++)
  711. {
  712. if(!raw_qty_array[i])
  713. continue; // without this goods
  714. totalDemand = 0;
  715. memset(empty_slot_position_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
  716. memset(firm_selected_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
  717. firmSelectedPtr = firm_selected_array;
  718. //----------------------------------------------------------------------//
  719. // calculate the demand of this goods in factory
  720. //----------------------------------------------------------------------//
  721. factoryNodePtr = linked_factory_array;
  722. for(j=0; j<linked_factory_num; j++, factoryNodePtr++, firmSelectedPtr++)
  723. {
  724. err_when(firm_array.is_deleted(*factoryNodePtr));
  725. factoryPtr = (FirmFactory*) firm_array[*factoryNodePtr];
  726. err_when(factoryPtr->firm_id != FIRM_FACTORY);
  727. if(factoryPtr->nation_recno!=nation_recno)
  728. continue; // don't unload goods to factory of other nation
  729. if(factoryPtr->ai_status==FACTORY_RELOCATE)
  730. continue; // clearing the factory stock, so no unloading
  731. if(factoryPtr->product_raw_id-1 == i)
  732. {
  733. totalDemand = (short) (factoryPtr->max_raw_stock_qty - factoryPtr->raw_stock_qty);
  734. ++*firmSelectedPtr;
  735. }
  736. }
  737. //----------------------------------------------------------------------//
  738. // calculate the demand of this goods in market
  739. //----------------------------------------------------------------------//
  740. marketNodePtr = linked_market_array;
  741. for(j=0; j<linked_market_num; j++, marketNodePtr++, firmSelectedPtr++)
  742. {
  743. err_when(firm_array.is_deleted(*marketNodePtr));
  744. marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
  745. err_when(marketPtr->firm_id != FIRM_MARKET);
  746. if(marketPtr->nation_recno!=nation_recno)
  747. continue; // don't unload goods to market of other nation
  748. if(marketPtr->ai_status==MARKET_FOR_SELL)
  749. continue; // clearing the market stock, so no unloading
  750. //---------- check the demand of this goods in the market ---------//
  751. marketRawPtr = marketPtr->market_raw_array[i];
  752. if(marketRawPtr)
  753. {
  754. err_when(marketRawPtr->product_raw_id && marketRawPtr->raw_id);
  755. totalDemand += (short)(marketPtr->max_stock_qty - marketRawPtr->stock_qty);
  756. ++*firmSelectedPtr;
  757. }
  758. else // don't have this raw, clear for empty slot
  759. {
  760. marketGoodsPtr = marketPtr->market_goods_array;
  761. for(k=0; k<MAX_MARKET_GOODS; k++, marketGoodsPtr++)
  762. {
  763. err_when(marketGoodsPtr->product_raw_id && marketGoodsPtr->raw_id);
  764. if(!marketGoodsPtr->stock_qty && !marketGoodsPtr->supply_30days())
  765. {
  766. empty_slot_position_array[j] = k;
  767. totalDemand += (short)marketPtr->max_stock_qty;
  768. ++*firmSelectedPtr;
  769. break;
  770. }
  771. }
  772. }
  773. }
  774. //----------------------------------------------------------------------//
  775. // distribute the stock into each factory
  776. //----------------------------------------------------------------------//
  777. curStock = raw_qty_array[i];
  778. factoryNodePtr = linked_factory_array;
  779. firmSelectedPtr = firm_selected_array;
  780. for(j=0; j<linked_factory_num; j++, factoryNodePtr++, firmSelectedPtr++)
  781. {
  782. if(!(*firmSelectedPtr))
  783. continue;
  784. err_when(firm_array.is_deleted(*factoryNodePtr));
  785. factoryPtr = (FirmFactory*) firm_array[*factoryNodePtr];
  786. err_when(factoryPtr->firm_id != FIRM_FACTORY);
  787. err_when(factoryPtr->product_raw_id-1!=i);
  788. unloadQty = totalDemand ? (short)((factoryPtr->max_raw_stock_qty-factoryPtr->raw_stock_qty)*curStock/totalDemand + 0.5) : 0;
  789. unloadQty = min((short)(factoryPtr->max_raw_stock_qty-factoryPtr->raw_stock_qty), unloadQty);
  790. unloadQty = min(raw_qty_array[i], unloadQty);
  791. factoryPtr->raw_stock_qty += unloadQty;
  792. err_when(factoryPtr->raw_stock_qty > factoryPtr->max_raw_stock_qty);
  793. raw_qty_array[i] -= unloadQty;
  794. err_when(raw_qty_array[i] < 0);
  795. mprocessed_raw_qty_array[linked_mine_num+j][i] += 2;
  796. }
  797. //----------------------------------------------------------------------//
  798. // distribute the stock into each market
  799. //----------------------------------------------------------------------//
  800. marketNodePtr = linked_market_array;
  801. for(j=0; j<linked_market_num; j++, marketNodePtr, firmSelectedPtr++)
  802. {
  803. if(!(*firmSelectedPtr))
  804. continue;
  805. err_when(firm_array.is_deleted(*marketNodePtr));
  806. marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
  807. err_when(marketPtr->firm_id != FIRM_MARKET);
  808. marketRawPtr = marketPtr->market_raw_array[i];
  809. if(!marketRawPtr) // using empty slot, don't set the pointer to the market_goods_array until unloadQty>0
  810. {
  811. useEmptySlot = 1;
  812. marketRawPtr = marketPtr->market_goods_array + empty_slot_position_array[j];
  813. }
  814. else
  815. useEmptySlot = 0;
  816. unloadQty = totalDemand ? (short)((marketPtr->max_stock_qty-marketRawPtr->stock_qty)*curStock/totalDemand + 0.5) : 0;
  817. unloadQty = min((short)(marketPtr->max_stock_qty-marketRawPtr->stock_qty), unloadQty);
  818. unloadQty = min(raw_qty_array[i], unloadQty);
  819. if(unloadQty)
  820. {
  821. if(useEmptySlot)
  822. marketPtr->set_goods(1, i+1, empty_slot_position_array[j]);
  823. marketRawPtr->stock_qty += unloadQty;
  824. err_when(marketRawPtr->stock_qty > marketPtr->max_stock_qty);
  825. raw_qty_array[i] -= unloadQty;
  826. err_when(raw_qty_array[i] < 0);
  827. mprocessed_raw_qty_array[linked_mine_num+linked_factory_num+j][i] += 2;
  828. }
  829. }
  830. }
  831. }
  832. //----------- End of function UnitMarine::harbor_unload_raw -----------//
  833. //--------- Begin of function UnitMarine::harbor_load_goods ---------//
  834. void UnitMarine::harbor_load_goods()
  835. {
  836. if(!linked_mine_num && !linked_factory_num && !linked_market_num)
  837. return;
  838. err_when(linked_mine_num+linked_factory_num+linked_market_num>MAX_LINKED_FIRM_FIRM);
  839. ShipStop *stopPtr = stop_array+dest_stop_id-1;
  840. if(stopPtr->pick_up_type == NO_PICK_UP)
  841. return; // return if not allowed to load any goods
  842. int pickUpType, goodsId;
  843. for(int i=0; i<MAX_PICK_UP_GOODS; i++)
  844. {
  845. if(!stopPtr->pick_up_array[i])
  846. continue;
  847. pickUpType = i+1;
  848. if(pickUpType>=PICK_UP_RAW_FIRST && pickUpType<=PICK_UP_RAW_LAST)
  849. {
  850. goodsId = pickUpType-PICK_UP_RAW_FIRST;
  851. if(raw_qty_array[goodsId]<carry_goods_capacity)
  852. harbor_load_raw(goodsId, 0, 1); // 1 -- only consider our firm
  853. if(raw_qty_array[goodsId]<carry_goods_capacity)
  854. harbor_load_raw(goodsId, 0, 0); // 0 -- only consider firm of other nation
  855. }
  856. else if(pickUpType>=PICK_UP_PRODUCT_FIRST && pickUpType<=PICK_UP_PRODUCT_LAST)
  857. {
  858. goodsId = pickUpType-PICK_UP_PRODUCT_FIRST;
  859. if(product_raw_qty_array[goodsId]<carry_goods_capacity) // 1 -- only consider our firm
  860. harbor_load_product(goodsId, 0, 1);
  861. if(product_raw_qty_array[goodsId]<carry_goods_capacity) // 0 -- only consider firm of other nation
  862. harbor_load_product(goodsId, 0, 0);
  863. }
  864. else
  865. err_here();
  866. }
  867. }
  868. //----------- End of function UnitMarine::harbor_load_goods -----------//
  869. //--------- Begin of function UnitMarine::harbor_auto_load_goods ---------//
  870. void UnitMarine::harbor_auto_load_goods()
  871. {
  872. if(!linked_mine_num && !linked_factory_num && !linked_market_num)
  873. return;
  874. err_when(linked_mine_num+linked_factory_num+linked_market_num>MAX_LINKED_FIRM_FIRM);
  875. int i;
  876. for(i=0; i<MAX_PRODUCT; i++)
  877. {
  878. if(product_raw_qty_array[i]<carry_goods_capacity)
  879. harbor_load_product(i, 1, 1); // 1 -- only consider our market
  880. }
  881. for(i=0; i<MAX_RAW; i++)
  882. {
  883. if(raw_qty_array[i]<carry_goods_capacity)
  884. harbor_load_raw(i, 1, 1); // 1 -- only consider our market
  885. }
  886. }
  887. //----------- End of function UnitMarine::harbor_auto_load_goods -----------//
  888. //--------- Begin of function UnitMarine::harbor_load_product ---------//
  889. // <int> considerMode - 1 only consider our market
  890. // - 0 only consider markets of other nation
  891. //
  892. void UnitMarine::harbor_load_product(int goodsId, int autoPickUp, int considerMode)
  893. {
  894. if(!linked_factory_num && !linked_market_num)
  895. return;
  896. if(product_raw_qty_array[goodsId]==carry_goods_capacity)
  897. return;
  898. int i;
  899. short totalSupply;
  900. short *factoryNodePtr; // point to linked_factory_array
  901. short *marketNodePtr; // point to linked_market_array
  902. char *firmSelectedPtr; // mark which firm is used (for factory and market)
  903. FirmFactory *factoryPtr;
  904. FirmMarket *marketPtr;
  905. MarketGoods *marketProductPtr;
  906. short loadQty, keepStockQty;
  907. totalSupply = 0;
  908. memset(firm_selected_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
  909. firmSelectedPtr = firm_selected_array;
  910. //----------------------------------------------------------------------//
  911. // calculate the supply of this goods in factory
  912. //----------------------------------------------------------------------//
  913. if(linked_factory_num)
  914. {
  915. factoryPtr = (FirmFactory*) firm_array[linked_factory_array[0]];
  916. keepStockQty = autoPickUp ? (short) (factoryPtr->max_stock_qty/5) : 0;
  917. }
  918. factoryNodePtr = linked_factory_array;
  919. for(i=0; i<linked_factory_num; i++, factoryNodePtr++, firmSelectedPtr++)
  920. {
  921. if(mprocessed_product_raw_qty_array[linked_mine_num+i][goodsId]==2)
  922. continue;
  923. err_when(firm_array.is_deleted(*factoryNodePtr));
  924. factoryPtr = (FirmFactory*) firm_array[*factoryNodePtr];
  925. err_when(factoryPtr->firm_id != FIRM_FACTORY);
  926. if(considerMode)
  927. {
  928. if(factoryPtr->nation_recno!=nation_recno)
  929. continue; // not our market
  930. }
  931. else
  932. {
  933. if(factoryPtr->nation_recno==nation_recno)
  934. continue; // not consider our market for this mode
  935. }
  936. //---------- check the supply of this goods in the factory ---------//
  937. if(factoryPtr->product_raw_id!=goodsId+1)
  938. continue; // incorrect product
  939. totalSupply += max((short)(factoryPtr->stock_qty-keepStockQty), 0);
  940. ++*firmSelectedPtr;
  941. }
  942. //----------------------------------------------------------------------//
  943. // calculate the supply of this goods in market
  944. //----------------------------------------------------------------------//
  945. if(linked_market_num)
  946. {
  947. marketPtr = (FirmMarket*) firm_array[linked_market_array[0]];
  948. keepStockQty = autoPickUp ? (short) (marketPtr->max_stock_qty/5) : 0;
  949. }
  950. marketNodePtr = linked_market_array;
  951. for(i=0; i<linked_market_num; i++, marketNodePtr++, firmSelectedPtr++)
  952. {
  953. if(mprocessed_product_raw_qty_array[linked_mine_num+linked_factory_num+i][goodsId]==2)
  954. continue;
  955. err_when(firm_array.is_deleted(*marketNodePtr));
  956. marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
  957. err_when(marketPtr->firm_id != FIRM_MARKET);
  958. if(considerMode)
  959. {
  960. if(marketPtr->nation_recno!=nation_recno)
  961. continue; // not our market
  962. }
  963. else
  964. {
  965. if(marketPtr->nation_recno==nation_recno)
  966. continue; // not consider our market for this mode
  967. }
  968. //---------- check the supply of this goods in the market ---------//
  969. marketProductPtr = marketPtr->market_product_array[goodsId];
  970. if(marketProductPtr)
  971. {
  972. totalSupply += max((short)(marketProductPtr->stock_qty-keepStockQty), 0);
  973. ++*firmSelectedPtr;
  974. }
  975. }
  976. Nation *nationPtr = nation_array[nation_recno];
  977. int curDemand = carry_goods_capacity-product_raw_qty_array[goodsId];
  978. firmSelectedPtr = firm_selected_array;
  979. //----------------------------------------------------------------------//
  980. // get the stock from each factory
  981. //----------------------------------------------------------------------//
  982. if(linked_factory_num)
  983. {
  984. factoryPtr = (FirmFactory*) firm_array[linked_factory_array[0]];
  985. keepStockQty = autoPickUp ? (short) (factoryPtr->max_stock_qty/5) : 0;
  986. }
  987. factoryNodePtr = linked_factory_array;
  988. for(i=0; i<linked_factory_num; i++, factoryNodePtr++, firmSelectedPtr++)
  989. {
  990. if(!(*firmSelectedPtr))
  991. continue;
  992. err_when(firm_array.is_deleted(*factoryNodePtr));
  993. factoryPtr = (FirmFactory*) firm_array[*factoryNodePtr];
  994. err_when(factoryPtr->firm_id != FIRM_FACTORY);
  995. err_when(factoryPtr->product_raw_id-1!=goodsId);
  996. loadQty = max((short) (factoryPtr->stock_qty-keepStockQty), 0);
  997. loadQty = totalSupply ? min((short) ((float)loadQty*curDemand/totalSupply), loadQty) : 0;
  998. if(factoryPtr->nation_recno!=nation_recno)
  999. {
  1000. loadQty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/PRODUCT_PRICE, loadQty) : 0;
  1001. if(loadQty)
  1002. nationPtr->import_goods(IMPORT_PRODUCT, factoryPtr->nation_recno, (float)loadQty*PRODUCT_PRICE);
  1003. }
  1004. factoryPtr->stock_qty -= loadQty;
  1005. err_when(factoryPtr->stock_qty < 0);
  1006. product_raw_qty_array[goodsId] += loadQty;
  1007. err_when(product_raw_qty_array[goodsId] > carry_goods_capacity);
  1008. }
  1009. //----------------------------------------------------------------------//
  1010. // get the stock from each market
  1011. //----------------------------------------------------------------------//
  1012. if(linked_market_num)
  1013. {
  1014. marketPtr = (FirmMarket*) firm_array[linked_market_array[0]];
  1015. keepStockQty = autoPickUp ? (short) (marketPtr->max_stock_qty/5) : 0;
  1016. }
  1017. marketNodePtr = linked_market_array;
  1018. for(i=0; i<linked_market_num; i++, marketNodePtr++, firmSelectedPtr++)
  1019. {
  1020. if(!(*firmSelectedPtr))
  1021. continue;
  1022. err_when(firm_array.is_deleted(*marketNodePtr));
  1023. marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
  1024. err_when(marketPtr->firm_id != FIRM_MARKET);
  1025. marketProductPtr = marketPtr->market_product_array[goodsId];
  1026. loadQty = max((short) marketProductPtr->stock_qty-keepStockQty, 0);
  1027. loadQty = totalSupply ? min((short) ((float)loadQty*curDemand/totalSupply), loadQty) : 0;
  1028. if(marketPtr->nation_recno!=nation_recno)
  1029. {
  1030. loadQty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/PRODUCT_PRICE, loadQty) : 0;
  1031. if(loadQty)
  1032. nationPtr->import_goods(IMPORT_PRODUCT, marketPtr->nation_recno, (float)loadQty * PRODUCT_PRICE);
  1033. }
  1034. marketProductPtr->stock_qty -= loadQty;
  1035. err_when(marketProductPtr->stock_qty < 0);
  1036. product_raw_qty_array[goodsId] += loadQty;
  1037. err_when(product_raw_qty_array[goodsId] > carry_goods_capacity);
  1038. }
  1039. }
  1040. //----------- End of function UnitMarine::harbor_load_product -----------//
  1041. //--------- Begin of function UnitMarine::harbor_load_raw ---------//
  1042. // <int> considerMode - 1 only consider our market
  1043. // - 0 only consider markets of other nation
  1044. //
  1045. void UnitMarine::harbor_load_raw(int goodsId, int autoPickUp, int considerMode)
  1046. {
  1047. if(!linked_mine_num && !linked_market_num)
  1048. return;
  1049. if(raw_qty_array[goodsId]==carry_goods_capacity)
  1050. return;
  1051. int i;
  1052. short totalSupply;
  1053. short *mineNodePtr; // point to linked_factory_array
  1054. short *marketNodePtr; // point to linked_market_array
  1055. char *firmSelectedPtr; // mark which firm is used (for factory and market)
  1056. FirmMine *minePtr;
  1057. FirmMarket *marketPtr;
  1058. MarketGoods *marketRawPtr;
  1059. short loadQty, keepStockQty;
  1060. totalSupply = 0;
  1061. memset(firm_selected_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
  1062. firmSelectedPtr = firm_selected_array;
  1063. //----------------------------------------------------------------------//
  1064. // calculate the supply of this goods in mine
  1065. //----------------------------------------------------------------------//
  1066. if(linked_mine_num)
  1067. {
  1068. minePtr = (FirmMine*) firm_array[linked_mine_array[0]];
  1069. keepStockQty = autoPickUp ? (short) (minePtr->max_stock_qty/5) : 0;
  1070. }
  1071. mineNodePtr = linked_mine_array;
  1072. for(i=0; i<linked_mine_num; i++, mineNodePtr++, firmSelectedPtr++)
  1073. {
  1074. if(mprocessed_raw_qty_array[i][goodsId]==2)
  1075. continue;
  1076. err_when(firm_array.is_deleted(*mineNodePtr));
  1077. minePtr = (FirmMine*) firm_array[*mineNodePtr];
  1078. err_when(minePtr->firm_id != FIRM_MINE);
  1079. if(considerMode)
  1080. {
  1081. if(minePtr->nation_recno!=nation_recno)
  1082. continue; // not our market
  1083. }
  1084. else
  1085. {
  1086. if(minePtr->nation_recno==nation_recno)
  1087. continue; // not consider our market for this mode
  1088. }
  1089. //---------- check the supply of this goods in the mine ---------//
  1090. if(minePtr->raw_id!=goodsId+1)
  1091. continue; // incorrect goods
  1092. totalSupply += max((short)(minePtr->stock_qty-keepStockQty), 0);
  1093. ++*firmSelectedPtr;
  1094. }
  1095. //----------------------------------------------------------------------//
  1096. // calculate the supply of this goods in market
  1097. //----------------------------------------------------------------------//
  1098. if(linked_market_num)
  1099. {
  1100. marketPtr = (FirmMarket*) firm_array[linked_market_array[0]];
  1101. keepStockQty = autoPickUp ? (short) (marketPtr->max_stock_qty/5) : 0;
  1102. }
  1103. marketNodePtr = linked_market_array;
  1104. for(i=0; i<linked_market_num; i++, marketNodePtr++, firmSelectedPtr++)
  1105. {
  1106. if(mprocessed_raw_qty_array[linked_mine_num+linked_factory_num+i][goodsId]==2)
  1107. continue;
  1108. err_when(firm_array.is_deleted(*marketNodePtr));
  1109. marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
  1110. err_when(marketPtr->firm_id != FIRM_MARKET);
  1111. if(considerMode)
  1112. {
  1113. if(marketPtr->nation_recno!=nation_recno)
  1114. continue; // not our market
  1115. }
  1116. else
  1117. {
  1118. if(marketPtr->nation_recno==nation_recno)
  1119. continue; // not consider our market for this mode
  1120. }
  1121. //---------- check the supply of this goods in the market ---------//
  1122. marketRawPtr = marketPtr->market_raw_array[goodsId];
  1123. if(marketRawPtr)
  1124. {
  1125. totalSupply += max((short)(marketRawPtr->stock_qty-keepStockQty), 0);
  1126. ++*firmSelectedPtr;
  1127. }
  1128. }
  1129. Nation *nationPtr = nation_array[nation_recno];
  1130. int curDemand = carry_goods_capacity-raw_qty_array[goodsId];
  1131. firmSelectedPtr = firm_selected_array;
  1132. //----------------------------------------------------------------------//
  1133. // get the stock from each mine
  1134. //----------------------------------------------------------------------//
  1135. if(linked_mine_num)
  1136. {
  1137. minePtr = (FirmMine*) firm_array[linked_mine_array[0]];
  1138. keepStockQty = autoPickUp ? (short) (minePtr->max_stock_qty/5) : 0;
  1139. }
  1140. mineNodePtr = linked_mine_array;
  1141. for(i=0; i<linked_mine_num; i++, mineNodePtr++, firmSelectedPtr++)
  1142. {
  1143. if(!(*firmSelectedPtr))
  1144. continue;
  1145. err_when(firm_array.is_deleted(*mineNodePtr));
  1146. minePtr = (FirmMine*) firm_array[*mineNodePtr];
  1147. err_when(minePtr->firm_id != FIRM_MINE);
  1148. err_when(minePtr->raw_id-1!=goodsId);
  1149. loadQty = max((short) (minePtr->stock_qty-keepStockQty), 0);
  1150. loadQty = totalSupply ? min((short) ((float)loadQty*curDemand/totalSupply), loadQty) : 0;
  1151. if(minePtr->nation_recno!=nation_recno)
  1152. {
  1153. loadQty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/RAW_PRICE, loadQty) : 0;
  1154. if(loadQty)
  1155. nationPtr->import_goods(IMPORT_RAW, minePtr->nation_recno, (float)loadQty*RAW_PRICE);
  1156. }
  1157. minePtr->stock_qty -= loadQty;
  1158. err_when(minePtr->stock_qty < 0);
  1159. raw_qty_array[goodsId] += loadQty;
  1160. err_when(raw_qty_array[goodsId] > carry_goods_capacity);
  1161. }
  1162. //----------------------------------------------------------------------//
  1163. // get the stock from each market
  1164. //----------------------------------------------------------------------//
  1165. if(linked_market_num)
  1166. {
  1167. marketPtr = (FirmMarket*) firm_array[linked_market_array[0]];
  1168. keepStockQty = autoPickUp ? (short) (marketPtr->max_stock_qty/5) : 0;
  1169. }
  1170. marketNodePtr = linked_market_array;
  1171. for(i=0; i<linked_market_num; i++, marketNodePtr++, firmSelectedPtr++)
  1172. {
  1173. if(!(*firmSelectedPtr))
  1174. continue;
  1175. err_when(firm_array.is_deleted(*marketNodePtr));
  1176. marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
  1177. err_when(marketPtr->firm_id != FIRM_MARKET);
  1178. marketRawPtr = marketPtr->market_raw_array[goodsId];
  1179. loadQty = max((short) marketRawPtr->stock_qty-keepStockQty, 0);
  1180. loadQty = totalSupply ? min((short) ((float)loadQty*curDemand/totalSupply), loadQty) : 0;
  1181. if(marketPtr->nation_recno!=nation_recno)
  1182. {
  1183. loadQty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/RAW_PRICE, loadQty) : 0;
  1184. if(loadQty)
  1185. nationPtr->import_goods(IMPORT_RAW, marketPtr->nation_recno, (float)loadQty * RAW_PRICE);
  1186. }
  1187. marketRawPtr->stock_qty -= loadQty;
  1188. err_when(marketRawPtr->stock_qty < 0);
  1189. raw_qty_array[goodsId] += loadQty;
  1190. err_when(raw_qty_array[goodsId] > carry_goods_capacity);
  1191. }
  1192. }
  1193. //----------- End of function UnitMarine::harbor_load_raw -----------//