OU_MARIF.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  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_MARI2.CPP
  21. //Description: UnitMarine - functions for displaying info.
  22. #include <OVGA.h>
  23. #include <OINFO.h>
  24. #include <OHELP.h>
  25. #include <OMOUSE.h>
  26. #include <OCONFIG.h>
  27. #include <ORACERES.h>
  28. #include <OIMGRES.h>
  29. #include <ORAWRES.h>
  30. #include <OPOWER.h>
  31. #include <OFONT.h>
  32. #include <OBUTTON.h>
  33. #include <OBUTT3D.h>
  34. #include <OREMOTE.h>
  35. #include <OU_CARA.h>
  36. #include <OU_MARI.h>
  37. #include <ONATION.h>
  38. #include <OF_MINE.h>
  39. #include <OF_FACT.h>
  40. #include <OBUTTCUS.h>
  41. #include <OSE.h>
  42. #include <OF_HARB.h>
  43. #ifdef DEBUG
  44. #include <stdio.h>
  45. #endif
  46. //--------- Define static vars ----------//
  47. static short unit_disp_y1, unit_info_disp_y1, stop_disp_y1;
  48. static Button3D button_unload_all;
  49. static ButtonGroup button_mode(2);
  50. static Button button_auto_trade;
  51. static Button button_set_stop[MAX_STOP_FOR_SHIP];
  52. static Button button_go_stop[MAX_STOP_FOR_SHIP];
  53. static Button button_cancel_stop[MAX_STOP_FOR_SHIP];
  54. //static Button button_select_attack;
  55. static ButtonCustom button_select_array[MAX_STOP_FOR_SHIP][MAX_GOODS_SELECT_BUTTON];
  56. static char button_select_enable_flag[MAX_STOP_FOR_SHIP][MAX_GOODS_SELECT_BUTTON];
  57. static char ship_goods_num[MAX_STOP_FOR_SHIP];
  58. static void i_disp_marine_select_button(ButtonCustom *button, int repaintBody);
  59. static char dummyShipEnableFlag[MAX_STOP_FOR_CARAVAN][MAX_GOODS_SELECT_BUTTON];
  60. static char dummyShipGoodsNum[MAX_STOP_FOR_CARAVAN];
  61. //------------ define static function -------------//
  62. static void update_ship_stop_and_goods_info_to_dummy(UnitMarine *shipPtr)
  63. {
  64. ShipStop *stopPtr = shipPtr->stop_array;
  65. for(int i=0; i<MAX_STOP_FOR_SHIP; i++, stopPtr++)
  66. {
  67. if(!stopPtr->firm_recno)
  68. continue;
  69. err_when(firm_array.is_deleted(stopPtr->firm_recno));
  70. dummyShipGoodsNum[i] = stopPtr->update_pick_up(dummyShipEnableFlag[i]);
  71. }
  72. }
  73. //--------- Begin of function UnitMarine::disp_info ---------//
  74. //
  75. void UnitMarine::disp_info(int refreshFlag)
  76. {
  77. disp_basic_info(INFO_Y1, refreshFlag);
  78. if( !should_show_info() )
  79. return;
  80. //---- display the switch between the units and goods menu ----//
  81. UnitInfo* unitInfo = unit_res[unit_id];
  82. int y=INFO_Y1+54;
  83. if( unitInfo->carry_unit_capacity && unitInfo->carry_goods_capacity )
  84. {
  85. if( refreshFlag == INFO_REPAINT )
  86. {
  87. vga.d3_panel_up( INFO_X1, y, INFO_X2, y+22 );
  88. button_mode[0].create_text( INFO_X1+5, y+3, INFO_X1+80, y+19, "Units" );
  89. button_mode[1].create_text( INFO_X1+90, y+3, INFO_X1+155, y+19, "Goods" );
  90. button_mode.paint(menu_mode);
  91. button_auto_trade.paint_text( INFO_X1+165, y+3, INFO_X2-10, y+19, auto_mode ? (char*)"T" : (char*)"C");
  92. }
  93. y += 25;
  94. }
  95. //----- for multiplayer game, skip displaying information for the first frame --------//
  96. if(remote.is_enable())
  97. {
  98. if(unit_array.mp_first_frame_to_select_ship && // first frame
  99. unit_array.mp_pre_selected_ship_recno==sprite_recno) // is selected
  100. {
  101. err_when(!auto_mode);
  102. return;
  103. }
  104. }
  105. //-------------------------------------------------------------//
  106. switch( menu_mode )
  107. {
  108. case SHIP_MENU_GOODS:
  109. disp_goods_menu(y, refreshFlag);
  110. break;
  111. case SHIP_MENU_UNIT:
  112. disp_unit_menu(y, refreshFlag);
  113. break;
  114. }
  115. }
  116. //----------- End of function UnitMarine::disp_info -----------//
  117. //--------- Begin of function UnitMarine::detect_info ---------//
  118. //
  119. void UnitMarine::detect_info()
  120. {
  121. if(!is_visible())
  122. return;
  123. if( detect_basic_info() )
  124. return;
  125. if( !is_own() )
  126. return;
  127. //----- detect switching the menu mode -----//
  128. UnitInfo* unitInfo = unit_res[unit_id];
  129. if( unitInfo->carry_unit_capacity && unitInfo->carry_goods_capacity )
  130. {
  131. int rc;
  132. if( (rc=button_mode.detect()) >= 0 )
  133. {
  134. menu_mode = rc;
  135. info.disp();
  136. return;
  137. }
  138. }
  139. if( !is_own() && !config.show_ai_info)
  140. return;
  141. //--------- detect menu mode --------//
  142. switch( menu_mode )
  143. {
  144. case SHIP_MENU_GOODS:
  145. detect_goods_menu();
  146. break;
  147. case SHIP_MENU_UNIT:
  148. detect_unit_menu();
  149. break;
  150. }
  151. //---- detect toggling auto trade mode ----//
  152. if( button_auto_trade.detect() )
  153. {
  154. if( !remote.is_enable() )
  155. {
  156. auto_mode = !auto_mode;
  157. button_auto_trade.paint_text( INFO_X1+165, INFO_Y1+57, INFO_X2-10, INFO_Y1+73, auto_mode ? (char*)"T" : (char*)"C");
  158. }
  159. else
  160. {
  161. // packet structure <unit recno> <new mode>
  162. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_U_SHIP_CHANGE_MODE, 2*sizeof(short) );
  163. *shortPtr = sprite_recno;
  164. shortPtr[1] = !auto_mode;
  165. }
  166. }
  167. }
  168. //----------- End of function UnitMarine::detect_info -----------//
  169. //-------- Begin of function UnitMarine::should_show_info ------//
  170. //
  171. int UnitMarine::should_show_info()
  172. {
  173. if( config.show_ai_info || nation_recno==nation_array.player_recno )
  174. return 1;
  175. //--- if any of the units on the ship are spies of the player ---//
  176. for( int i=0 ; i<unit_count ; i++ )
  177. {
  178. if( unit_array[ unit_recno_array[i] ]->is_own() )
  179. return 1;
  180. }
  181. return 0;
  182. }
  183. //---------- End of function UnitMarine::should_show_info --------//
  184. //--------- Begin of function UnitMarine::disp_unit_menu ---------//
  185. //
  186. void UnitMarine::disp_unit_menu(int dispY1, int refreshFlag)
  187. {
  188. disp_unit_list(dispY1 , refreshFlag);
  189. disp_unit_info(dispY1+90, refreshFlag);
  190. if( !is_own() )
  191. return;
  192. if( refreshFlag==INFO_REPAINT )
  193. button_unload_all.paint( INFO_X1, dispY1+165, 'A', "OUTSHIP" );
  194. if( can_unload_unit() )
  195. button_unload_all.enable();
  196. else
  197. button_unload_all.disable();
  198. // if( refreshFlag == INFO_REPAINT )
  199. // button_select_attack.paint_text( INFO_X2-50, INFO_Y1+180, INFO_X2-5, INFO_Y1+200, "0" );
  200. }
  201. //----------- End of function UnitMarine::disp_unit_menu -----------//
  202. //--------- Begin of function UnitMarine::can_unload_unit ---------//
  203. //
  204. int UnitMarine::can_unload_unit()
  205. {
  206. err_when(cur_action==SPRITE_ATTACK && (cur_x!=next_x || cur_y!=next_y));
  207. return unit_count>0 &&
  208. (cur_action==SPRITE_IDLE || cur_action==SPRITE_ATTACK) &&
  209. is_on_coast();
  210. }
  211. //----------- End of function UnitMarine::can_unload_unit -----------//
  212. //--------- Begin of function UnitMarine::detect_unit_menu ---------//
  213. //
  214. void UnitMarine::detect_unit_menu()
  215. {
  216. //------- detect clicking on the units --------//
  217. if( detect_unit_list() )
  218. disp_unit_info(unit_info_disp_y1, INFO_UPDATE);
  219. if( !is_own() )
  220. return;
  221. //----------- detect the unload all button -----------//
  222. if( button_unload_all.detect() )
  223. {
  224. unload_all_units(COMMAND_PLAYER);
  225. info.disp();
  226. // ##### begin Gilbert 25/9 ######//
  227. se_ctrl.immediate_sound("TURN_ON");
  228. // ##### end Gilbert 25/9 ######//
  229. }
  230. /*
  231. if(button_select_attack.detect())
  232. {
  233. se_ctrl.immediate_sound("TURN_ON", 100, 0);
  234. select_attack_weapon();
  235. }
  236. */
  237. }
  238. //----------- End of function UnitMarine::detect_unit_menu -----------//
  239. //--------- Begin of function UnitMarine::select_attack_weapon ---------//
  240. void UnitMarine::select_attack_weapon()
  241. {
  242. // ###### begin Gilbert 25/6 ########//
  243. if( attack_count == 0 ) // TRANSPORT can't select attack weapon
  244. return;
  245. // ###### end Gilbert 25/6 ########//
  246. char oldAttackRange = attack_info_array[0].attack_range;
  247. if(attack_mode_selected>unit_count)
  248. attack_mode_selected = 0;
  249. else
  250. {
  251. Unit *unitPtr;
  252. int found = 0;
  253. for(int i=attack_mode_selected+1; i<=unit_count; i++)
  254. {
  255. unitPtr = unit_array[unit_recno_array[i-1]];
  256. if(unitPtr->attack_count && unit_res[unitPtr->unit_id]->unit_class==UNIT_CLASS_WEAPON)
  257. {
  258. //ship_attack_info = *unit_res.get_attack_info(unit_res[unitPtr->unit_id]->first_attack);
  259. ship_attack_info = *unitPtr->attack_info_array;
  260. ship_attack_info.eqv_attack_next = 0;
  261. ship_attack_info.bullet_out_frame = unit_res.get_attack_info(unit_res[unit_id]->first_attack)->bullet_out_frame;
  262. attack_count = 1;
  263. attack_info_array = &ship_attack_info;
  264. found++;
  265. attack_mode_selected = i;
  266. //cur_action = SPRITE_READY_TO_MOVE;
  267. break;
  268. }
  269. }
  270. if(!found)
  271. attack_mode_selected = 0;
  272. }
  273. if(attack_mode_selected==0)
  274. {
  275. ship_attack_info = *unit_res.get_attack_info(unit_res[unit_id]->first_attack);
  276. attack_count = 1;
  277. attack_info_array = &ship_attack_info;
  278. }
  279. //-------- update attacking if neccessary --------//
  280. if(attack_info_array[0].attack_range<oldAttackRange)
  281. {
  282. short attackXLoc, attackYLoc, attackPara;
  283. switch(action_mode)
  284. {
  285. case ACTION_ATTACK_UNIT:
  286. attackPara = action_para;
  287. stop2();
  288. attack_unit(attackPara);
  289. break;
  290. case ACTION_ATTACK_FIRM:
  291. attackXLoc = action_x_loc;
  292. attackYLoc = action_y_loc;
  293. stop2();
  294. attack_firm(attackXLoc, attackYLoc);
  295. break;
  296. case ACTION_ATTACK_TOWN:
  297. attackXLoc = action_x_loc;
  298. attackYLoc = action_y_loc;
  299. stop2();
  300. attack_town(attackXLoc, attackYLoc);
  301. break;
  302. case ACTION_ATTACK_WALL:
  303. attackXLoc = action_x_loc;
  304. attackYLoc = action_y_loc;
  305. stop2();
  306. attack_wall(attackXLoc, attackYLoc);
  307. break;
  308. }
  309. }
  310. // button_select_attack.paint_text( INFO_X2-50, INFO_Y1+180, INFO_X2-5, INFO_Y1+200, m.format(attack_mode_selected));
  311. }
  312. //----------- End of function UnitMarine::select_attack_weapon -----------//
  313. //--------- Begin of function UnitMarine::disp_unit_list ---------//
  314. //
  315. void UnitMarine::disp_unit_list(int dispY1, int refreshFlag)
  316. {
  317. unit_disp_y1 = dispY1;
  318. //---------------- paint the panel --------------//
  319. if( refreshFlag == INFO_REPAINT )
  320. vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+88 );
  321. //------ display population composition -------//
  322. int x, y;
  323. Unit* unitPtr;
  324. static short last_unit_id_array[MAX_UNIT_IN_SHIP];
  325. if( selected_unit_id > unit_count )
  326. selected_unit_id = 0;
  327. dispY1+=4;
  328. for( int i=0 ; i<MAX_UNIT_IN_SHIP ; i++ )
  329. {
  330. x = INFO_X1+6+i%3*66;
  331. y = dispY1+i/3*28;
  332. if( i<unit_count )
  333. {
  334. unitPtr = unit_array[ unit_recno_array[i] ];
  335. if( refreshFlag==INFO_REPAINT || last_unit_id_array[i] != unitPtr->unit_id )
  336. {
  337. vga_front.d3_panel_up( x, y, x+27, y+23, 1 );
  338. // ###### begin Gilbert 17/10 ########//
  339. vga_front.put_bitmap(x+2, y+2, unit_res[unitPtr->unit_id]->get_small_icon_ptr(unitPtr->rank_id));
  340. // ###### end Gilbert 17/10 ########//
  341. }
  342. //----- highlight the selected unit -------//
  343. if( selected_unit_id == i+1 )
  344. vga_front.rect( x-2, y-2, x+29, y+25, 2, V_YELLOW );
  345. else
  346. vga_front.rect( x-2, y-2, x+29, y+25, 2, vga_front.color_up );
  347. //---------- display hit point ----------//
  348. font_san.disp(x+32, y+6, (int) unitPtr->hit_points, 1, x+61);
  349. last_unit_id_array[i] = unitPtr->unit_id;
  350. //------- set help parameters ---------//
  351. if( mouse.in_area(x, y, x+27, y+23) )
  352. help.set_unit_help( unitPtr->unit_id, unitPtr->rank_id, x, y, x+27, y+23 );
  353. }
  354. else
  355. {
  356. if( last_unit_id_array[i] != 0 )
  357. {
  358. vga.blt_buf( x-2, y-2, x+49, y+25, 0 );
  359. last_unit_id_array[i] = 0;
  360. }
  361. }
  362. }
  363. }
  364. //----------- End of function UnitMarine::disp_unit_list -----------//
  365. //--------- Begin of function UnitMarine::detect_unit_list ---------//
  366. //
  367. int UnitMarine::detect_unit_list()
  368. {
  369. //------- detect buttons on hiring firm units -------//
  370. int i, x, y;
  371. for( i=0 ; i<unit_count ; i++ )
  372. {
  373. x = INFO_X1+6+i%3*66;
  374. y = unit_disp_y1+4+i/3*28;
  375. //---------------------------------//
  376. if( mouse.press_area(x, y, x+27, y+23) ) // left click to select unit
  377. {
  378. selected_unit_id = i+1;
  379. return 1;
  380. }
  381. else if( mouse.any_click(x, y, x+27, y+23, 1) ) // 1-right button. right click to call out unit
  382. {
  383. mouse.reset_click(); // reset queued mouse click for fast single clicking
  384. unload_unit( i+1, COMMAND_PLAYER );
  385. info.disp();
  386. return 1;
  387. }
  388. }
  389. return 0;
  390. }
  391. //----------- End of function UnitMarine::detect_unit_list -----------//
  392. //--------- Begin of function UnitMarine::disp_unit_info ---------//
  393. //
  394. void UnitMarine::disp_unit_info(int dispY1, int refreshFlag)
  395. {
  396. static int lastSelected;
  397. unit_info_disp_y1 = dispY1;
  398. if( selected_unit_id > unit_count )
  399. selected_unit_id = unit_count;
  400. //---------------- paint the panel --------------//
  401. if( refreshFlag == INFO_REPAINT )
  402. {
  403. vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+71 );
  404. }
  405. else
  406. {
  407. if( lastSelected != selected_unit_id > 0 )
  408. {
  409. lastSelected = selected_unit_id > 0;
  410. vga.blt_buf( INFO_X1, dispY1, INFO_X2, dispY1+71, 0 );
  411. }
  412. }
  413. //-----------------------------------------------//
  414. if( selected_unit_id > 0 )
  415. {
  416. int x=INFO_X1+4, y=dispY1+4, x1=x+100;
  417. Unit* unitPtr = unit_array[ unit_recno_array[selected_unit_id-1] ];
  418. if( unitPtr->race_id && unitPtr->rank_id != RANK_KING )
  419. info.disp_loyalty( x, y, x1, unitPtr->loyalty, unitPtr->target_loyalty, nation_recno, refreshFlag);
  420. else
  421. font_san.field( x, y, "Loyalty", x1, "N/A", INFO_X2-2, refreshFlag ); // no loyalty because it does not belong to your empire
  422. y+=16;
  423. font_san.field( x, y, "Combat", x1, unitPtr->skill.combat_level, 1, INFO_X2-2, refreshFlag);
  424. y+=16;
  425. //----------------------------------------------//
  426. String str;
  427. str = (int) unitPtr->hit_points;
  428. str += "/";
  429. str += unitPtr->max_hit_points;
  430. font_san.field( x, y, "Hit Points", x1, str, INFO_X2-2, refreshFlag);
  431. y += 16;
  432. //----------------------------------------------//
  433. if( unitPtr->skill.skill_id )
  434. {
  435. if( refreshFlag == INFO_REPAINT )
  436. font_san.field( x, y, unitPtr->skill.skill_des(), x1, unitPtr->skill.skill_level , 1, INFO_X2-2, refreshFlag );
  437. else
  438. {
  439. font_san.put( x+2, y+2, unitPtr->skill.skill_des(), 1, x1-2 );
  440. font_san.update_field( x1, y, unitPtr->skill.skill_level, 1, INFO_X2-10);
  441. }
  442. }
  443. else
  444. {
  445. if( refreshFlag == INFO_REPAINT )
  446. font_san.field( x, y, "", x1, "", INFO_X2-2, refreshFlag );
  447. else
  448. {
  449. font_san.put( x+2, y+2, "", 1, x1-2 );
  450. font_san.update_field( x1, y, "", INFO_X2-10);
  451. }
  452. }
  453. }
  454. }
  455. //----------- End of function UnitMarine::disp_unit_info -----------//
  456. //--------- Begin of function UnitMarine::disp_goods_menu ---------//
  457. //
  458. void UnitMarine::disp_goods_menu(int dispY1, int refreshFlag)
  459. {
  460. disp_stop(dispY1, refreshFlag);
  461. disp_goods(dispY1+180, refreshFlag);
  462. }
  463. //----------- End of function UnitMarine::disp_goods_menu -----------//
  464. //--------- Begin of function UnitMarine::detect_goods_menu ---------//
  465. //
  466. void UnitMarine::detect_goods_menu()
  467. {
  468. detect_stop();
  469. }
  470. //---------- End of function UnitMarine::detect_goods_menu ----------//
  471. //--------- Begin of function UnitMarine::disp_stop ---------//
  472. //
  473. void UnitMarine::disp_stop(int dispY1, int refreshFlag)
  474. {
  475. //###### begin trevor 3/10 #######//
  476. if(refreshFlag!=INFO_REPAINT && refreshFlag!=INFO_UPDATE)
  477. return;
  478. int i, x=INFO_X1, y=dispY1, needRefresh;
  479. Firm *firmPtr;
  480. static short last_firm_recno_array[MAX_STOP_FOR_CARAVAN];
  481. for(i=0 ; i<MAX_STOP_FOR_CARAVAN ; i++, y+=60)
  482. {
  483. //---- compare with the previous display and see if an update is needed ----//
  484. if( refreshFlag==INFO_REPAINT )
  485. {
  486. needRefresh = 1;
  487. }
  488. else if( last_firm_recno_array[i] != stop_array[i].firm_recno )
  489. {
  490. needRefresh = 1;
  491. }
  492. last_firm_recno_array[i] = stop_array[i].firm_recno;
  493. //----------------------------------------//
  494. if( !stop_array[i].firm_recno ||
  495. firm_array.is_deleted(stop_array[i].firm_recno) )
  496. {
  497. if( refreshFlag == INFO_REPAINT )
  498. {
  499. vga.d3_panel_up(x, y, INFO_X2, y+58);
  500. #if(defined(FRENCH))
  501. button_set_stop[i].paint_text( x+4, y+37, x+90, y+56, "Faire Escale" );
  502. #else
  503. button_set_stop[i].paint_text( x+4, y+37, x+80, y+56, "Set Stop" );
  504. #endif
  505. }
  506. }
  507. else
  508. {
  509. if( refreshFlag == INFO_REPAINT )
  510. {
  511. vga.d3_panel_up(x, y, INFO_X2, y+58);
  512. //-------- display name of the stop --------//
  513. firmPtr = firm_array[ stop_array[i].firm_recno ];
  514. nation_array[firmPtr->nation_recno]->disp_nation_color(x+4, y+4);
  515. font_san.put(x+20, y+4, firmPtr->firm_name());
  516. font_san.put(x+4, y+19, "Pick up: ");
  517. #if(defined(FRENCH))
  518. button_set_stop[i].paint_text( x+4, y+37, x+90, y+56, "Faire Escale" );
  519. #else
  520. button_set_stop[i].paint_text( x+4, y+37, x+80, y+56, "Set Stop" );
  521. #endif
  522. button_set_stop[i].set_help_code( "SSETSTOP" );
  523. #if(defined(FRENCH))
  524. button_go_stop[i].paint_text( x+94, y+37, x+180, y+56, "Voir Escale" );
  525. #else
  526. button_go_stop[i].paint_text( x+84, y+37, x+180, y+56, "View Stop" );
  527. #endif
  528. button_go_stop[i].set_help_code( "SGOSTOP" );
  529. button_cancel_stop[i].paint_text( x+184, y+37, INFO_X2-4, y+56, "X" );
  530. button_cancel_stop[i].set_help_code( "SDELSTOP" );
  531. }
  532. disp_goods_select_button(i, y+1, refreshFlag);
  533. }
  534. }
  535. //###### end trevor 3/10 #######//
  536. }
  537. //---------- End of function UnitMarine::disp_stop ----------//
  538. //------ Begin of function UnitMarine::disp_goods_select_button -------//
  539. //
  540. void UnitMarine::disp_goods_select_button(int stopNum, int dispY1, int refreshFlag)
  541. {
  542. if(refreshFlag!=INFO_REPAINT && refreshFlag!=INFO_UPDATE)
  543. return;
  544. #define SHIFT_X_OFFSET 73
  545. #define SELECT_BUTTON_WIDTH 16
  546. #define SELECT_BUTTON_HEIGHT 16
  547. ShipStop *stopPtr = &stop_array[stopNum];
  548. if(!ship_goods_num[stopNum])
  549. return;
  550. int x=INFO_X1+SHIFT_X_OFFSET, y=dispY1+1, x1;
  551. char *pickUpArray = stopPtr->pick_up_array;
  552. char isPush;
  553. //###### begin trevor 3/10 #######//
  554. for(int i=1 ;i<=MAX_PICK_UP_GOODS; ++i, pickUpArray++)
  555. {
  556. x1 = x + i*SELECT_BUTTON_WIDTH;
  557. if(button_select_enable_flag[stopNum][i])
  558. {
  559. isPush = stopPtr->pick_up_array[i-1];
  560. err_when(isPush && (stopPtr->pick_up_type==AUTO_PICK_UP || stopPtr->pick_up_type==NO_PICK_UP));
  561. button_select_array[stopNum][i].paint(x1, y, x1+SELECT_BUTTON_WIDTH,
  562. y+SELECT_BUTTON_HEIGHT, i_disp_marine_select_button, ButtonCustomPara(this, i),
  563. 0, isPush); // 0 for inelastic
  564. }
  565. else
  566. {
  567. vga.blt_buf( x1, y, x1+SELECT_BUTTON_WIDTH, y+SELECT_BUTTON_HEIGHT, 0 );
  568. }
  569. }
  570. //---------------- draw the buttons for auto_pick_up and no_pick_up -------------//
  571. if(ship_goods_num[stopNum]>1)
  572. {
  573. x1 = x;
  574. isPush = (stopPtr->pick_up_type==AUTO_PICK_UP);
  575. button_select_enable_flag[stopNum][AUTO_PICK_UP] = 1;
  576. button_select_array[stopNum][AUTO_PICK_UP].paint(x1, y, x1+SELECT_BUTTON_WIDTH,
  577. y+SELECT_BUTTON_HEIGHT, i_disp_marine_select_button, ButtonCustomPara(this, AUTO_PICK_UP),
  578. 0, isPush); // 0 for inelastic
  579. x1 = x+SELECT_BUTTON_WIDTH*NO_PICK_UP;
  580. button_select_enable_flag[stopNum][NO_PICK_UP] = 1;
  581. button_select_array[stopNum][NO_PICK_UP].paint(x1, y, x1+SELECT_BUTTON_WIDTH,
  582. y+SELECT_BUTTON_HEIGHT, i_disp_marine_select_button, ButtonCustomPara(this, NO_PICK_UP));
  583. }
  584. else
  585. {
  586. x1 = x;
  587. vga.blt_buf( x1, y, x1+SELECT_BUTTON_WIDTH, y+SELECT_BUTTON_HEIGHT, 0 );
  588. x1 = x+SELECT_BUTTON_WIDTH*NO_PICK_UP;
  589. vga.blt_buf( x1, y, x1+SELECT_BUTTON_WIDTH, y+SELECT_BUTTON_HEIGHT, 0 );
  590. }
  591. //###### end trevor 3/10 #######//
  592. }
  593. //---------- End of function UnitMarine::disp_goods_select_button ----------//
  594. //--------- Begin of function UnitMarine::detect_stop ---------//
  595. //
  596. void UnitMarine::detect_stop()
  597. {
  598. int i, x=INFO_X1, y=INFO_Y1+54+25;
  599. for( i=0 ; i<MAX_STOP_FOR_SHIP ; i++, y+=38 )
  600. {
  601. if( button_set_stop[i].detect() && is_own() )
  602. power.issue_command( COMMAND_SET_SHIP_STOP, sprite_recno, i+1 ); // i+1 - stop id., passed as a parameter of the command
  603. if(i>=stop_defined_num)
  604. continue;
  605. if(button_cancel_stop[i].detect())
  606. {
  607. if(is_visible())
  608. {
  609. del_stop(i+1, COMMAND_PLAYER);
  610. // ##### begin Gilbert 25/9 ######//
  611. se_ctrl.immediate_sound("TURN_ON");
  612. // ##### end Gilbert 25/9 ######//
  613. }
  614. }
  615. for(int b=0; b<MAX_GOODS_SELECT_BUTTON; ++b)
  616. {
  617. if(!button_select_enable_flag[i][b])
  618. continue;
  619. if(button_select_array[i][b].detect())
  620. {
  621. // ###### begin Gilbert 25/9 #######//
  622. se_ctrl.immediate_sound(
  623. button_select_array[i][b].elastic_flag || button_select_array[i][b].pushed_flag ?
  624. (char*)"TURN_ON" : (char*)"TURN_OFF");
  625. // ###### end Gilbert 25/9 #######//
  626. set_stop_pick_up(i+1, b, COMMAND_PLAYER); // b = 1 - MAX_PICK_UP_GOODS
  627. }
  628. }
  629. if( button_go_stop[i].detect() )
  630. {
  631. Firm* firmPtr = firm_array[stop_array[i].firm_recno];
  632. world.go_loc(firmPtr->center_x, firmPtr->center_y);
  633. }
  634. }
  635. }
  636. //---------- End of function UnitMarine::detect_stop ----------//
  637. //--------- Begin of function UnitMarine::set_stop_pick_up ---------//
  638. //
  639. // Set the pickup type of a specific stop of this marine.
  640. //
  641. // <int> stopId - id. of the stop. (1 - MAX_STOP_FOR_SHIP)
  642. // <int> newPickUpType - set the pickup type of the specific stop. (0 - MAX_GOODS_SELECT_BUTTON-1)
  643. // <int> remoteActoin - remote action type
  644. //
  645. void UnitMarine::set_stop_pick_up(int stopId, int newPickUpType, int remoteAction)
  646. {
  647. int remoteEnable = 0;
  648. if(remote.is_enable())
  649. {
  650. if(!remoteAction)
  651. {
  652. // packet structure : <unit recno> <stop id> <new pick_up_type>
  653. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_U_SHIP_CHANGE_GOODS, 3*sizeof(short));
  654. *shortPtr = sprite_recno;
  655. shortPtr[1] = stopId;
  656. shortPtr[2] = newPickUpType;
  657. return;
  658. }
  659. else //-------- validate remote message ----------//
  660. {
  661. //-*******************************************************-//
  662. /*char mess[255];
  663. sprintf(mess, "Change Seed !!!! \r\n");
  664. OutputDebugString(mess);
  665. Firm *firmPtr = firm_array[stop_array[stopId-1].firm_recno];
  666. switch(firmPtr->firm_id)
  667. {
  668. case FIRM_MINE:
  669. //firmPtr->sell_firm(COMMAND_AUTO);
  670. //firm_array[stop_array[0].firm_recno]->sell_firm(COMMAND_AUTO);
  671. break;
  672. case FIRM_FACTORY:
  673. break;
  674. case FIRM_MARKET:
  675. break;
  676. }
  677. update_stop_list();
  678. if(unit_array.selected_recno == sprite_recno)
  679. {
  680. if(!remote.is_enable() || nation_recno==nation_array.player_recno || config.show_ai_info)
  681. {
  682. int y=INFO_Y1+54;
  683. UnitInfo* unitInfo = unit_res[unit_id];
  684. if( unitInfo->carry_unit_capacity && unitInfo->carry_goods_capacity )
  685. y+=25;
  686. disp_stop(y, INFO_UPDATE);
  687. }
  688. }*/
  689. //-*******************************************************-//
  690. err_when(!is_visible()); // no action if the unit is invisible
  691. if(firm_array.is_deleted(stop_array[stopId-1].firm_recno))
  692. return; // firm is deleted
  693. if(stop_defined_num<stopId)
  694. return; // stop_list is updated, stop exists no more
  695. #ifdef DEBUG
  696. //-*******************************************************-//
  697. /*//char mess[255];
  698. sprintf(mess, "Change Seed : %d %d %d\r\n", stopId, newPickUpType, sprite_recno);
  699. OutputDebugString(mess);*/
  700. //-*******************************************************-//
  701. m.set_random_seed(stopId + newPickUpType*(m.random(4)+1)*10 + sprite_recno*100*m.random(100));
  702. //-*******************************************************-//
  703. /*//char mess[255];
  704. sprintf(mess, "Change Seed : %d\r\n", m.random_seed);
  705. OutputDebugString(mess);*/
  706. //-*******************************************************-//
  707. #endif
  708. }
  709. remoteEnable = 1;
  710. }
  711. switch(newPickUpType)
  712. {
  713. case AUTO_PICK_UP:
  714. if(remoteEnable)
  715. {
  716. update_ship_stop_and_goods_info_to_dummy(this);
  717. stop_array[stopId-1].mp_pick_up_set_auto(dummyShipEnableFlag[stopId-1]);
  718. }
  719. else
  720. stop_array[stopId-1].pick_up_set_auto();
  721. break;
  722. case NO_PICK_UP:
  723. if(remoteEnable)
  724. {
  725. update_ship_stop_and_goods_info_to_dummy(this);
  726. stop_array[stopId-1].mp_pick_up_set_none(dummyShipEnableFlag[stopId-1]);
  727. }
  728. else
  729. stop_array[stopId-1].pick_up_set_none();
  730. break;
  731. default:
  732. err_when(newPickUpType<PICK_UP_RAW_FIRST || newPickUpType>PICK_UP_PRODUCT_LAST);
  733. if(remoteEnable)
  734. stop_array[stopId-1].mp_pick_up_toggle(newPickUpType);
  735. else
  736. stop_array[stopId-1].pick_up_toggle(newPickUpType);
  737. break;
  738. }
  739. if( unit_array.selected_recno == sprite_recno )
  740. {
  741. if(!remote.is_enable() || nation_recno==nation_array.player_recno || config.show_ai_info)
  742. {
  743. int y=INFO_Y1+54;
  744. UnitInfo* unitInfo = unit_res[unit_id];
  745. if( unitInfo->carry_unit_capacity && unitInfo->carry_goods_capacity )
  746. y+=25;
  747. disp_stop(y, INFO_UPDATE);
  748. }
  749. }
  750. }
  751. //---------- End of function UnitMarine::set_stop_pick_up ----------//
  752. //--------- Begin of function UnitMarine::update_stop_and_goods_info ---------//
  753. void UnitMarine::update_stop_and_goods_info()
  754. {
  755. err_when(!auto_mode);
  756. update_stop_list();
  757. update_ship_stop_and_goods_info_to_dummy(this);
  758. if(sprite_recno==unit_array.selected_recno && ((nation_array.player_recno && nation_recno==nation_array.player_recno) ||
  759. config.show_ai_info))
  760. {
  761. memcpy(ship_goods_num, dummyShipGoodsNum, sizeof(char)*MAX_STOP_FOR_SHIP);
  762. memcpy(button_select_enable_flag, dummyShipEnableFlag, sizeof(char)*MAX_STOP_FOR_SHIP*MAX_GOODS_SELECT_BUTTON);
  763. }
  764. }
  765. //----------- End of function UnitMarine::update_stop_and_goods_info -----------//
  766. //--------- Begin of function UnitMarine::disp_goods ---------//
  767. //
  768. void UnitMarine::disp_goods(int dispY1, int refreshFlag)
  769. {
  770. if( refreshFlag == INFO_REPAINT )
  771. vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+42 );
  772. int x=INFO_X1+20, y=dispY1+5;
  773. String str;
  774. int i;
  775. for(i=0; i<MAX_RAW; i++, x+=60)
  776. {
  777. vga_front.d3_panel_up( x, y, x+RAW_SMALL_ICON_WIDTH+5, y+RAW_SMALL_ICON_HEIGHT+5 );
  778. raw_res.put_small_raw_icon( x+3, y+3, i+1 );
  779. font_san.disp( x+25, y+2, raw_qty_array[i], 1, x+59 );
  780. }
  781. x =INFO_X1+20;
  782. y+=19;
  783. for( i=0; i<MAX_PRODUCT; i++, x+=60)
  784. {
  785. vga_front.d3_panel_up( x, y, x+RAW_SMALL_ICON_WIDTH+5, y+RAW_SMALL_ICON_HEIGHT+5 );
  786. raw_res.put_small_product_icon( x+3, y+3, i+1 );
  787. font_san.disp( x+25, y+2, product_raw_qty_array[i], 1, x+59 );
  788. }
  789. }
  790. //---------- End of function UnitMarine::disp_goods ----------//
  791. //---------- begin static function i_disp_marine_select_button ---------------//
  792. static void i_disp_marine_select_button(ButtonCustom *button, int repaintBody)
  793. {
  794. int x1 = button->x1;
  795. int y1 = button->y1;
  796. int x2 = button->x2;
  797. int y2 = button->y2;
  798. int shift;
  799. //------------- modify x1,y1, x2,y2 to the button body ---------------//
  800. if(button->pushed_flag)
  801. {
  802. int colorDown = Vga::active_buf->color_down; // change the color of the body area to yellow to highlight the change
  803. Vga::active_buf->color_down = (char) V_YELLOW;
  804. Vga::active_buf->d3_panel_down(x1, y1, x2, y2);
  805. Vga::active_buf->color_down = (char) colorDown;
  806. x1++;
  807. y1++;
  808. shift = 2;
  809. }
  810. else
  811. {
  812. Vga::active_buf->d3_panel_up(x1, y1, x2, y2);
  813. x2--;
  814. y2--;
  815. shift = 3;
  816. }
  817. //-------------- put goods icon ---------------//
  818. int id = button->custom_para.value;
  819. char *iconName=NULL;
  820. int x = x1+shift;
  821. int y = y1+shift;
  822. if(id==AUTO_PICK_UP)
  823. {
  824. iconName = "AUTOPICK";
  825. }
  826. else if(id==NO_PICK_UP)
  827. {
  828. iconName = "NOPICK";
  829. }
  830. else if(id>=PICK_UP_RAW_FIRST && id<=PICK_UP_RAW_LAST)
  831. {
  832. raw_res.put_small_raw_icon( x, y, id-PICK_UP_RAW_FIRST+1 );
  833. }
  834. else if(id>=PICK_UP_PRODUCT_FIRST && id<=PICK_UP_PRODUCT_LAST)
  835. {
  836. raw_res.put_small_product_icon( x, y, id-PICK_UP_PRODUCT_FIRST+1 );
  837. }
  838. else
  839. err_here();
  840. if( iconName )
  841. {
  842. help.set_help( x, y, x+9, y+9, iconName );
  843. Vga::active_buf->put_bitmap_trans( x, y, image_icon.get_ptr(iconName) );
  844. }
  845. }
  846. //---------- end static function i_disp_marine_select_button ---------------//
  847. //---------- Begin of function UnitMarine::fix_attack_info ----------//
  848. void UnitMarine::fix_attack_info()
  849. {
  850. Unit::fix_attack_info();
  851. err_when( attack_mode_selected < 0 || attack_mode_selected > unit_count );
  852. if( attack_count > 0 )
  853. {
  854. err_when(attack_count > 1);
  855. if( attack_mode_selected == 0 )
  856. {
  857. ship_attack_info = *unit_res.get_attack_info(unit_res[unit_id]->first_attack);
  858. }
  859. attack_info_array = &ship_attack_info;
  860. }
  861. }
  862. //---------- End of function UnitMarine::fix_attack_info ----------//
  863. //--------- Begin of function UnitMarine::set_stop ---------//
  864. // <int> stopId - the id. of the stop
  865. // <int> stopXLoc, stopYLoc - the location of the stop
  866. //
  867. void UnitMarine::set_stop(int stopId, int stopXLoc, int stopYLoc, char remoteAction)
  868. {
  869. //-------------------------------------------------------//
  870. // check if there is a station in the given location
  871. //-------------------------------------------------------//
  872. Location *locPtr = world.get_loc(stopXLoc, stopYLoc);
  873. if(!locPtr->is_firm())
  874. return;
  875. Firm *firmPtr = firm_array[locPtr->firm_recno()];
  876. if( !can_set_stop( firmPtr->firm_recno ) )
  877. return;
  878. //-------------------------------------------------------//
  879. // return if the harbor stop is in another territory
  880. //-------------------------------------------------------//
  881. FirmHarbor *harborPtr = (FirmHarbor*) firmPtr;
  882. if(world.get_loc(next_x_loc(), next_y_loc())->region_id!=harborPtr->sea_region_id)
  883. return;
  884. //-----------------------------------------//
  885. if(!remoteAction && remote.is_enable())
  886. {
  887. // packet structure : <unit recno> <stop id> <stop x> <stop y>
  888. short *shortPtr = (short *) remote.new_send_queue_msg(MSG_U_SHIP_SET_STOP, 4*sizeof(short));
  889. *shortPtr = sprite_recno;
  890. shortPtr[1] = stopId;
  891. shortPtr[2] = stopXLoc;
  892. shortPtr[3] = stopYLoc;
  893. return;
  894. }
  895. if(!stop_array[stopId-1].firm_recno)
  896. stop_defined_num++; // no plus one if the recno is defined originally
  897. //-------------------------------------------------------//
  898. // set the station recno of the stop
  899. //-------------------------------------------------------//
  900. ShipStop *stopPtr = stop_array + stopId - 1;
  901. if(stopPtr->firm_recno==firmPtr->firm_recno)
  902. {
  903. err_when(stopPtr->firm_loc_x1!=firmPtr->loc_x1 || stopPtr->firm_loc_y1!=firmPtr->loc_y1);
  904. return; // same stop as before
  905. }
  906. memset(button_select_enable_flag[stopId-1], 0, sizeof(char)*MAX_GOODS_SELECT_BUTTON);
  907. ship_goods_num[stopId-1] = 0;
  908. short oldStopFirmRecno = dest_stop_id ? stop_array[dest_stop_id-1].firm_recno : 0;
  909. stopPtr->firm_recno = firmPtr->firm_recno;
  910. stopPtr->firm_loc_x1 = firmPtr->loc_x1;
  911. stopPtr->firm_loc_y1 = firmPtr->loc_y1;
  912. stopPtr->pick_up_set_auto();
  913. //-------------------------------------------------------//
  914. // remove duplicate stop or stop change nation
  915. //-------------------------------------------------------//
  916. update_stop_list();
  917. if(dest_stop_id)
  918. {
  919. short newStopFirmRecno;
  920. err_when(firm_array.is_deleted(stop_array[dest_stop_id-1].firm_recno));
  921. if((newStopFirmRecno=stop_array[dest_stop_id-1].firm_recno) != oldStopFirmRecno)
  922. {
  923. firmPtr = firm_array[newStopFirmRecno];
  924. err_when(firmPtr->firm_id!=FIRM_HARBOR);
  925. move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, FIRM_HARBOR);
  926. journey_status = ON_WAY_TO_FIRM;
  927. }
  928. }
  929. else
  930. stop2();
  931. //-------------------------------------------------------//
  932. // refresh stop info area
  933. //-------------------------------------------------------//
  934. if(unit_array.selected_recno==sprite_recno)
  935. {
  936. if(!remote.is_enable() || nation_recno==nation_array.player_recno || config.show_ai_info)
  937. info.disp();
  938. }
  939. }
  940. //---------- End of function UnitMarine::set_stop ----------//