OU_CARA.cpp 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585
  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_CARA.CPP
  21. //Description : Unit Caravan
  22. #include <OVGA.h>
  23. #include <OSTR.h>
  24. #include <OHELP.h>
  25. #include <OFONT.h>
  26. #include <OINFO.h>
  27. #include <OCONFIG.h>
  28. #include <OIMGRES.h>
  29. #include <OMOUSE.h>
  30. #include <OPOWER.h>
  31. #include <OBUTTON.h>
  32. #include <OBUTT3D.h>
  33. #include <ONATION.h>
  34. #include <OU_CARA.h>
  35. #include <OREMOTE.h>
  36. #include <OF_MINE.h>
  37. #include <OF_FACT.h>
  38. #include <OBUTTCUS.h>
  39. #include <OSE.h>
  40. //------------- Define static vars ------------//
  41. static Button button_set_stop[MAX_STOP_FOR_CARAVAN];
  42. static Button button_go_stop[MAX_STOP_FOR_CARAVAN];
  43. static Button button_cancel_stop[MAX_STOP_FOR_CARAVAN];
  44. static ButtonCustom button_select_array[MAX_STOP_FOR_CARAVAN][MAX_GOODS_SELECT_BUTTON];
  45. static char button_select_enable_flag[MAX_STOP_FOR_CARAVAN][MAX_GOODS_SELECT_BUTTON];
  46. static void i_disp_caravan_select_button(ButtonCustom *button, int repaintBody);
  47. static char goods_num[MAX_STOP_FOR_CARAVAN];
  48. static char dummyCaravanEnableFlag[MAX_STOP_FOR_CARAVAN][MAX_GOODS_SELECT_BUTTON];
  49. static char dummyCaravanGoodsNum[MAX_STOP_FOR_CARAVAN];
  50. //------------- define static function ------------//
  51. static void update_caravan_stop_and_goods_to_dummy(UnitCaravan *caravanPtr)
  52. {
  53. CaravanStop *stopPtr = caravanPtr->stop_array;
  54. for(int i=0; i<MAX_STOP_FOR_CARAVAN; i++, stopPtr++)
  55. {
  56. if(!stopPtr->firm_recno)
  57. continue;
  58. err_when(firm_array.is_deleted(stopPtr->firm_recno));
  59. dummyCaravanGoodsNum[i] = stopPtr->update_pick_up(dummyCaravanEnableFlag[i]);
  60. }
  61. }
  62. //--------- Begin of function UnitCaravan::UnitCaravan ---------//
  63. //
  64. UnitCaravan::UnitCaravan()
  65. {
  66. memset( stop_array, 0, MAX_STOP_FOR_CARAVAN * sizeof(CaravanStop) );
  67. journey_status = ON_WAY_TO_FIRM;
  68. dest_stop_id = 1;
  69. stop_defined_num = 0;
  70. wait_count = 0;
  71. stop_x_loc = 0;
  72. stop_y_loc = 0;
  73. memset(raw_qty_array, 0, sizeof(short)*MAX_RAW);
  74. memset(product_raw_qty_array, 0, sizeof(short)*MAX_PRODUCT);
  75. }
  76. //---------- End of function UnitCaravan::UnitCaravan ----------//
  77. //--------- Begin of function UnitCaravan::disp_info ---------//
  78. //
  79. void UnitCaravan::disp_info(int refreshFlag)
  80. {
  81. //----- for multiplayer game, skip displaying information for the first frame --------//
  82. if(remote.is_enable())
  83. {
  84. if(unit_array.mp_first_frame_to_select_caravan && // first frame
  85. unit_array.mp_pre_selected_caravan_recno==sprite_recno) // is selected
  86. return;
  87. }
  88. disp_basic_info(INFO_Y1, refreshFlag);
  89. if( !config.show_ai_info && !is_own() )
  90. return;
  91. disp_stop(INFO_Y1+54, refreshFlag);
  92. disp_goods(INFO_Y1+235, refreshFlag);
  93. }
  94. //---------- End of function UnitCaravan::disp_info ----------//
  95. //--------- Begin of function UnitCaravan::detect_info ---------//
  96. //
  97. void UnitCaravan::detect_info()
  98. {
  99. if(!is_visible())
  100. return;
  101. if( detect_basic_info() )
  102. return;
  103. if( !is_own() && !config.show_ai_info )
  104. return;
  105. detect_stop();
  106. }
  107. //---------- End of function UnitCaravan::detect_info ----------//
  108. //--------- Begin of function UnitCaravan::disp_stop ---------//
  109. //
  110. void UnitCaravan::disp_stop(int dispY1, int refreshFlag)
  111. {
  112. //###### begin trevor 15/9 #######//
  113. if(refreshFlag!=INFO_REPAINT && refreshFlag!=INFO_UPDATE)
  114. return;
  115. int i, x=INFO_X1, y=dispY1, needRefresh;
  116. Firm *firmPtr;
  117. static short last_firm_recno_array[MAX_STOP_FOR_CARAVAN];
  118. for(i=0 ; i<MAX_STOP_FOR_CARAVAN ; i++, y+=60)
  119. {
  120. //---- compare with the previous display and see if an update is needed ----//
  121. if( refreshFlag==INFO_REPAINT )
  122. {
  123. needRefresh = 1;
  124. }
  125. else if( last_firm_recno_array[i] != stop_array[i].firm_recno )
  126. {
  127. needRefresh = 1;
  128. }
  129. last_firm_recno_array[i] = stop_array[i].firm_recno;
  130. //----------------------------------------//
  131. if( !stop_array[i].firm_recno ||
  132. firm_array.is_deleted(stop_array[i].firm_recno) )
  133. {
  134. if( refreshFlag == INFO_REPAINT )
  135. {
  136. vga.d3_panel_up(x, y, INFO_X2, y+58);
  137. #if(defined(FRENCH))
  138. button_set_stop[i].paint_text( x+4, y+37, x+86, y+56, "Set Stop" );
  139. #else
  140. button_set_stop[i].paint_text( x+4, y+37, x+80, y+56, "Set Stop" );
  141. #endif
  142. button_set_stop[i].set_help_code( "CSETSTOP" );
  143. }
  144. }
  145. else
  146. {
  147. if( refreshFlag == INFO_REPAINT )
  148. {
  149. vga.d3_panel_up(x, y, INFO_X2, y+58);
  150. //-------- display name of the stop --------//
  151. firmPtr = firm_array[ stop_array[i].firm_recno ];
  152. nation_array[firmPtr->nation_recno]->disp_nation_color(x+4, y+4);
  153. font_san.put(x+20, y+4, firmPtr->firm_name());
  154. font_san.put(x+4, y+19, "Pick up: ");
  155. #if(defined(FRENCH))
  156. button_set_stop[i].paint_text( x+4, y+37, x+86, y+56, "Set Stop" );
  157. #else
  158. button_set_stop[i].paint_text( x+4, y+37, x+80, y+56, "Set Stop" );
  159. #endif
  160. button_set_stop[i].set_help_code( "CSETSTOP" );
  161. #if(defined(FRENCH))
  162. button_go_stop[i].paint_text( x+90, y+37, x+180, y+56, "View Stop" );
  163. #else
  164. button_go_stop[i].paint_text( x+84, y+37, x+180, y+56, "View Stop" );
  165. #endif
  166. button_go_stop[i].set_help_code( "CGOSTOP" );
  167. button_cancel_stop[i].paint_text( x+184, y+37, INFO_X2-4, y+56, "X" );
  168. button_cancel_stop[i].set_help_code( "CDELSTOP" );
  169. }
  170. disp_goods_select_button(i, y+1, refreshFlag);
  171. }
  172. }
  173. //###### end trevor 15/9 #######//
  174. }
  175. //---------- End of function UnitCaravan::disp_stop ----------//
  176. //--------- Begin of function UnitCaravan::detect_stop ---------//
  177. //
  178. void UnitCaravan::detect_stop()
  179. {
  180. int i, x=INFO_X1;
  181. for( i=0 ; i<MAX_STOP_FOR_CARAVAN ; i++ )
  182. {
  183. // ###### begin Gilbert 14/8 #########//
  184. if( button_set_stop[i].detect() && is_own() )
  185. power.issue_command( COMMAND_SET_CARAVAN_STOP, sprite_recno, i+1 ); // i+1 - stop id., passed as a parameter of the command
  186. // ###### end Gilbert 14/8 #########//
  187. if(i>=stop_defined_num)
  188. continue;
  189. if(button_cancel_stop[i].detect())
  190. {
  191. if(is_visible())
  192. {
  193. del_stop(i+1, COMMAND_PLAYER);
  194. // ###### begin Gilbert 26/9 ######//
  195. se_ctrl.immediate_sound("TURN_OFF");
  196. // ###### end Gilbert 26/9 ######//
  197. }
  198. }
  199. for(int b=0; b<MAX_GOODS_SELECT_BUTTON; ++b)
  200. {
  201. if(!button_select_enable_flag[i][b])
  202. continue;
  203. if(button_select_array[i][b].detect())
  204. {
  205. // ###### begin Gilbert 26/9 ######//
  206. se_ctrl.immediate_sound(
  207. button_select_array[i][b].elastic_flag || button_select_array[i][b].pushed_flag ?
  208. (char*)"TURN_ON" : (char*)"TURN_OFF");
  209. // ###### end Gilbert 26/9 ######//
  210. set_stop_pick_up(i+1, b, COMMAND_PLAYER); // b = 1 - MAX_PICK_UP_GOODS
  211. }
  212. }
  213. if( button_go_stop[i].detect() )
  214. {
  215. Firm* firmPtr = firm_array[ stop_array[i].firm_recno ];
  216. world.go_loc( firmPtr->center_x, firmPtr->center_y );
  217. }
  218. }
  219. }
  220. //---------- End of function UnitCaravan::detect_stop ----------//
  221. //--------- Begin of function UnitCaravan::disp_goods_select_button ---------//
  222. void UnitCaravan::disp_goods_select_button(int stopNum, int dispY1, int refreshFlag)
  223. {
  224. if(refreshFlag!=INFO_REPAINT && refreshFlag!=INFO_UPDATE)
  225. return;
  226. #define SHIFT_X_OFFSET 60
  227. #define SELECT_BUTTON_WIDTH 16
  228. #define SELECT_BUTTON_HEIGHT 16
  229. CaravanStop *stopPtr = &stop_array[stopNum];
  230. if( !goods_num[stopNum] )
  231. return;
  232. int x=INFO_X1+SHIFT_X_OFFSET, y=dispY1+17, x1;
  233. char *pickUpArray = stopPtr->pick_up_array;
  234. char isPush;
  235. //-------------- draw the buttons for the cargo -------------//
  236. //###### begin trevor 13/9 #######//
  237. for(int i=1 ;i<=MAX_PICK_UP_GOODS; ++i, pickUpArray++)
  238. {
  239. x1 = x + i*SELECT_BUTTON_WIDTH;
  240. if(button_select_enable_flag[stopNum][i])
  241. {
  242. isPush = stopPtr->pick_up_array[i-1];
  243. err_when(isPush && (stopPtr->pick_up_type==AUTO_PICK_UP || stopPtr->pick_up_type==NO_PICK_UP));
  244. button_select_array[stopNum][i].paint(x1, y, x1+SELECT_BUTTON_WIDTH,
  245. y+SELECT_BUTTON_HEIGHT, i_disp_caravan_select_button, ButtonCustomPara(this, i),
  246. 0, isPush); // 0 for inelastic
  247. }
  248. else
  249. {
  250. vga.blt_buf( x1, y, x1+SELECT_BUTTON_WIDTH, y+SELECT_BUTTON_HEIGHT, 0 );
  251. }
  252. }
  253. //---------------- draw the buttons for auto_pick_up and no_pick_up -------------//
  254. if(goods_num[stopNum]>1)
  255. {
  256. x1 = x;
  257. isPush = (stopPtr->pick_up_type==AUTO_PICK_UP);
  258. button_select_enable_flag[stopNum][AUTO_PICK_UP] = 1;
  259. button_select_array[stopNum][AUTO_PICK_UP].paint(x1, y, x1+SELECT_BUTTON_WIDTH,
  260. y+SELECT_BUTTON_HEIGHT, i_disp_caravan_select_button, ButtonCustomPara(this, AUTO_PICK_UP),
  261. 0, isPush); // 0 for inelastic
  262. x1 = x+SELECT_BUTTON_WIDTH*NO_PICK_UP;
  263. button_select_enable_flag[stopNum][NO_PICK_UP] = 1;
  264. button_select_array[stopNum][NO_PICK_UP].paint(x1, y, x1+SELECT_BUTTON_WIDTH,
  265. y+SELECT_BUTTON_HEIGHT, i_disp_caravan_select_button, ButtonCustomPara(this, NO_PICK_UP));
  266. }
  267. else
  268. {
  269. x1 = x;
  270. vga.blt_buf( x1, y, x1+SELECT_BUTTON_WIDTH, y+SELECT_BUTTON_HEIGHT, 0 );
  271. x1 = x+SELECT_BUTTON_WIDTH*NO_PICK_UP;
  272. vga.blt_buf( x1, y, x1+SELECT_BUTTON_WIDTH, y+SELECT_BUTTON_HEIGHT, 0 );
  273. }
  274. //###### end trevor 13/9 #######//
  275. }
  276. //---------- End of function UnitCaravan::disp_goods_select_button ----------//
  277. //--------- Begin of function UnitCaravan::set_stop_pick_up ---------//
  278. //
  279. // Set the pickup type of a specific stop of this caravan.
  280. //
  281. // <int> stopId - id. of the stop. (1 - MAX_STOP_FOR_CARAVAN)
  282. // <int> newPickUpType - set the pickup type of the specific stop. (0 - MAX_GOODS_SELECT_BUTTON-1)
  283. // <int> remoteActoin - remote action type
  284. //
  285. void UnitCaravan::set_stop_pick_up(int stopId, int newPickUpType, int remoteAction)
  286. {
  287. int remoteEnable = 0;
  288. if(remote.is_enable())
  289. {
  290. if(!remoteAction)
  291. {
  292. // packet structure : <unit recno> <stop id> <new pick_up_type>
  293. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_U_CARA_CHANGE_GOODS, 3*sizeof(short));
  294. *shortPtr = sprite_recno;
  295. shortPtr[1] = stopId;
  296. shortPtr[2] = newPickUpType;
  297. return;
  298. }
  299. else //-------- validate remote message ----------//
  300. {
  301. //-*******************************************************-//
  302. /*char mess[255];
  303. sprintf(mess, "Change Seed !!!! \r\n");
  304. OutputDebugString(mess);*/
  305. /*Firm *firmPtr = firm_array[stop_array[stopId-1].firm_recno];
  306. switch(firmPtr->firm_id)
  307. {
  308. case FIRM_MINE:
  309. //firmPtr->sell_firm(COMMAND_AUTO);
  310. //firm_array[stop_array[0].firm_recno]->sell_firm(COMMAND_AUTO);
  311. break;
  312. case FIRM_FACTORY:
  313. break;
  314. case FIRM_MARKET:
  315. break;
  316. }
  317. update_stop_list();
  318. if(unit_array.selected_recno == sprite_recno)
  319. {
  320. if(!remote.is_enable() || nation_renco==nation_array.player_recno || config.show_ai_info)
  321. disp_stop(INFO_Y1+54, INFO_UPDATE);
  322. }*/
  323. //-*******************************************************-//
  324. err_when(!is_visible()); // no action if the unit is invisible
  325. if(firm_array.is_deleted(stop_array[stopId-1].firm_recno))
  326. return; // firm is deleted
  327. if(stop_defined_num<stopId)
  328. return; // stop_list is updated, stop exists no more
  329. #ifdef DEBUG
  330. //-*******************************************************-//
  331. /*//char mess[255];
  332. sprintf(mess, "Change Seed : %d %d %d\r\n", stopId, newPickUpType, sprite_recno);
  333. OutputDebugString(mess);*/
  334. //-*******************************************************-//
  335. m.set_random_seed(stopId + newPickUpType*(m.random(4)+1)*10 + sprite_recno*100*m.random(100) +
  336. m.get_random_seed());
  337. //-*******************************************************-//
  338. /*//char mess[255];
  339. sprintf(mess, "Change Seed : %d\r\n", m.random_seed);
  340. OutputDebugString(mess);*/
  341. //-*******************************************************-//
  342. #endif
  343. }
  344. remoteEnable = 1;
  345. }
  346. switch(newPickUpType)
  347. {
  348. case AUTO_PICK_UP:
  349. if(remoteEnable)
  350. {
  351. update_caravan_stop_and_goods_to_dummy(this);
  352. stop_array[stopId-1].mp_pick_up_set_auto(dummyCaravanEnableFlag[stopId-1]);
  353. }
  354. else
  355. stop_array[stopId-1].pick_up_set_auto();
  356. break;
  357. case NO_PICK_UP:
  358. // if(remoteEnable)
  359. if(remoteEnable)
  360. {
  361. update_caravan_stop_and_goods_to_dummy(this);
  362. stop_array[stopId-1].mp_pick_up_set_none(dummyCaravanEnableFlag[stopId-1]);
  363. }
  364. else
  365. stop_array[stopId-1].pick_up_set_none();
  366. break;
  367. default:
  368. err_when(newPickUpType<PICK_UP_RAW_FIRST || newPickUpType>PICK_UP_PRODUCT_LAST);
  369. if(remoteEnable)
  370. stop_array[stopId-1].mp_pick_up_toggle(newPickUpType);
  371. else
  372. stop_array[stopId-1].pick_up_toggle(newPickUpType);
  373. break;
  374. }
  375. if(unit_array.selected_recno==sprite_recno)
  376. {
  377. if(!remote.is_enable() || nation_recno==nation_array.player_recno || config.show_ai_info)
  378. disp_stop(INFO_Y1+54, INFO_UPDATE);
  379. }
  380. }
  381. //---------- End of function UnitCaravan::set_stop_pick_up ----------//
  382. //--------- Begin of function UnitCaravan::disp_goods ---------//
  383. //
  384. void UnitCaravan::disp_goods(int dispY1, int refreshFlag)
  385. {
  386. if( refreshFlag == INFO_REPAINT )
  387. vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+42 );
  388. int x=INFO_X1+20, y=dispY1+5;
  389. String str;
  390. int i;
  391. for(i=0; i<MAX_RAW; i++, x+=60)
  392. {
  393. vga_front.d3_panel_up( x, y, x+RAW_SMALL_ICON_WIDTH+5, y+RAW_SMALL_ICON_HEIGHT+5 );
  394. raw_res.put_small_raw_icon( x+3, y+3, i+1 );
  395. font_san.disp( x+25, y+2, raw_qty_array[i], 1, x+59 );
  396. }
  397. x =INFO_X1+20;
  398. y+=19;
  399. for( i=0; i<MAX_PRODUCT; i++, x+=60)
  400. {
  401. vga_front.d3_panel_up( x, y, x+RAW_SMALL_ICON_WIDTH+5, y+RAW_SMALL_ICON_HEIGHT+5 );
  402. raw_res.put_small_product_icon( x+3, y+3, i+1 );
  403. font_san.disp( x+25, y+2, product_raw_qty_array[i], 1, x+59 );
  404. }
  405. }
  406. //---------- End of function UnitCaravan::disp_goods ----------//
  407. //--------- Begin of function UnitCaravan::set_stop ---------//
  408. //
  409. // <int> stopId - the id. of the stop
  410. // <int> stopXLoc, stopYLoc - the location of the stop
  411. //
  412. void UnitCaravan::set_stop(int stopId, int stopXLoc, int stopYLoc, char remoteAction)
  413. {
  414. //-------------------------------------------------------//
  415. // check if there is a station in the given location
  416. //-------------------------------------------------------//
  417. Location *locPtr = world.get_loc(stopXLoc, stopYLoc);
  418. if(!locPtr->is_firm())
  419. return;
  420. Firm *firmPtr = firm_array[locPtr->firm_recno()];
  421. if( !can_set_stop(firmPtr->firm_recno) )
  422. return;
  423. //-------------------------------------------------------//
  424. // return if the market stop is in another territory
  425. //-------------------------------------------------------//
  426. if(world.get_loc(next_x_loc(), next_y_loc())->region_id!=locPtr->region_id)
  427. return;
  428. //-------------------------------------------//
  429. if(!remoteAction && remote.is_enable())
  430. {
  431. // packet structure : <unit recno> <stop id> <stop x> <stop y>
  432. short *shortPtr = (short *) remote.new_send_queue_msg(MSG_U_CARA_SET_STOP, 4*sizeof(short));
  433. *shortPtr = sprite_recno;
  434. shortPtr[1] = stopId;
  435. shortPtr[2] = stopXLoc;
  436. shortPtr[3] = stopYLoc;
  437. return;
  438. }
  439. if(!stop_array[stopId-1].firm_recno)
  440. {
  441. stop_defined_num++; // no plus one if the recno is defined originally
  442. err_when( stop_defined_num > MAX_STOP_FOR_CARAVAN );
  443. }
  444. //-------------------------------------------------------//
  445. // set the station recno of the stop
  446. //-------------------------------------------------------//
  447. CaravanStop *stopPtr = stop_array+stopId-1;
  448. if(stopPtr->firm_recno == firmPtr->firm_recno)
  449. {
  450. err_when(stopPtr->firm_loc_x1!=firmPtr->loc_x1 || stopPtr->firm_loc_y1!=firmPtr->loc_y1 ||
  451. stopPtr->firm_id!=firmPtr->firm_id);
  452. return; // same stop as before
  453. }
  454. //-------------- reset ignore_power_nation -------------//
  455. ignore_power_nation = 0;
  456. memset(button_select_enable_flag[stopId-1], 0, sizeof(char)*MAX_GOODS_SELECT_BUTTON);
  457. goods_num[stopId-1] = 0;
  458. short oldStopFirmRecno = dest_stop_id ? stop_array[dest_stop_id-1].firm_recno : 0;
  459. short newStopFirmRecno;
  460. memset(stopPtr->pick_up_array, 0, sizeof(char)*MAX_PICK_UP_GOODS);
  461. stopPtr->firm_recno = firmPtr->firm_recno;
  462. stopPtr->firm_id = firmPtr->firm_id;
  463. stopPtr->firm_loc_x1 = firmPtr->loc_x1;
  464. stopPtr->firm_loc_y1 = firmPtr->loc_y1;
  465. //------------------------------------------------------------------------------------//
  466. // codes for setting pick_up_type
  467. //------------------------------------------------------------------------------------//
  468. MarketGoods *goodsPtr;
  469. int i, goodsId, goodsNum;
  470. switch(firmPtr->firm_id)
  471. {
  472. case FIRM_MINE:
  473. goodsId = ((FirmMine*)firmPtr)->raw_id;
  474. if(goodsId)
  475. stopPtr->pick_up_toggle(goodsId); // enable
  476. else
  477. stopPtr->pick_up_set_none();
  478. break;
  479. case FIRM_FACTORY:
  480. goodsId = ((FirmFactory*)firmPtr)->product_raw_id+MAX_RAW;
  481. if(goodsId)
  482. stopPtr->pick_up_toggle(goodsId); // enable
  483. else
  484. stopPtr->pick_up_set_none();
  485. break;
  486. case FIRM_MARKET:
  487. goodsPtr = ((FirmMarket*) firmPtr)->market_goods_array;
  488. goodsNum = 0;
  489. for(i=0; i<MAX_MARKET_GOODS; ++i, goodsPtr++)
  490. {
  491. if(goodsPtr->raw_id)
  492. {
  493. if(goodsNum==0)
  494. goodsId = goodsPtr->raw_id;
  495. goodsNum++;
  496. }
  497. else if(goodsPtr->product_raw_id)
  498. {
  499. if(goodsNum==0)
  500. goodsId = goodsPtr->product_raw_id+MAX_RAW;
  501. goodsNum++;
  502. }
  503. }
  504. if(goodsNum==1)
  505. stopPtr->pick_up_toggle(goodsId); // cancel auto_pick_up
  506. else if(goodsNum==0)
  507. stopPtr->pick_up_set_none();
  508. else
  509. stopPtr->pick_up_set_auto();
  510. break;
  511. default: err_here();
  512. break;
  513. }
  514. last_set_stop_date = info.game_date;
  515. //-------------------------------------------------------//
  516. // remove duplicate stop or stop change nation
  517. //-------------------------------------------------------//
  518. update_stop_list();
  519. if(dest_stop_id)
  520. {
  521. if((newStopFirmRecno=stop_array[dest_stop_id-1].firm_recno) != oldStopFirmRecno)
  522. {
  523. firmPtr = firm_array[newStopFirmRecno];
  524. err_when(firmPtr->firm_id!=FIRM_MARKET && firmPtr->firm_id!=FIRM_MINE && firmPtr->firm_id!=FIRM_FACTORY);
  525. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, stop_array[dest_stop_id-1].firm_id);
  526. journey_status = ON_WAY_TO_FIRM;
  527. }
  528. }
  529. else
  530. stop2();
  531. if( unit_array.selected_recno == sprite_recno )
  532. {
  533. if(!remote.is_enable() || nation_recno==nation_array.player_recno || config.show_ai_info)
  534. info.disp();
  535. }
  536. }
  537. //---------- End of function UnitCaravan::set_stop ----------//
  538. //--------- Begin of function UnitCaravan::del_stop ---------//
  539. void UnitCaravan::del_stop(int stopId, char remoteAction)
  540. {
  541. err_when(action_para || action_para2);
  542. if(!remoteAction && remote.is_enable())
  543. {
  544. // packet structure : <unit recno> <stop id>
  545. short *shortPtr = (short *) remote.new_send_queue_msg(MSG_U_CARA_DEL_STOP, 2*sizeof(short));
  546. *shortPtr = sprite_recno;
  547. shortPtr[1] = stopId;
  548. return;
  549. }
  550. //------ stop is deleted before receiving this message, thus, ignore invalid message -----//
  551. if(remote.is_enable() && stop_array[stopId-1].firm_recno==0)
  552. return;
  553. stop_array[stopId-1].firm_recno = 0;
  554. stop_defined_num--;
  555. err_when( stop_defined_num < 0 );
  556. update_stop_list();
  557. if( unit_array.selected_recno == sprite_recno )
  558. {
  559. if(!remote.is_enable() || nation_recno==nation_array.player_recno || config.show_ai_info)
  560. info.disp();
  561. }
  562. }
  563. //---------- End of function UnitCaravan::del_stop ----------//
  564. //--------- Begin of function UnitCaravan::update_stop_list ---------//
  565. void UnitCaravan::update_stop_list()
  566. {
  567. err_when(stop_defined_num<0 || stop_defined_num>MAX_STOP_FOR_CARAVAN);
  568. //------------- used to debug for multiplayer game ------------------//
  569. #ifdef DEBUG
  570. m.random(100);
  571. #endif
  572. //-------------------------------------------------------//
  573. // backup original destination stop firm recno
  574. //-------------------------------------------------------//
  575. short nextStopRecno = stop_array[dest_stop_id-1].firm_recno;
  576. //----------------------------------------------------------------------//
  577. // check stop existence and the relationship between firm's nation
  578. //----------------------------------------------------------------------//
  579. CaravanStop *nodePtr = stop_array;
  580. Firm *firmPtr;
  581. int i;
  582. for(i=0; i<MAX_STOP_FOR_CARAVAN; i++, nodePtr++)
  583. {
  584. if(!nodePtr->firm_recno)
  585. continue;
  586. if(firm_array.is_deleted(nodePtr->firm_recno))
  587. {
  588. nodePtr->firm_recno = 0; // clear the recno
  589. stop_defined_num--;
  590. err_when( stop_defined_num < 0 );
  591. continue;
  592. }
  593. firmPtr = firm_array[nodePtr->firm_recno];
  594. if( !can_set_stop(nodePtr->firm_recno) ||
  595. firmPtr->loc_x1!=nodePtr->firm_loc_x1 ||
  596. firmPtr->loc_y1!=nodePtr->firm_loc_y1 )
  597. {
  598. nodePtr->firm_recno = 0;
  599. stop_defined_num--;
  600. err_when( stop_defined_num < 0 );
  601. continue;
  602. }
  603. }
  604. //-------------------------------------------------------//
  605. // remove duplicate node
  606. //-------------------------------------------------------//
  607. CaravanStop *insertNodePtr = stop_array;
  608. if(stop_defined_num<1)
  609. {
  610. memset(stop_array, 0, sizeof(CaravanStop)*MAX_STOP_FOR_CARAVAN);
  611. dest_stop_id = 0;
  612. return; // no stop
  613. }
  614. //-------------------------------------------------------//
  615. // pack the firm_recno to the beginning part of the array
  616. //-------------------------------------------------------//
  617. short compareRecno;
  618. for(i=0, nodePtr=stop_array; i<MAX_STOP_FOR_CARAVAN; i++, nodePtr++)
  619. {
  620. if(nodePtr->firm_recno)
  621. {
  622. compareRecno = nodePtr->firm_recno;
  623. break;
  624. }
  625. }
  626. if(i++) // else, the first record is already in the beginning of the array
  627. memcpy(insertNodePtr, nodePtr, sizeof(CaravanStop));
  628. if(stop_defined_num==1)
  629. {
  630. memset(insertNodePtr+1, 0, sizeof(CaravanStop)*(MAX_STOP_FOR_CARAVAN-1));
  631. dest_stop_id = 1;
  632. return;
  633. }
  634. short unprocessed = stop_defined_num-1;
  635. err_when(i==MAX_STOP_FOR_CARAVAN); // error if only one record
  636. err_when(!unprocessed);
  637. insertNodePtr++;
  638. nodePtr++;
  639. for(; i<MAX_STOP_FOR_CARAVAN && unprocessed; i++, nodePtr++)
  640. {
  641. if(!nodePtr->firm_recno)
  642. continue; // empty
  643. err_when(!nodePtr->firm_recno);
  644. if(nodePtr->firm_recno==compareRecno)
  645. {
  646. nodePtr->firm_recno = 0;
  647. stop_defined_num--;
  648. err_when( stop_defined_num < 0 );
  649. }
  650. else
  651. {
  652. compareRecno = nodePtr->firm_recno;
  653. if(insertNodePtr!=nodePtr)
  654. memcpy(insertNodePtr++, nodePtr, sizeof(CaravanStop));
  655. else
  656. insertNodePtr++;
  657. }
  658. unprocessed--;
  659. }
  660. if(stop_defined_num>2)
  661. {
  662. //-------- compare the first and the end record -------//
  663. nodePtr = stop_array + stop_defined_num - 1; // point to the end
  664. if(nodePtr->firm_recno == stop_array[0].firm_recno)
  665. {
  666. nodePtr->firm_recno = 0; // remove the end record
  667. stop_defined_num--;
  668. err_when( stop_defined_num < 0 );
  669. }
  670. }
  671. if(stop_defined_num<MAX_STOP_FOR_CARAVAN)
  672. memset(stop_array+stop_defined_num, 0, sizeof(CaravanStop)*(MAX_STOP_FOR_CARAVAN-stop_defined_num));
  673. #ifdef DEBUG
  674. int debugCount;
  675. for(debugCount=0; debugCount<stop_defined_num; debugCount++)
  676. err_when(!stop_array[debugCount].firm_recno);
  677. for(; debugCount<MAX_STOP_FOR_CARAVAN; debugCount++)
  678. err_when(stop_array[debugCount].firm_recno);
  679. for(debugCount=0; debugCount<stop_defined_num; debugCount++)
  680. err_when(stop_array[debugCount].firm_recno &&
  681. stop_array[debugCount].firm_recno==stop_array[(debugCount+1)%MAX_STOP_FOR_CARAVAN].firm_recno);
  682. #endif
  683. //-----------------------------------------------------------------------------------------//
  684. // There should be at least one stop in the list. Otherwise, clear all the stops
  685. //-----------------------------------------------------------------------------------------//
  686. int ourFirmExist = 0;
  687. for(i=0, nodePtr=stop_array; i<stop_defined_num; i++, nodePtr++)
  688. {
  689. err_when(firm_array.is_deleted(nodePtr->firm_recno));
  690. firmPtr = firm_array[nodePtr->firm_recno];
  691. if(firmPtr->nation_recno==nation_recno)
  692. {
  693. ourFirmExist++;
  694. break;
  695. }
  696. }
  697. if(!ourFirmExist) // none of the markets belong to our nation
  698. {
  699. memset(stop_array, 0, MAX_STOP_FOR_CARAVAN * sizeof(CaravanStop));
  700. journey_status = ON_WAY_TO_FIRM;
  701. dest_stop_id = 0;
  702. stop_defined_num = 0;
  703. return;
  704. }
  705. //-----------------------------------------------------------------------------------------//
  706. // reset dest_stop_id since the order of the stop may be changed
  707. //-----------------------------------------------------------------------------------------//
  708. int xLoc = next_x_loc();
  709. int yLoc = next_y_loc();
  710. int dist, minDist=0x7FFF;
  711. for(i=0, dest_stop_id=0, nodePtr=stop_array; i<stop_defined_num; i++, nodePtr++)
  712. {
  713. if(nodePtr->firm_recno==nextStopRecno)
  714. {
  715. dest_stop_id = i+1;
  716. break;
  717. }
  718. else
  719. {
  720. firmPtr = firm_array[nodePtr->firm_recno];
  721. dist = m.points_distance(xLoc, yLoc, firmPtr->center_x, firmPtr->center_y);
  722. if(dist<minDist)
  723. {
  724. dist = minDist;
  725. dest_stop_id = i+1;
  726. }
  727. }
  728. }
  729. err_when(dest_stop_id<0 || dest_stop_id>MAX_STOP_FOR_CARAVAN);
  730. }
  731. //----------- End of function UnitCaravan::update_stop_list -----------//
  732. //--------- Begin of function UnitCaravan::update_stop_and_goods_info ---------//
  733. void UnitCaravan::update_stop_and_goods_info()
  734. {
  735. update_stop_list();
  736. update_caravan_stop_and_goods_to_dummy(this);
  737. if(sprite_recno==unit_array.selected_recno && ((nation_array.player_recno && nation_recno==nation_array.player_recno) ||
  738. config.show_ai_info))
  739. {
  740. memcpy(goods_num, dummyCaravanGoodsNum, sizeof(char)*MAX_STOP_FOR_CARAVAN);
  741. memcpy(button_select_enable_flag, dummyCaravanEnableFlag, sizeof(char)*MAX_STOP_FOR_CARAVAN*MAX_GOODS_SELECT_BUTTON);
  742. }
  743. }
  744. //----------- End of function UnitCaravan::update_stop_and_goods_info -----------//
  745. //--------- Begin of function UnitCaravan::can_set_stop ---------//
  746. //
  747. // Whether can set a caravan's stop on the given firm.
  748. //
  749. int UnitCaravan::can_set_stop(int firmRecno)
  750. {
  751. Firm* firmPtr = firm_array[firmRecno];
  752. if( firmPtr->under_construction )
  753. return 0;
  754. switch(firmPtr->firm_id)
  755. {
  756. case FIRM_MARKET:
  757. return nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty;
  758. case FIRM_MINE:
  759. case FIRM_FACTORY:
  760. return nation_recno == firmPtr->nation_recno;
  761. default:
  762. return 0;
  763. }
  764. }
  765. //----------- End of function UnitCaravan::can_set_stop -----------//
  766. //--------- Begin of function UnitCaravan::get_next_stop_id ---------//
  767. //
  768. // Get the id. of the next defined stop.
  769. //
  770. // [int] curStopId - the id. of the current stop.
  771. // if it is MAX_STOP_FOR_CARAVAN, this function will return
  772. // the id. of the first valid stop.
  773. //
  774. // (default: MAX_STOP_FOR_CARAVAN)
  775. // return : 0 ~ MAX_STOP_FOR_CARAVAN, where 0 for no valid stop
  776. //
  777. int UnitCaravan::get_next_stop_id(int curStopId)
  778. {
  779. int nextStopId = (curStopId>=stop_defined_num) ? 1 : curStopId+1;
  780. CaravanStop *stopPtr = stop_array+nextStopId-1;
  781. int needUpdate = 0;
  782. if(firm_array.is_deleted(stopPtr->firm_recno))
  783. {
  784. needUpdate++;
  785. }
  786. else
  787. {
  788. Firm *firmPtr = firm_array[stopPtr->firm_recno];
  789. if( !can_set_stop( stopPtr->firm_recno ) ||
  790. firmPtr->loc_x1 != stopPtr->firm_loc_x1 ||
  791. firmPtr->loc_y1 != stopPtr->firm_loc_y1 )
  792. {
  793. needUpdate++;
  794. }
  795. }
  796. //### begin alex 24/10 ###//
  797. if(needUpdate)
  798. {
  799. short preStopRecno = stop_array[curStopId-1].firm_recno;
  800. update_stop_list();
  801. if(!stop_defined_num)
  802. return 0; // no stop is valid
  803. int i;
  804. for(i=1, stopPtr=stop_array; i<=stop_defined_num; i++, stopPtr++)
  805. {
  806. if(stopPtr->firm_recno==preStopRecno)
  807. return (i>=stop_defined_num) ? 1 : i+1;
  808. }
  809. return 1;
  810. }
  811. else
  812. return nextStopId;
  813. //#### end alex 24/10 ####//
  814. }
  815. //----------- End of function UnitCaravan::get_next_stop_id -----------//
  816. //--------- Begin of function UnitCaravan::pre_process ---------//
  817. //
  818. void UnitCaravan::pre_process()
  819. {
  820. Unit::pre_process();
  821. if(cur_x == -1) // can't use !is_visible(), keep process if cur_x < -1
  822. return;
  823. #define SURROUND_FIRM_WAIT_FACTOR 10
  824. //-----------------------------------------------------------------------------//
  825. // if all the hit points are lost, die now
  826. //-----------------------------------------------------------------------------//
  827. if(hit_points <= 0)
  828. {
  829. if(action_mode != ACTION_DIE)
  830. set_die();
  831. return;
  832. }
  833. err_when(action_mode==ACTION_DIE || cur_action==SPRITE_DIE || hit_points<=0);
  834. //-----------------------------------------------------------------------------//
  835. // stop action if no stop is defined
  836. //-----------------------------------------------------------------------------//
  837. if(!stop_defined_num)
  838. {
  839. err_when(dest_stop_id!=0);
  840. if(journey_status!=NO_STOP_DEFINED)
  841. stop(); // stop if no valid stop is defined
  842. journey_status = NO_STOP_DEFINED;
  843. return;
  844. }
  845. //-----------------------------------------------------------------------------//
  846. // wait in the surrounding of the stop if stop_defined_num==1 (only one stop)
  847. //-----------------------------------------------------------------------------//
  848. if(stop_defined_num==1)
  849. {
  850. CaravanStop *stopPtr = &stop_array[0];
  851. err_when(!stopPtr->firm_recno);
  852. if(firm_array.is_deleted(stopPtr->firm_recno))
  853. {
  854. update_stop_list();
  855. return;
  856. }
  857. Firm *firmPtr = firm_array[stopPtr->firm_recno];
  858. int firmXLoc1 = firmPtr->loc_x1;
  859. int firmYLoc1 = firmPtr->loc_y1;
  860. int firmXLoc2 = firmPtr->loc_x2;
  861. int firmYLoc2 = firmPtr->loc_y2;
  862. int firmId = firmPtr->firm_id;
  863. if(firmXLoc1!=stopPtr->firm_loc_x1 || firmYLoc1!=stopPtr->firm_loc_y1 ||
  864. (firmId!=FIRM_MINE && firmId!=FIRM_FACTORY && firmId!=FIRM_MARKET))
  865. {
  866. update_stop_list();
  867. return;
  868. }
  869. int curXLoc = next_x_loc();
  870. int curYLoc = next_y_loc();
  871. if(curXLoc<firmXLoc1-1 || curXLoc>firmXLoc2+1 || curYLoc<firmYLoc1-1 || curYLoc>firmYLoc2+1)
  872. {
  873. if(cur_action==SPRITE_IDLE)
  874. move_to_firm_surround(firmXLoc1, firmYLoc1, sprite_info->loc_width, sprite_info->loc_height, firmId);
  875. else
  876. journey_status = ON_WAY_TO_FIRM;
  877. }
  878. else
  879. {
  880. journey_status = SURROUND_FIRM;
  881. //if(firmPtr->nation_recno==nation_recno)
  882. if(nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty)
  883. {
  884. if(wait_count<=0)
  885. {
  886. //---------- unloading goods -------------//
  887. switch(stopPtr->firm_id)
  888. {
  889. case FIRM_MINE:
  890. break; // no goods unload to mine
  891. case FIRM_FACTORY:
  892. factory_unload_goods();
  893. break;
  894. case FIRM_MARKET:
  895. market_unload_goods();
  896. break;
  897. default: err_here();
  898. break;
  899. }
  900. wait_count = MAX_CARAVAN_WAIT_TERM*SURROUND_FIRM_WAIT_FACTOR;
  901. }
  902. else
  903. wait_count--;
  904. }
  905. }
  906. return;
  907. }
  908. //-----------------------------------------------------------------------------//
  909. // at least 2 stops for the caravan to move between
  910. //-----------------------------------------------------------------------------//
  911. err_when(stop_defined_num<=1);
  912. if(journey_status==INSIDE_FIRM)
  913. caravan_in_firm();
  914. else
  915. caravan_on_way();
  916. }
  917. //----------- End of function UnitCaravan::pre_process -----------//
  918. //--------- Begin of function UnitCaravan::caravan_in_firm ---------//
  919. // journey_status : INSIDE_FIRM --> ON_WAY_TO_FIRM
  920. // NO_STOP_DEFINED if no valid stop
  921. // SURROUND_FIRM if only one stop
  922. //
  923. void UnitCaravan::caravan_in_firm()
  924. {
  925. //-----------------------------------------------------------------------------//
  926. // the market is deleted while the caravan is in market
  927. //-----------------------------------------------------------------------------//
  928. if(firm_array.is_deleted(action_para))
  929. {
  930. hit_points = (float) 0; // caravan also die if the market is deleted
  931. unit_array.disappear_in_firm(sprite_recno); // caravan also die if the market is deleted
  932. return;
  933. }
  934. //-----------------------------------------------------------------------------//
  935. // waiting (time to upload/download cargo)
  936. //-----------------------------------------------------------------------------//
  937. if(wait_count>0)
  938. {
  939. wait_count--;
  940. return;
  941. }
  942. //-----------------------------------------------------------------------------//
  943. // leave the market and go to another market if possible
  944. //-----------------------------------------------------------------------------//
  945. CaravanStop *stopPtr = stop_array + dest_stop_id - 1;
  946. int xLoc = stop_x_loc;
  947. int yLoc = stop_y_loc;
  948. Location *locPtr = world.get_loc(xLoc, yLoc);
  949. Firm *firmPtr;
  950. if(locPtr->can_move(mobile_type))
  951. init_sprite(xLoc, yLoc); // appear in the location the unit disappeared before
  952. else
  953. {
  954. //---- the entering location is blocked, select another location to leave ----//
  955. err_when(action_para==0);
  956. firmPtr = firm_array[action_para];
  957. if(appear_in_firm_surround(xLoc, yLoc, firmPtr))
  958. {
  959. init_sprite(xLoc, yLoc);
  960. stop();
  961. err_when(action_para);
  962. }
  963. else
  964. {
  965. wait_count = MAX_CARAVAN_WAIT_TERM*10; //********* BUGHERE, continue to wait or ....
  966. return;
  967. }
  968. }
  969. //-------------- get next stop id. ----------------//
  970. int nextStopId = get_next_stop_id(dest_stop_id);
  971. if(!nextStopId || dest_stop_id==nextStopId)
  972. {
  973. dest_stop_id = nextStopId;
  974. journey_status = (!nextStopId) ? NO_STOP_DEFINED : SURROUND_FIRM;
  975. return; // no stop or only one stop is valid
  976. }
  977. dest_stop_id = nextStopId;
  978. firmPtr = firm_array[stop_array[dest_stop_id-1].firm_recno];
  979. action_para = 0; // since action_para is used to store the current market recno, reset before searching
  980. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
  981. journey_status = ON_WAY_TO_FIRM;
  982. }
  983. //----------- End of function UnitCaravan::caravan_in_firm -----------//
  984. //--------- Begin of function UnitCaravan::caravan_on_way ---------//
  985. // journey_status : ON_WAY_TO_FIRM --> SURROUND_FIRM
  986. // SURROUND_FIRM --> INSIDE_FIRM
  987. //
  988. void UnitCaravan::caravan_on_way()
  989. {
  990. CaravanStop *stopPtr = stop_array + dest_stop_id - 1;
  991. if(cur_action==SPRITE_IDLE && journey_status!=SURROUND_FIRM)
  992. {
  993. if(!firm_array.is_deleted(stopPtr->firm_recno))
  994. {
  995. Firm *firmPtr = firm_array[stopPtr->firm_recno];
  996. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
  997. int nextXLoc = next_x_loc();
  998. int nextYLoc = next_y_loc();
  999. if(nextXLoc>=firmPtr->loc_x1-1 && nextXLoc<=firmPtr->loc_x2+1 &&
  1000. nextYLoc>=firmPtr->loc_y1-1 && nextYLoc<=firmPtr->loc_y2+1) // hard code 1 for carvan size 1x1
  1001. journey_status = SURROUND_FIRM;
  1002. if(nextXLoc==move_to_x_loc && nextYLoc==move_to_y_loc && !ignore_power_nation)
  1003. ignore_power_nation = 1;
  1004. return;
  1005. }
  1006. }
  1007. short unitRecno = sprite_recno;
  1008. err_when(cur_action==SPRITE_ATTACK || action_mode==ACTION_ATTACK_UNIT || action_mode==ACTION_ATTACK_FIRM ||
  1009. action_mode==ACTION_ATTACK_TOWN || action_mode==ACTION_ATTACK_WALL);
  1010. if(unit_array.is_deleted(unitRecno))
  1011. return; //-***************** BUGHERE ***************//
  1012. if(firm_array.is_deleted(stopPtr->firm_recno))
  1013. {
  1014. update_stop_list();
  1015. if(stop_defined_num) // move to next stop
  1016. {
  1017. Firm *firmPtr = firm_array[stop_array[stop_defined_num-1].firm_recno];
  1018. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
  1019. }
  1020. return;
  1021. }
  1022. //CaravanStop *stopPtr = stop_array + dest_stop_id - 1;
  1023. Firm *firmPtr = firm_array[stopPtr->firm_recno];
  1024. int nextXLoc = next_x_loc();
  1025. int nextYLoc = next_y_loc();
  1026. if(journey_status==SURROUND_FIRM ||
  1027. ( nextXLoc==move_to_x_loc && nextYLoc==move_to_y_loc && cur_x==next_x && cur_y==next_y && // move in a tile exactly
  1028. (nextXLoc>=firmPtr->loc_x1-1 && nextXLoc<=firmPtr->loc_x2+1 &&
  1029. nextYLoc>=firmPtr->loc_y1-1 && nextYLoc<=firmPtr->loc_y2+1) )) // in the surrounding of the firm
  1030. {
  1031. //-*************************************************************-//
  1032. /*if(nation_recno==nation_array.player_recno)
  1033. {
  1034. OutputDebugString("surround firm\r\n");
  1035. for(int type = 0; type<MAX_GOODS_SELECT_BUTTON; type++)
  1036. {
  1037. if(button_select_enable_flag[0][type])
  1038. break;
  1039. }
  1040. stop_array[0].pick_up_array[type] ^= 1;
  1041. set_stop_pick_up(1, type, COMMAND_PLAYER);
  1042. }*/
  1043. //-*************************************************************-//
  1044. //-------------------- update pick_up_array --------------------//
  1045. stopPtr->update_pick_up();
  1046. //-------------------------------------------------------//
  1047. // load/unload goods
  1048. //-------------------------------------------------------//
  1049. if(nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty)
  1050. {
  1051. switch(firmPtr->firm_id)
  1052. {
  1053. case FIRM_MINE:
  1054. mine_load_goods(stopPtr->pick_up_type);
  1055. break;
  1056. case FIRM_FACTORY:
  1057. factory_unload_goods();
  1058. factory_load_goods(stopPtr->pick_up_type);
  1059. break;
  1060. case FIRM_MARKET:
  1061. market_unload_goods();
  1062. if(stopPtr->pick_up_type == AUTO_PICK_UP)
  1063. market_auto_load_goods();
  1064. else if(stopPtr->pick_up_type!=NO_PICK_UP)
  1065. market_load_goods();
  1066. break;
  1067. default: err_here();
  1068. break;
  1069. }
  1070. }
  1071. //-------------------------------------------------------//
  1072. // action_para is used to store the firm_recno of the market
  1073. // where the caravan move in.
  1074. //-------------------------------------------------------//
  1075. action_para = stopPtr->firm_recno;
  1076. stop_x_loc = move_to_x_loc; // store entering location
  1077. stop_y_loc = move_to_y_loc;
  1078. wait_count = MAX_CARAVAN_WAIT_TERM; // set waiting term
  1079. reset_path();
  1080. deinit_sprite(1); // the caravan enters the market now. 1-keep it selected if it is currently selected
  1081. err_when(cur_x!=-1);
  1082. cur_x--; // set cur_x to -2, such that invisible but still process pre_process()
  1083. journey_status = INSIDE_FIRM;
  1084. }
  1085. else
  1086. {
  1087. if(cur_action!=SPRITE_MOVE)
  1088. {
  1089. //----------------------------------------------------//
  1090. // blocked by something, go to the destination again
  1091. // note: if return value is 0, cannot reach the firm. //*********BUGHERE
  1092. //----------------------------------------------------//
  1093. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
  1094. journey_status = ON_WAY_TO_FIRM;
  1095. }
  1096. }
  1097. }
  1098. //----------- End of function UnitCaravan::caravan_on_way -----------//
  1099. //--------- Begin of function UnitCaravan::appear_in_firm_surround ---------//
  1100. //
  1101. // This function return 1 if a suitable location is found, that means the
  1102. // caravan will leave the firm there. Otherwise, return 0.
  1103. //
  1104. // xLoc, yLoc are reference variables for returning the location found.
  1105. //
  1106. int UnitCaravan::appear_in_firm_surround(int& xLoc, int& yLoc, Firm* firmPtr)
  1107. {
  1108. int upperLeftBoundX = firmPtr->loc_x1 - 1; // the surrounding coordinates of the firm
  1109. int upperLeftBoundY = firmPtr->loc_y1 - 1;
  1110. int lowerRightBoundX = firmPtr->loc_x2 + 1;
  1111. int lowerRightBoundY = firmPtr->loc_y2 + 1;
  1112. int count = 1, inside = 1, found = 0, i;
  1113. int testXLoc = xLoc;
  1114. int testYLoc = yLoc;
  1115. int limit;
  1116. Location *locPtr;
  1117. //---------------------------------------------------------//
  1118. // 9 10 11 12 the location is tested in the order
  1119. // 8 1 2 13 shown, if the location is the surrounding
  1120. // 7 x 3 14 of the firm and non-blocked, break
  1121. // 6 5 4 ... the test
  1122. //---------------------------------------------------------//
  1123. while(inside)
  1124. {
  1125. inside = 0;
  1126. limit = count<<1;
  1127. err_when(limit!=count*2);
  1128. //------------ upper --------------//
  1129. testXLoc = xLoc - count + 1;
  1130. testYLoc = yLoc - count;
  1131. for(i=0; i<limit; i++)
  1132. {
  1133. if(testXLoc<0 || testYLoc>=MAX_WORLD_X_LOC || testYLoc<0 || testYLoc>=MAX_WORLD_Y_LOC)
  1134. continue;
  1135. if(testXLoc<upperLeftBoundX || testXLoc>lowerRightBoundX || testYLoc<upperLeftBoundY || testYLoc>lowerRightBoundY)
  1136. continue;
  1137. locPtr = world.get_loc(testXLoc, testYLoc);
  1138. if(locPtr->can_move(mobile_type))
  1139. {
  1140. found++;
  1141. break;
  1142. }
  1143. else
  1144. xLoc++;
  1145. inside++;
  1146. }
  1147. if(found)
  1148. break;
  1149. //------------ right --------------//
  1150. testXLoc = xLoc + count;
  1151. testYLoc = yLoc - count + 1;
  1152. for(i=0; i<limit; i++)
  1153. {
  1154. if(testXLoc<0 || testYLoc>=MAX_WORLD_X_LOC || testYLoc<0 || testYLoc>=MAX_WORLD_Y_LOC)
  1155. continue;
  1156. if(testXLoc<upperLeftBoundX || testXLoc>lowerRightBoundX || testYLoc<upperLeftBoundY || testYLoc>lowerRightBoundY)
  1157. continue;
  1158. locPtr = world.get_loc(testXLoc, testYLoc);
  1159. if(locPtr->can_move(mobile_type))
  1160. {
  1161. found++;
  1162. break;
  1163. }
  1164. else
  1165. yLoc++;
  1166. inside++;
  1167. }
  1168. if(found)
  1169. break;
  1170. //------------- down --------------//
  1171. testXLoc = xLoc + count - 1;
  1172. testYLoc = yLoc + count;
  1173. for(i=0; i<limit; i++)
  1174. {
  1175. if(testXLoc<0 || testYLoc>=MAX_WORLD_X_LOC || testYLoc<0 || testYLoc>=MAX_WORLD_Y_LOC)
  1176. continue;
  1177. if(testXLoc<upperLeftBoundX || testXLoc>lowerRightBoundX || testYLoc<upperLeftBoundY || testYLoc>lowerRightBoundY)
  1178. continue;
  1179. locPtr = world.get_loc(testXLoc, testYLoc);
  1180. if(locPtr->can_move(mobile_type))
  1181. {
  1182. found++;
  1183. break;
  1184. }
  1185. else
  1186. xLoc--;
  1187. inside++;
  1188. }
  1189. if(found)
  1190. break;
  1191. //------------- left --------------//
  1192. testXLoc = xLoc - count;
  1193. testYLoc = yLoc + count - 1;
  1194. for(i=0; i<limit; i++)
  1195. {
  1196. if(testXLoc<0 || testYLoc>=MAX_WORLD_X_LOC || testYLoc<0 || testYLoc>=MAX_WORLD_Y_LOC)
  1197. continue;
  1198. if(testXLoc<upperLeftBoundX || testXLoc>lowerRightBoundX || testYLoc<upperLeftBoundY || testYLoc>lowerRightBoundY)
  1199. continue;
  1200. locPtr = world.get_loc(testXLoc, testYLoc);
  1201. if(locPtr->can_move(mobile_type))
  1202. {
  1203. found++;
  1204. break;
  1205. }
  1206. else
  1207. yLoc--;
  1208. inside++;
  1209. }
  1210. if(found)
  1211. break;
  1212. //---------------------------------------------//
  1213. count++;
  1214. }
  1215. if(found)
  1216. {
  1217. xLoc = testXLoc;
  1218. yLoc = testYLoc;
  1219. return 1;
  1220. }
  1221. return 0;
  1222. }
  1223. //----------- End of function UnitCaravan::appear_in_firm_surround -----------//
  1224. //---------- begin static function i_disp_caravan_select_button ---------------//
  1225. static void i_disp_caravan_select_button(ButtonCustom *button, int repaintBody)
  1226. {
  1227. int x1 = button->x1;
  1228. int y1 = button->y1;
  1229. int x2 = button->x2;
  1230. int y2 = button->y2;
  1231. int shift;
  1232. //------------- modify x1,y1, x2,y2 to the button body --------------//
  1233. if(button->pushed_flag)
  1234. {
  1235. int colorDown = Vga::active_buf->color_down; // change the color of the body area to yellow to highlight the change
  1236. Vga::active_buf->color_down = (char) V_YELLOW;
  1237. Vga::active_buf->d3_panel_down(x1, y1, x2, y2);
  1238. Vga::active_buf->color_down = (char) colorDown;
  1239. x1++;
  1240. y1++;
  1241. shift = 2;
  1242. }
  1243. else
  1244. {
  1245. Vga::active_buf->d3_panel_up(x1, y1, x2, y2);
  1246. x2--;
  1247. y2--;
  1248. shift = 3;
  1249. }
  1250. //-------------- put goods icon ---------------//
  1251. int id = button->custom_para.value;
  1252. char *iconName=NULL;
  1253. int x = x1+shift;
  1254. int y = y1+shift;
  1255. if(id==AUTO_PICK_UP)
  1256. {
  1257. iconName = "AUTOPICK";
  1258. }
  1259. else if(id==NO_PICK_UP)
  1260. {
  1261. iconName = "NOPICK";
  1262. }
  1263. else if(id>=PICK_UP_RAW_FIRST && id<=PICK_UP_RAW_LAST)
  1264. {
  1265. raw_res.put_small_raw_icon( x, y, id-PICK_UP_RAW_FIRST+1 );
  1266. }
  1267. else if(id>=PICK_UP_PRODUCT_FIRST && id<=PICK_UP_PRODUCT_LAST)
  1268. {
  1269. raw_res.put_small_product_icon( x, y, id-PICK_UP_PRODUCT_FIRST+1 );
  1270. }
  1271. else
  1272. err_here();
  1273. if( iconName )
  1274. {
  1275. help.set_help( x, y, x+9, y+9, iconName );
  1276. Vga::active_buf->put_bitmap_trans( x, y, image_icon.get_ptr(iconName) );
  1277. }
  1278. }
  1279. //---------- end static function i_disp_caravan_select_button ---------------//
  1280. //--------- Begin of function UnitCaravan::has_pick_up_type ---------//
  1281. //
  1282. // Return whether the specific stop has the specific pick up types.
  1283. //
  1284. int UnitCaravan::has_pick_up_type(int stopId, int pickUpType)
  1285. {
  1286. return stop_array[stopId-1].pick_up_array[pickUpType-1];
  1287. }
  1288. //---------- End of function UnitCaravan::has_pick_up_type ----------//
  1289. //--------- Begin of function UnitCaravan::carrying_qty ---------//
  1290. //
  1291. // Return whether the qty of the specific product/raw type that
  1292. // this caravan is currently carrying.
  1293. //
  1294. int UnitCaravan::carrying_qty(int pickUpType)
  1295. {
  1296. if( pickUpType >= PICK_UP_RAW_FIRST &&
  1297. pickUpType <= PICK_UP_RAW_LAST )
  1298. {
  1299. return raw_qty_array[pickUpType-PICK_UP_RAW_FIRST];
  1300. }
  1301. else if( pickUpType >= PICK_UP_PRODUCT_FIRST &&
  1302. pickUpType <= PICK_UP_PRODUCT_LAST )
  1303. {
  1304. return product_raw_qty_array[pickUpType-PICK_UP_PRODUCT_FIRST];
  1305. }
  1306. else
  1307. {
  1308. err_here();
  1309. return 0;
  1310. }
  1311. }
  1312. //---------- End of function UnitCaravan::carrying_qty ----------//