OFIRMIF2.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  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 : OFIRMIF2.CPP
  21. //Description : Firm interface functions - part 2
  22. #include <OINFO.h>
  23. #include <OVGA.h>
  24. #include <OSYS.h>
  25. #include <OSPY.h>
  26. #include <OSTR.h>
  27. #include <OHELP.h>
  28. #include <OFONT.h>
  29. #include <OMOUSE.h>
  30. #include <OVBROWIF.h>
  31. #include <OGAME.h>
  32. #include <ONATION.h>
  33. #include <OBUTT3D.h>
  34. #include <OIMGRES.h>
  35. #include <ORAWRES.h>
  36. #include <ORACERES.h>
  37. #include <OWORLD.h>
  38. #include <OUNIT.h>
  39. #include <OFIRM.h>
  40. #include <OREMOTE.h>
  41. //------------- Define coordinations -----------//
  42. enum { SPY_BROWSE_X1 = INFO_X1,
  43. SPY_BROWSE_Y1 = INFO_Y1+75,
  44. SPY_BROWSE_X2 = INFO_X2,
  45. SPY_BROWSE_Y2 = SPY_BROWSE_Y1+130,
  46. };
  47. enum { BUTTON_X1 = INFO_X1,
  48. BUTTON_Y1 = SPY_BROWSE_Y2+28,
  49. BUTTON_X2 = INFO_X2,
  50. BUTTON_Y2 = BUTTON_Y1+50,
  51. };
  52. //----------- Define static variables ----------//
  53. static VBrowseIF browse_spy;
  54. static Button3D button_spy_menu, button_spy_mobilize, button_spy_action, button_spy_reward,
  55. button_bribe, button_assassinate, button_capture, button_view_secret, button_cancel;
  56. static Firm* firm_ptr;
  57. //----------- Define static functions ----------//
  58. static int spy_filter(int recNo=0);
  59. static void put_spy_rec(int recNo, int x, int y, int refreshFlag);
  60. static int get_player_spy_recno(int firmRecno);
  61. //--------- Begin of function Firm::disp_spy_menu ---------//
  62. //
  63. void Firm::disp_spy_menu(int refreshFlag)
  64. {
  65. static int lastSpyCount;
  66. firm_ptr = this;
  67. disp_basic_info(INFO_Y1, refreshFlag);
  68. //---------- paint controls -----------//
  69. if( refreshFlag == INFO_REPAINT )
  70. {
  71. //------ display browser field description -------//
  72. int x=SPY_BROWSE_X1+2;
  73. int y=SPY_BROWSE_Y1-23;
  74. vga.d3_panel_up( SPY_BROWSE_X1, y, SPY_BROWSE_X2, SPY_BROWSE_Y1-3 );
  75. font_san.put( x+4 , y+4, "Spy Skill" );
  76. font_san.put( x+70 , y+4, "Loyalty" );
  77. font_san.put( x+130, y+4, "Action" );
  78. //------------ create browser ------------//
  79. browse_spy.init( SPY_BROWSE_X1, SPY_BROWSE_Y1, SPY_BROWSE_X2, SPY_BROWSE_Y2,
  80. 0, 25, player_spy_count, put_spy_rec );
  81. browse_spy.open(1);
  82. lastSpyCount = player_spy_count;
  83. err_when( player_spy_count != spy_filter() );
  84. }
  85. else
  86. {
  87. //---------- update controls -----------//
  88. if( player_spy_count != lastSpyCount )
  89. {
  90. lastSpyCount = player_spy_count;
  91. info.disp();
  92. return;
  93. }
  94. else
  95. browse_spy.update();
  96. }
  97. if( spy_filter()==0 )
  98. return;
  99. //----------- create the paint button ----------//
  100. if( refreshFlag == INFO_REPAINT )
  101. {
  102. int x=BUTTON_X1;
  103. int y=SPY_BROWSE_Y2+5;
  104. //--------- spy menu mode -----------//
  105. if( firm_menu_mode == FIRM_MENU_SPY )
  106. {
  107. //--------- mobilize spy button --------//
  108. button_spy_mobilize.paint( x, y, 'A', "MOBILSPY" );
  109. x+=BUTTON_ACTION_WIDTH;
  110. //--------- reward spy button --------//
  111. button_spy_reward.paint( x, y, 'A', "REWARD" );
  112. x+=BUTTON_ACTION_WIDTH;
  113. //------ change spy action button ------//
  114. if( firm_id != FIRM_INN && nation_recno != nation_array.player_recno ) // cannot change action in inns
  115. {
  116. button_spy_action.paint( x, y, 'A', "SPYCHACT" );
  117. x+=BUTTON_ACTION_WIDTH;
  118. }
  119. else
  120. button_spy_action.reset();
  121. //---------- capture button -----------//
  122. if( can_player_spy_capture() )
  123. {
  124. button_capture.paint( x, y, 'A', "SPYCAPT" );
  125. x+=BUTTON_ACTION_WIDTH;
  126. if( x+BUTTON_ACTION_WIDTH-5 > INFO_X2 )
  127. {
  128. x = BUTTON_X1;
  129. y += BUTTON_ACTION_HEIGHT;
  130. }
  131. }
  132. else
  133. button_capture.reset();
  134. //---------- view secret button -----------//
  135. if( nation_recno && nation_recno != nation_array.player_recno )
  136. {
  137. button_view_secret.paint( x, y, 'A', "VSECRET" );
  138. x+=BUTTON_ACTION_WIDTH;
  139. if( x+BUTTON_ACTION_WIDTH-5 > INFO_X2 )
  140. {
  141. x = BUTTON_X1;
  142. y += BUTTON_ACTION_HEIGHT;
  143. }
  144. }
  145. else
  146. button_view_secret.reset();
  147. //---------- assassination button -----------//
  148. if( nation_recno && nation_recno != nation_array.player_recno &&
  149. firm_res[firm_id]->need_overseer )
  150. {
  151. button_assassinate.paint( x, y, 'A', "ASSASSIN" );
  152. x+=BUTTON_ACTION_WIDTH;
  153. if( x+BUTTON_ACTION_WIDTH-5 > INFO_X2 )
  154. {
  155. x = BUTTON_X1;
  156. y += BUTTON_ACTION_HEIGHT;
  157. }
  158. }
  159. else
  160. button_assassinate.reset();
  161. }
  162. //--------- select briber mode --------//
  163. else if( firm_menu_mode == FIRM_MENU_SELECT_BRIBER )
  164. {
  165. button_bribe.paint( x, y, 'A', "BRIBE" );
  166. x+=BUTTON_ACTION_WIDTH;
  167. }
  168. else
  169. err_here();
  170. //----------- cancel button -----------//
  171. button_cancel.paint( x, y, 'A', "PREVMENU" );
  172. }
  173. //---- enable/disable view secret button ----//
  174. //### begin alex 20/3 ###//
  175. if( button_view_secret.init_flag && firm_menu_mode==FIRM_MENU_SPY)
  176. //#### end alex 20/3 ####//
  177. {
  178. Spy* spyPtr = spy_array[ spy_filter( browse_spy.recno() ) ];
  179. if( spyPtr->spy_skill >= MIN_VIEW_SECRET_SPYING_SKILL )
  180. button_view_secret.enable();
  181. else
  182. button_view_secret.disable();
  183. }
  184. //---- enable/disable assassinate button ----//
  185. if( button_assassinate.init_flag )
  186. {
  187. if( overseer_recno &&
  188. unit_array[overseer_recno]->true_nation_recno() != nation_array.player_recno ) // don't assassinate your own spy
  189. {
  190. button_assassinate.enable();
  191. }
  192. else
  193. {
  194. button_assassinate.disable();
  195. }
  196. }
  197. }
  198. //----------- End of function Firm::disp_spy_menu -----------//
  199. //--------- Begin of function Firm::can_player_spy_capture ---------//
  200. //
  201. // return: <int> 0 - if the player can't capture this firm
  202. // >0 - the recno of the player's spy who can capture this
  203. // firm.
  204. //
  205. int Firm::can_player_spy_capture()
  206. {
  207. if( nation_recno == nation_array.player_recno ) // this is the player's own firm.
  208. return 0;
  209. firm_ptr = this;
  210. if( spy_filter()==0 )
  211. return 0;
  212. //---- if the overseer is one of the player's spies -----//
  213. if( firm_res[firm_id]->need_overseer )
  214. {
  215. if( overseer_recno )
  216. {
  217. int spyRecno = unit_array[overseer_recno]->spy_recno;
  218. if( spyRecno )
  219. {
  220. if( spy_array[spyRecno]->true_nation_recno == nation_array.player_recno )
  221. {
  222. return spyRecno;
  223. }
  224. }
  225. }
  226. }
  227. //-- if there are no other units in the firm beside the player's spy unit --//
  228. else
  229. {
  230. if( worker_count == player_spy_count )
  231. {
  232. return spy_filter( browse_spy.recno() );
  233. }
  234. }
  235. return 0;
  236. }
  237. //----------- End of function Firm::can_player_spy_capture -----------//
  238. //--------- Begin of function Firm::detect_spy_menu ---------//
  239. //
  240. void Firm::detect_spy_menu()
  241. {
  242. firm_ptr = this;
  243. if( spy_filter()==0 )
  244. return;
  245. browse_spy.detect();
  246. Spy* spyPtr = spy_array[ spy_filter( browse_spy.recno() ) ];
  247. //--------- detect buttons --------//
  248. //--------- spy menu mode -----------//
  249. if( firm_menu_mode == FIRM_MENU_SPY )
  250. {
  251. //------ mobilize spy ---------//
  252. if( button_spy_mobilize.detect() )
  253. {
  254. if( !remote.is_enable() )
  255. {
  256. if( spyPtr->mobilize_firm_spy() )
  257. {
  258. spyPtr->notify_cloaked_nation_flag = 0; // reset it so the player can control it
  259. info.disp();
  260. return;
  261. }
  262. }
  263. else
  264. {
  265. // packet structure <spy recno>
  266. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_SPY_LEAVE_FIRM, sizeof(short) );
  267. *shortPtr = spyPtr->spy_recno;
  268. }
  269. }
  270. //------ reward spy ---------//
  271. else if( button_spy_reward.detect() )
  272. {
  273. spyPtr->reward(COMMAND_PLAYER);
  274. }
  275. //------- change spy action ---------//
  276. else if( button_spy_action.detect() ) // set action mode
  277. {
  278. if( !remote.is_enable() )
  279. {
  280. spyPtr->set_next_action_mode();
  281. disp_spy_menu( INFO_UPDATE );
  282. }
  283. else
  284. {
  285. // packet structure <spy recno>
  286. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_SPY_CYCLE_ACTION, sizeof(short) );
  287. *shortPtr = spyPtr->spy_recno;
  288. }
  289. }
  290. //------ capture firm ---------//
  291. else if( button_capture.detect() )
  292. {
  293. int spyRecno = can_player_spy_capture();
  294. if( spyRecno )
  295. {
  296. Spy* capturerSpy = spy_array[spyRecno];
  297. if( !remote.is_enable() )
  298. {
  299. capturerSpy->capture_firm();
  300. }
  301. else
  302. {
  303. // packet structure <spy recno>
  304. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_SPY_CAPTURE_FIRM, sizeof(short) );
  305. *shortPtr = capturerSpy->spy_recno;
  306. }
  307. }
  308. }
  309. //------ view secret ---------//
  310. else if( button_view_secret.detect() )
  311. {
  312. action_spy_recno = spyPtr->spy_recno;
  313. firm_menu_mode = FIRM_MENU_VIEW_SECRET;
  314. info.disp();
  315. }
  316. //-------- assassinate ------//
  317. else if( button_assassinate.detect() )
  318. {
  319. spyPtr->assassinate( overseer_recno, COMMAND_PLAYER );
  320. }
  321. }
  322. //--------- select briber mode --------//
  323. else if( firm_menu_mode == FIRM_MENU_SELECT_BRIBER )
  324. {
  325. if( button_bribe.detect() )
  326. {
  327. action_spy_recno = spyPtr->spy_recno;
  328. firm_menu_mode = FIRM_MENU_SET_BRIBE_AMOUNT;
  329. info.disp();
  330. }
  331. }
  332. else
  333. {
  334. err_here();
  335. }
  336. //--------- detect cancel button --------//
  337. if( button_cancel.detect() )
  338. {
  339. firm_menu_mode = FIRM_MENU_MAIN;
  340. info.disp();
  341. }
  342. }
  343. //----------- End of function Firm::detect_spy_menu -----------//
  344. //--------- Begin of function spy_filter ---------//
  345. //
  346. static int spy_filter(int recNo)
  347. {
  348. Spy* spyPtr;
  349. int curFirmRecno = firm_ptr->firm_recno;
  350. int recCount=0;
  351. for( int i=spy_array.size() ; i>=1 ; i-- )
  352. {
  353. if( spy_array.is_deleted(i) )
  354. continue;
  355. spyPtr = spy_array[i];
  356. if( spyPtr->spy_place==SPY_FIRM &&
  357. spyPtr->spy_place_para==curFirmRecno &&
  358. spyPtr->true_nation_recno==nation_array.player_recno )
  359. {
  360. recCount++;
  361. }
  362. if( recNo && recCount==recNo )
  363. return i;
  364. }
  365. err_when( recNo );
  366. return recCount;
  367. }
  368. //----------- End of function spy_filter -----------//
  369. //-------- Begin of static function put_spy_rec --------//
  370. //
  371. static void put_spy_rec(int recNo, int x, int y, int refreshFlag)
  372. {
  373. int x2 = x+browse_spy.rec_width-1;
  374. //-------- display icon of the spy unit -----//
  375. Spy* spyPtr = spy_array[ spy_filter(recNo) ];
  376. //-------- get the rank of the spy --------//
  377. int unitId = race_res[spyPtr->race_id]->basic_unit_id;
  378. int rankId = RANK_SOLDIER;
  379. if( spyPtr->spy_place == SPY_FIRM )
  380. {
  381. int unitRecno = firm_array[spyPtr->spy_place_para]->overseer_recno;
  382. if( unitRecno && unit_array[unitRecno]->spy_recno == spyPtr->spy_recno )
  383. rankId = RANK_GENERAL;
  384. }
  385. //---------- display unit icon ---------//
  386. if( refreshFlag == INFO_REPAINT )
  387. {
  388. vga.d3_panel_down(x+1, y+1, x+UNIT_SMALL_ICON_WIDTH+4, y+UNIT_SMALL_ICON_HEIGHT+4 );
  389. vga_front.put_bitmap(x+3, y+3, unit_res[unitId]->get_small_icon_ptr(rankId) );
  390. }
  391. //--------- set help parameters --------//
  392. if( mouse.in_area(x+1, y+1, x+RACE_ICON_WIDTH+4, y+RACE_ICON_HEIGHT+4) )
  393. {
  394. help.set_unit_help( unitId, rankId, x+1, y+1, x+RACE_ICON_WIDTH+4, y+RACE_ICON_HEIGHT+4 );
  395. }
  396. //-------- display spy skill -------//
  397. font_san.put( x+40, y+6, spyPtr->spy_skill, 1, x+66 );
  398. //-------- display spy loyalty -------//
  399. font_san.put( x+67, y+6, spyPtr->spy_loyalty, 1, x+94 );
  400. //------ display the action mode of the spy ------//
  401. vga.blt_buf( x+95, y+6, x2, y+5+font_san.height(), 0 );
  402. font_san.use_max_height();
  403. font_san.center_put( x+95, y+6, x2, y+5+font_san.height(), spyPtr->action_str() );
  404. font_san.use_std_height();
  405. }
  406. //----------- End of static function put_spy_rec -----------//
  407. //--------- Begin of function Firm::disp_spy_button --------//
  408. //
  409. void Firm::disp_spy_button(int x, int y, int refreshFlag)
  410. {
  411. if( !own_firm() ) // if not own firm, there is not other button other than the spy button, so always display it left-aligned
  412. x = INFO_X1; // if own firm, the x passed will be space position on the interface already, taking into account of the other buttons on interface
  413. //-------------------------------------//
  414. if( player_spy_count > 0 )
  415. {
  416. //------------ spy menu -----------//
  417. if( refreshFlag == INFO_REPAINT )
  418. button_spy_menu.paint( x, y, 'A', "SPYMENU" );
  419. x += BUTTON_ACTION_WIDTH;
  420. //---------- bribe button -----------//
  421. if( nation_recno != nation_array.player_recno ) // only display the bribe button for non-player owned towns
  422. {
  423. int canBribe=0;
  424. if( selected_worker_id )
  425. canBribe = can_spy_bribe(selected_worker_id, nation_array.player_recno );
  426. else if( overseer_recno )
  427. canBribe = can_spy_bribe(0, nation_array.player_recno );
  428. //-------- display the bribe button -------//
  429. if( refreshFlag == INFO_REPAINT )
  430. button_bribe.paint( x, y, 'A', "SELBRIBE" );
  431. if( canBribe )
  432. button_bribe.enable();
  433. else
  434. button_bribe.disable();
  435. x += BUTTON_ACTION_WIDTH;
  436. }
  437. }
  438. //--------- capture button ----------//
  439. int canCapture = can_worker_capture(nation_array.player_recno);
  440. if( canCapture )
  441. {
  442. if( !button_capture.enable_flag || refreshFlag==INFO_REPAINT )
  443. button_capture.paint( x, y, 'A', "CAPTURE" );
  444. }
  445. else
  446. {
  447. if( refreshFlag==INFO_REPAINT )
  448. button_capture.reset();
  449. else if( button_capture.enable_flag )
  450. button_capture.hide();
  451. }
  452. }
  453. //--------- End of function Firm::disp_spy_button --------//
  454. //--------- Begin of function Firm::detect_spy_button --------//
  455. void Firm::detect_spy_button()
  456. {
  457. if( player_spy_count>0 )
  458. {
  459. if( button_spy_menu.detect() )
  460. {
  461. firm_menu_mode = FIRM_MENU_SPY;
  462. info.disp();
  463. }
  464. if( nation_recno != nation_array.player_recno ) // only display the bribe button for non-player towns
  465. {
  466. if( button_bribe.detect() )
  467. {
  468. if( player_spy_count > 1 )
  469. {
  470. firm_menu_mode = FIRM_MENU_SELECT_BRIBER;
  471. }
  472. else
  473. {
  474. action_spy_recno = get_player_spy_recno(firm_recno); // the player has only one spy in this firm
  475. firm_menu_mode = FIRM_MENU_SET_BRIBE_AMOUNT;
  476. }
  477. info.disp();
  478. }
  479. }
  480. }
  481. //-----------------------------------------//
  482. if( button_capture.detect() && can_worker_capture(nation_array.player_recno) )
  483. {
  484. // ##### begin Gilbert 24/6 ##########//
  485. if( !remote.is_enable() )
  486. {
  487. capture_firm(nation_array.player_recno); // update RemoteMsg::firm_capture
  488. }
  489. else
  490. {
  491. // packet structure <firm recno> <capturer's nation recno>
  492. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_FIRM_CAPTURE, 2*sizeof(short) );
  493. *shortPtr = firm_recno;
  494. shortPtr[1] = nation_array.player_recno;
  495. }
  496. // ##### end Gilbert 24/6 ##########//
  497. }
  498. }
  499. //--------- End of function Firm::detect_spy_button --------//
  500. //--------- Begin of function get_player_spy_recno --------//
  501. //
  502. static int get_player_spy_recno(int firmRecno)
  503. {
  504. int spyCount=spy_array.size();
  505. Spy* spyPtr;
  506. for( int i=1 ; i<=spyCount ; i++ )
  507. {
  508. if( spy_array.is_deleted(i) )
  509. continue;
  510. spyPtr = spy_array[i];
  511. if( spyPtr->spy_place==SPY_FIRM &&
  512. spyPtr->spy_place_para==firmRecno &&
  513. spyPtr->true_nation_recno==nation_array.player_recno )
  514. {
  515. return i;
  516. }
  517. }
  518. return 0;
  519. }
  520. //------- End of function Firm::get_player_spy_recno ---------//
  521. //--------- Begin of function Firm::can_worker_capture --------//
  522. //
  523. // Return whether current workers of <captureNationRecno> can
  524. // capture this firm or not.
  525. //
  526. int Firm::can_worker_capture(int captureNationRecno)
  527. {
  528. if( nation_recno == captureNationRecno ) // cannot capture its own firm
  529. return 0;
  530. //----- if this firm needs an overseer, can only capture it when the overseer is the spy ---//
  531. if( firm_res[firm_id]->need_overseer )
  532. {
  533. return overseer_recno &&
  534. unit_array[overseer_recno]->true_nation_recno() == captureNationRecno;
  535. }
  536. //--- if this firm doesn't need an overseer, can capture it if all the units in the firm are the player's spies ---//
  537. Worker* workerPtr = worker_array;
  538. int captureUnitCount=0, otherUnitCount=0;
  539. for( int i=0 ; i<worker_count ; i++, workerPtr++ )
  540. {
  541. if( workerPtr->spy_recno &&
  542. spy_array[workerPtr->spy_recno]->true_nation_recno == captureNationRecno )
  543. {
  544. captureUnitCount++;
  545. continue;
  546. }
  547. if( workerPtr->town_recno )
  548. {
  549. if( town_array[ workerPtr->town_recno ]->nation_recno == captureNationRecno )
  550. captureUnitCount++;
  551. else
  552. otherUnitCount++;
  553. }
  554. else
  555. {
  556. otherUnitCount++; // must be an own unit in camps and bases if the unit is not a spy
  557. }
  558. }
  559. return captureUnitCount>0 && otherUnitCount==0;
  560. }
  561. //--------- End of function Firm::can_worker_capture --------//