OF_CAMP.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : OF_CAMP.CPP
  21. //Description : Firm Military Camp
  22. #include <OINFO.h>
  23. #include <OVGA.h>
  24. #include <ODATE.h>
  25. #include <OIMGRES.h>
  26. #include <OHELP.h>
  27. #include <OSYS.h>
  28. #include <OSTR.h>
  29. #include <OFONT.h>
  30. #include <OMOUSE.h>
  31. #include <OBUTTON.h>
  32. #include <OBUTT3D.h>
  33. #include <OPOWER.h>
  34. #include <OUNIT.h>
  35. #include <OINFO.h>
  36. #include <OGAME.h>
  37. #include <OSPY.h>
  38. #include <ONATION.h>
  39. #include <ORACERES.h>
  40. #include <OTERRAIN.h>
  41. #include <OWORLD.h>
  42. #include <OF_CAMP.h>
  43. #include <OREMOTE.h>
  44. #include <OSERES.h>
  45. #include <OSE.h>
  46. //----------- Define static vars -------------//
  47. static Button3D button_patrol, button_reward, button_defense;
  48. static Firm* cur_firm_ptr;
  49. //--------- Declare static functions ---------//
  50. static int sort_soldier_function( const void *a, const void *b );
  51. static int sort_soldier_id_function( const void *a, const void *b );
  52. static void disp_debug_info(FirmCamp* firmPtr, int refreshFlag);
  53. //--------- Begin of function FirmCamp::FirmCamp ---------//
  54. //
  55. FirmCamp::FirmCamp()
  56. {
  57. firm_skill_id = SKILL_LEADING;
  58. employ_new_worker = 1;
  59. memset(defense_array, 0, sizeof(DefenseUnit)*(MAX_WORKER+1));
  60. defend_target_recno = 0;
  61. defense_flag = 1;
  62. is_attack_camp = 0;
  63. }
  64. //----------- End of function FirmCamp::FirmCamp -----------//
  65. //--------- Begin of function FirmCamp::deinit ---------//
  66. //
  67. void FirmCamp::deinit()
  68. {
  69. int firmRecno = firm_recno; // save the firm_recno first for reset_unit_home_camp()
  70. Firm::deinit();
  71. //-------------------------------------------//
  72. int saveOverseerRecno = overseer_recno;
  73. overseer_recno = 0; // set overseer_recno to 0 when calling update_influence(), so this base is disregarded.
  74. update_influence();
  75. overseer_recno = saveOverseerRecno;
  76. clear_defense_mode();
  77. //---- reset all units whose home_camp_firm_recno is this firm ----//
  78. reset_unit_home_camp(firmRecno); // this must be called at last as Firm::deinit() will create new units.
  79. //--- if this camp is in the Nation::attack_camp_array[], remove it now ---//
  80. reset_attack_camp(firmRecno);
  81. }
  82. //----------- End of function FirmCamp::deinit -----------//
  83. //--------- Begin of function FirmCamp::reset_unit_home_camp ---------//
  84. //
  85. void FirmCamp::reset_unit_home_camp(int firmRecno)
  86. {
  87. //---- reset all units whose home_camp_firm_recno is this firm ----//
  88. Unit* unitPtr;
  89. for( int i=unit_array.size() ; i>0 ; i-- )
  90. {
  91. if( unit_array.is_deleted(i) )
  92. continue;
  93. unitPtr = unit_array[i];
  94. if( unitPtr->home_camp_firm_recno == firmRecno )
  95. unitPtr->home_camp_firm_recno = 0;
  96. }
  97. }
  98. //----------- End of function FirmCamp::reset_unit_home_camp -----------//
  99. //--------- Begin of function FirmCamp::reset_attack_camp ---------//
  100. //
  101. void FirmCamp::reset_attack_camp(int firmRecno)
  102. {
  103. //--- if this camp is in the Nation::attack_camp_array[], remove it now ---//
  104. if( firm_ai )
  105. {
  106. Nation* nationPtr = nation_array[nation_recno];
  107. for( int i=0 ; i<nationPtr->attack_camp_count ; i++ )
  108. {
  109. if( nationPtr->attack_camp_array[i].firm_recno == firmRecno )
  110. {
  111. m.del_array_rec(nationPtr->attack_camp_array, nationPtr->attack_camp_count, sizeof(AttackCamp), i+1 );
  112. nationPtr->attack_camp_count--;
  113. break;
  114. }
  115. }
  116. }
  117. }
  118. //----------- End of function FirmCamp::reset_attack_camp -----------//
  119. //--------- Begin of function FirmCamp::clear_defense_mode ---------//
  120. void FirmCamp::clear_defense_mode()
  121. {
  122. //------------------------------------------------------------------//
  123. // change defense unit's to non-defense mode
  124. //------------------------------------------------------------------//
  125. Unit *unitPtr;
  126. for(int i=unit_array.size(); i>=1; --i)
  127. {
  128. if(unit_array.is_deleted(i))
  129. continue;
  130. unitPtr = unit_array[i];
  131. if(!unitPtr)
  132. continue;
  133. err_when(unitPtr->cur_action==SPRITE_DIE || unitPtr->action_mode==ACTION_DIE || unitPtr->hit_points<=0);
  134. if(unitPtr->in_auto_defense_mode() && unitPtr->action_misc==ACTION_MISC_DEFENSE_CAMP_RECNO &&
  135. unitPtr->action_misc_para==firm_recno)
  136. unitPtr->clear_unit_defense_mode();
  137. }
  138. memset(defense_array, 0, sizeof(DefenseUnit)*(MAX_WORKER+1));
  139. }
  140. //----------- End of function FirmCamp::clear_defense_mode -----------//
  141. //--------- Begin of function FirmCamp::assign_unit ---------//
  142. //
  143. void FirmCamp::assign_unit(int unitRecno)
  144. {
  145. Unit* unitPtr = unit_array[unitRecno];
  146. //------- if this is a construction worker -------//
  147. if( unitPtr->skill.skill_id == SKILL_CONSTRUCTION )
  148. {
  149. set_builder(unitRecno);
  150. return;
  151. }
  152. //-------- assign the unit ----------//
  153. int rankId = unit_array[unitRecno]->rank_id;
  154. if( rankId == RANK_GENERAL || rankId==RANK_KING )
  155. {
  156. assign_overseer(unitRecno);
  157. }
  158. else
  159. {
  160. assign_worker(unitRecno);
  161. }
  162. }
  163. //----------- End of function FirmCamp::assign_unit -----------//
  164. //--------- Begin of function FirmCamp::assign_overseer ---------//
  165. //
  166. void FirmCamp::assign_overseer(int overseerRecno)
  167. {
  168. //---- reset the team member count of the general ----//
  169. if( overseerRecno )
  170. {
  171. Unit* unitPtr = unit_array[overseerRecno];
  172. err_when( !unitPtr->race_id );
  173. err_when( unitPtr->rank_id != RANK_GENERAL && unitPtr->rank_id != RANK_KING );
  174. err_when( !unitPtr->team_info );
  175. unitPtr->team_info->member_count = 0;
  176. unitPtr->home_camp_firm_recno = 0;
  177. }
  178. //----- assign the overseer now -------//
  179. Firm::assign_overseer(overseerRecno);
  180. //------------- update influence -----------//
  181. update_influence();
  182. }
  183. //----------- End of function FirmCamp::assign_overseer -----------//
  184. //--------- Begin of function FirmCamp::assign_worker --------//
  185. //
  186. // Increase armed unit count of the race of the worker assigned,
  187. // as when a unit is assigned to a camp, Unit::deinit() will decrease
  188. // the counter, so we need to increase it back here.
  189. //
  190. void FirmCamp::assign_worker(int workerUnitRecno)
  191. {
  192. Firm::assign_worker(workerUnitRecno);
  193. //--- remove the unit from patrol_unit_array when it returns to the base ---//
  194. validate_patrol_unit();
  195. //-------- sort soldiers ---------//
  196. sort_soldier();
  197. }
  198. //----------- End of function FirmCamp::assign_worker --------//
  199. //------- Begin of function FirmCamp::validate_patrol_unit ---------//
  200. //
  201. void FirmCamp::validate_patrol_unit()
  202. {
  203. int unitRecno;
  204. Unit* unitPtr;
  205. err_when( patrol_unit_count > 9 );
  206. for( int i=patrol_unit_count ; i>0 ; i-- )
  207. {
  208. unitRecno = patrol_unit_array[i-1];
  209. if( unit_array.is_deleted(unitRecno) ||
  210. (unitPtr=unit_array[unitRecno])->is_visible()==0 ||
  211. unitPtr->nation_recno != nation_recno )
  212. {
  213. err_when( patrol_unit_count > 9 );
  214. m.del_array_rec( patrol_unit_array, patrol_unit_count, sizeof(patrol_unit_array[0]), i );
  215. err_when( patrol_unit_count==0 ); // it's already 0
  216. patrol_unit_count--;
  217. err_when( patrol_unit_count < 0 );
  218. err_when( patrol_unit_count > 9 );
  219. }
  220. }
  221. }
  222. //-------- End of function FirmCamp::validate_patrol_unit ---------//
  223. //------- Begin of function FirmCamp::change_nation ---------//
  224. //
  225. void FirmCamp::change_nation(int newNationRecno)
  226. {
  227. //--- update the UnitInfo vars of the workers in this firm ---//
  228. for( int i=0 ; i<worker_count ; i++ )
  229. unit_res[ worker_array[i].unit_id ]->unit_change_nation(newNationRecno, nation_recno, worker_array[i].rank_id );
  230. //----- reset unit's home camp to this firm -----//
  231. reset_unit_home_camp(firm_recno);
  232. //--- if this camp is in the Nation::attack_camp_array[], remove it now ---//
  233. reset_attack_camp(firm_recno);
  234. //---- reset AI vars --------//
  235. ai_capture_town_recno = 0;
  236. ai_recruiting_soldier = 0;
  237. //-------- change the nation of this firm now ----------//
  238. Firm::change_nation(newNationRecno);
  239. }
  240. //-------- End of function FirmCamp::change_nation ---------//
  241. //--------- Begin of function FirmCamp::update_influence ---------//
  242. //
  243. // Update this camp's influence on neighbor towns.
  244. //
  245. void FirmCamp::update_influence()
  246. {
  247. int i;
  248. Town* townPtr;
  249. for( i=0 ; i<linked_town_count ; i++ )
  250. {
  251. if(town_array.is_deleted(linked_town_array[i]))
  252. continue;
  253. townPtr = town_array[linked_town_array[i]];
  254. if( linked_town_enable_array[i] == LINK_EE )
  255. {
  256. if( townPtr->nation_recno )
  257. townPtr->update_target_loyalty();
  258. else
  259. townPtr->update_target_resistance();
  260. }
  261. }
  262. }
  263. //----------- End of function FirmCamp::update_influence -----------//
  264. //--------- Begin of function FirmCamp::put_info ---------//
  265. //
  266. void FirmCamp::put_info(int refreshFlag)
  267. {
  268. disp_basic_info(INFO_Y1, refreshFlag);
  269. if( !should_show_info() )
  270. return;
  271. disp_camp_info(INFO_Y1+54, refreshFlag);
  272. disp_worker_list(INFO_Y1+104, refreshFlag);
  273. disp_worker_info(INFO_Y1+168, refreshFlag);
  274. //------ display button -------//
  275. int x;
  276. if( own_firm() )
  277. {
  278. if( refreshFlag==INFO_REPAINT )
  279. {
  280. button_patrol.paint( INFO_X1, INFO_Y1+242, 'A', "PATROL" );
  281. button_reward.paint( INFO_X1+BUTTON_ACTION_WIDTH, INFO_Y1+242, 'A', "REWARDCB" );
  282. button_defense.paint( INFO_X2-BUTTON_ACTION_WIDTH, INFO_Y1+242, 'A', defense_flag ? (char*)"DEFENSE1" : (char*)"DEFENSE0" );
  283. }
  284. if( overseer_recno || worker_count )
  285. button_patrol.enable();
  286. else
  287. button_patrol.disable();
  288. if( nation_array[nation_recno]->cash >= REWARD_COST &&
  289. ( (overseer_recno && unit_array[overseer_recno]->rank_id != RANK_KING)
  290. || selected_worker_id ) )
  291. {
  292. button_reward.enable();
  293. }
  294. else
  295. {
  296. button_reward.disable();
  297. }
  298. x=INFO_X1+BUTTON_ACTION_WIDTH*2;
  299. }
  300. else
  301. x=INFO_X1;
  302. disp_spy_button(x, INFO_Y1+242, refreshFlag);
  303. #ifdef DEBUG
  304. if( sys.testing_session || sys.debug_session )
  305. disp_debug_info(this, refreshFlag);
  306. #endif
  307. }
  308. //----------- End of function FirmCamp::put_info -----------//
  309. //--------- Begin of function FirmCamp::detect_info ---------//
  310. //
  311. void FirmCamp::detect_info()
  312. {
  313. if( detect_basic_info() )
  314. return;
  315. if( !should_show_info() )
  316. return;
  317. //------ detect the overseer button -----//
  318. int rc = mouse.single_click(INFO_X1+6, INFO_Y1+58,
  319. INFO_X1+5+UNIT_LARGE_ICON_WIDTH, INFO_Y1+57+UNIT_LARGE_ICON_HEIGHT, 2 );
  320. if( rc==1 ) // display this overseer's info
  321. {
  322. selected_worker_id = 0;
  323. disp_camp_info(INFO_Y1+54, INFO_UPDATE);
  324. disp_worker_list(INFO_Y1+104, INFO_UPDATE);
  325. disp_worker_info(INFO_Y1+168, INFO_UPDATE);
  326. }
  327. //--------- detect soldier info ---------//
  328. if( detect_worker_list() )
  329. {
  330. disp_camp_info(INFO_Y1+54, INFO_UPDATE);
  331. disp_worker_list(INFO_Y1+104, INFO_UPDATE);
  332. disp_worker_info(INFO_Y1+168, INFO_UPDATE);
  333. }
  334. //---------- detect spy button ----------//
  335. detect_spy_button();
  336. if( !own_firm() )
  337. return;
  338. //------ detect the overseer button -----//
  339. if( rc==2 )
  340. {
  341. if(remote.is_enable())
  342. {
  343. // packet structure : <firm recno>
  344. short *shortPtr=(short *)remote.new_send_queue_msg(MSG_FIRM_MOBL_OVERSEER, sizeof(short));
  345. shortPtr[0] = firm_recno;
  346. }
  347. else
  348. {
  349. assign_overseer(0); // the overseer quits the camp
  350. }
  351. }
  352. //----------- detect patrol -----------//
  353. if( button_patrol.detect() )
  354. {
  355. if(remote.is_enable())
  356. {
  357. // packet structure : <firm recno>
  358. short *shortPtr=(short *)remote.new_send_queue_msg(MSG_F_CAMP_PATROL, sizeof(short));
  359. shortPtr[0] = firm_recno;
  360. }
  361. else
  362. {
  363. patrol();
  364. }
  365. }
  366. //----------- detect reward -----------//
  367. if( button_reward.detect() )
  368. {
  369. reward(selected_worker_id, COMMAND_PLAYER);
  370. // ##### begin Gilbert 25/9 ######//
  371. se_ctrl.immediate_sound("TURN_ON");
  372. // ##### end Gilbert 25/9 ######//
  373. }
  374. //----- detect defense mode button -------//
  375. if( button_defense.detect() )
  376. {
  377. // ##### begin Gilbert 25/9 ######//
  378. se_ctrl.immediate_sound( !defense_flag?(char*)"TURN_ON":(char*)"TURN_OFF");
  379. // ##### end Gilbert 25/9 ######//
  380. if( !remote.is_enable() )
  381. {
  382. // update RemoteMsg::toggle_camp_patrol()
  383. defense_flag = !defense_flag;
  384. }
  385. else
  386. {
  387. // packet structure : <firm recno> <defense_flag>
  388. short *shortPtr=(short *)remote.new_send_queue_msg(MSG_F_CAMP_TOGGLE_PATROL, 2*sizeof(short));
  389. shortPtr[0] = firm_recno;
  390. shortPtr[1] = !defense_flag;
  391. }
  392. button_defense.update_bitmap( defense_flag ? (char*)"DEFENSE1" : (char*)"DEFENSE0" );
  393. }
  394. }
  395. //----------- End of function FirmCamp::detect_info -----------//
  396. //--------- Begin of function FirmCamp::disp_camp_info ---------//
  397. //
  398. void FirmCamp::disp_camp_info(int dispY1, int refreshFlag)
  399. {
  400. //---------------- paint the panel --------------//
  401. if( refreshFlag == INFO_REPAINT )
  402. vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+46);
  403. if( !overseer_recno )
  404. return;
  405. //------------ display overseer info -------------//
  406. Unit* overseerUnit = unit_array[overseer_recno];
  407. int x=INFO_X1+6, y=dispY1+4, x1=x+UNIT_LARGE_ICON_WIDTH+8;
  408. if( selected_worker_id == 0 )
  409. {
  410. vga_front.rect( x-2, y-2, x+UNIT_LARGE_ICON_WIDTH+1, y+UNIT_LARGE_ICON_HEIGHT+1, 2, V_YELLOW );
  411. }
  412. else
  413. {
  414. vga.blt_buf( x-2, y-2, x+UNIT_LARGE_ICON_WIDTH+1, y-1, 0 );
  415. vga.blt_buf( x-2, y+UNIT_LARGE_ICON_HEIGHT+1, x+UNIT_LARGE_ICON_WIDTH+1, y+UNIT_LARGE_ICON_HEIGHT+2, 0 );
  416. vga.blt_buf( x-2, y-2, x-1, y+UNIT_LARGE_ICON_HEIGHT+2, 0 );
  417. vga.blt_buf( x+UNIT_LARGE_ICON_WIDTH, y-2, x+UNIT_LARGE_ICON_WIDTH+1, y+UNIT_LARGE_ICON_HEIGHT+2, 0 );
  418. }
  419. //-------------------------------------//
  420. if( refreshFlag == INFO_REPAINT )
  421. {
  422. vga_front.put_bitmap(x, y, unit_res[overseerUnit->unit_id]->get_large_icon_ptr(overseerUnit->rank_id) );
  423. }
  424. //-------- set help parameters --------//
  425. if( mouse.in_area(x, y, x+UNIT_LARGE_ICON_WIDTH+3, y+UNIT_LARGE_ICON_HEIGHT+3) )
  426. help.set_unit_help( overseerUnit->unit_id, overseerUnit->rank_id, x, y, x+UNIT_LARGE_ICON_WIDTH+3, y+UNIT_LARGE_ICON_HEIGHT+3);
  427. //-------------------------------------//
  428. if( overseerUnit->rank_id == RANK_KING )
  429. {
  430. if( refreshFlag == INFO_REPAINT )
  431. font_san.put( x1, y, "King" );
  432. y+=14;
  433. }
  434. if( refreshFlag == INFO_REPAINT )
  435. font_san.put( x1, y, overseerUnit->unit_name(0), 0, INFO_X2-2 ); // 0-ask unit_name() not to return the title of the unit
  436. y+=14;
  437. //------- display leadership -------//
  438. String str;
  439. str = translate.process("Leadership");
  440. str += ": ";
  441. str += overseerUnit->skill.get_skill(SKILL_LEADING);
  442. font_san.disp( x1, y, str, INFO_X2-10 );
  443. y+=14;
  444. //--------- display loyalty ----------//
  445. if( overseerUnit->rank_id != RANK_KING )
  446. {
  447. x1 = font_san.put( x1, y, "Loyalty:" );
  448. int x2 = info.disp_loyalty( x1, y-1, x1, overseerUnit->loyalty, overseerUnit->target_loyalty, nation_recno, refreshFlag );
  449. if( overseerUnit->spy_recno )
  450. {
  451. //------ if this is the player's spy -------//
  452. if( overseerUnit->true_nation_recno() == nation_array.player_recno )
  453. {
  454. vga_front.put_bitmap( x2+5, y+1, image_icon.get_ptr("U_SPY") );
  455. x2 += 15;
  456. }
  457. }
  458. vga.blt_buf( x2, y-1, INFO_X2-2, dispY1+44, 0 );
  459. }
  460. }
  461. //----------- End of function FirmCamp::disp_camp_info -----------//
  462. //--------- Begin of function FirmCamp::next_day ---------//
  463. //
  464. void FirmCamp::next_day()
  465. {
  466. //----- call next_day() of the base class -----//
  467. Firm::next_day();
  468. //----- update the patrol_unit_array -----//
  469. validate_patrol_unit();
  470. //--------------------------------------//
  471. if( info.game_date%15 == firm_recno%15 ) // once a week
  472. {
  473. train_unit();
  474. recover_hit_point();
  475. }
  476. //--- if there are weapons in the firm, pay for their expenses ---//
  477. pay_weapon_expense();
  478. }
  479. //----------- End of function FirmCamp::next_day -----------//
  480. //------- Begin of function FirmCamp::train_unit -------//
  481. //
  482. // Increase the leadership and ocmbat level of the general and the soldiers.
  483. //
  484. void FirmCamp::train_unit()
  485. {
  486. if( !overseer_recno )
  487. return;
  488. Unit* overseerUnit = unit_array[overseer_recno];
  489. if( overseerUnit->skill.skill_id != SKILL_LEADING )
  490. return;
  491. int overseerSkill = overseerUnit->skill.skill_level;
  492. RaceInfo* overseerRaceInfo = race_res[overseerUnit->race_id];
  493. int incValue;
  494. //------- increase the commander's leadership ---------//
  495. if( worker_count > 0 && overseerUnit->skill.skill_level < 100 )
  496. {
  497. //-- the more soldiers this commander has, the higher the leadership will increase ---//
  498. incValue = 5 * worker_count
  499. * (int) overseerUnit->hit_points / overseerUnit->max_hit_points
  500. * (100+overseerUnit->skill.skill_potential*2) / 100;
  501. overseerUnit->skill.skill_level_minor += incValue;
  502. if( overseerUnit->skill.skill_level_minor >= 100 )
  503. {
  504. overseerUnit->skill.skill_level_minor -= 100;
  505. overseerUnit->skill.skill_level++;
  506. }
  507. }
  508. //------- increase the commander's combat level ---------//
  509. if( overseerUnit->skill.combat_level < 100 )
  510. {
  511. incValue = 20 * (int) overseerUnit->hit_points / overseerUnit->max_hit_points
  512. * (100+overseerUnit->skill.skill_potential*2) / 100;
  513. overseerUnit->skill.combat_level_minor += incValue;
  514. if( overseerUnit->skill.combat_level_minor >= 100 )
  515. {
  516. overseerUnit->skill.combat_level_minor -= 100;
  517. overseerUnit->set_combat_level(overseerUnit->skill.combat_level+1);
  518. }
  519. }
  520. //------- increase the solider's combat level -------//
  521. int levelMinor;
  522. Worker* workerPtr = worker_array;
  523. for( int i=0 ; i<worker_count ; i++, workerPtr++ )
  524. {
  525. if( workerPtr->skill_id != SKILL_LEADING )
  526. continue;
  527. //------- increase worker skill -----------//
  528. if( workerPtr->combat_level < overseerSkill )
  529. {
  530. incValue = max(20, overseerSkill-workerPtr->combat_level)
  531. * workerPtr->hit_points / workerPtr->max_hit_points()
  532. * (100+workerPtr->skill_potential*2) / 100;
  533. levelMinor = workerPtr->combat_level_minor + incValue; // with random factors, resulting in 75% to 125% of the original
  534. while( levelMinor >= 100 )
  535. {
  536. levelMinor -= 100;
  537. workerPtr->combat_level++;
  538. }
  539. workerPtr->combat_level_minor = levelMinor;
  540. }
  541. //-- if the soldier has leadership potential, he learns leadership --//
  542. if( workerPtr->skill_potential > 0 && workerPtr->skill_level < 100 )
  543. {
  544. incValue = (int) max(50, overseerUnit->skill.skill_level-workerPtr->skill_level)
  545. * workerPtr->hit_points / workerPtr->max_hit_points()
  546. * workerPtr->skill_potential*2 / 100;
  547. workerPtr->skill_level_minor += incValue;
  548. err_when( workerPtr->skill_level >= 100 );
  549. if( workerPtr->skill_level_minor > 100 )
  550. {
  551. workerPtr->skill_level++;
  552. workerPtr->skill_level_minor -= 100;
  553. }
  554. }
  555. }
  556. sort_soldier();
  557. }
  558. //-------- End of function FirmCamp::train_unit --------//
  559. //------- Begin of function FirmCamp::recover_hit_point -------//
  560. //
  561. // Soldiers recover their hit points.
  562. //
  563. // No need to recover the hit points of the general here as
  564. // this is taken care in the Unit class function of the general.
  565. //
  566. void FirmCamp::recover_hit_point()
  567. {
  568. Worker* workerPtr = worker_array;
  569. for( int i=0 ; i<worker_count ; i++, workerPtr++ )
  570. {
  571. //------- increase worker hit points --------//
  572. if( workerPtr->hit_points < workerPtr->max_hit_points() )
  573. workerPtr->hit_points++;
  574. }
  575. }
  576. //------- End of function FirmCamp::recover_hit_point -------//
  577. //------- Begin of function FirmCamp::pay_weapon_expense -------//
  578. //
  579. void FirmCamp::pay_weapon_expense()
  580. {
  581. Worker* workerPtr = worker_array;
  582. Nation* nationPtr = nation_array[nation_recno];
  583. for( int i=1 ; i<=worker_count ; i++, workerPtr++ )
  584. {
  585. if( workerPtr->unit_id &&
  586. unit_res[workerPtr->unit_id]->unit_class == UNIT_CLASS_WEAPON )
  587. {
  588. if( nationPtr->cash > 0 )
  589. {
  590. nationPtr->add_expense( EXPENSE_WEAPON, (float) unit_res[workerPtr->unit_id]->year_cost / 365, 1 );
  591. }
  592. else // decrease hit points if the nation cannot pay the unit
  593. {
  594. if( workerPtr->hit_points > 0 )
  595. workerPtr->hit_points--;
  596. if( workerPtr->hit_points == 0 )
  597. kill_worker(i); // if its hit points is zero, delete it
  598. err_when( workerPtr->hit_points < 0 );
  599. }
  600. }
  601. }
  602. }
  603. //------- End of function FirmCamp::pay_weapon_expense -------//
  604. //--------- Begin of function FirmCamp::patrol ---------//
  605. //
  606. void FirmCamp::patrol()
  607. {
  608. err_when( !overseer_recno && !worker_count );
  609. err_when( firm_ai && ai_capture_town_recno ); // ai_capture_town_recno is set after patrol() is called
  610. if( nation_recno == nation_array.player_recno )
  611. power.reset_selection();
  612. //------------------------------------------------------------//
  613. // If the commander in this camp has units under his lead
  614. // outside and he is now going to lead a new team, then
  615. // the old team members should be reset.
  616. //------------------------------------------------------------//
  617. if(overseer_recno)
  618. {
  619. TeamInfo* teamInfo = unit_array[overseer_recno]->team_info;
  620. if( worker_count>0 && teamInfo->member_count>0 )
  621. {
  622. int unitRecno;
  623. for( int i=0 ; i<teamInfo->member_count ; i++ )
  624. {
  625. unitRecno = teamInfo->member_unit_array[i];
  626. if( unit_array.is_deleted(unitRecno) )
  627. continue;
  628. unit_array[unitRecno]->leader_unit_recno = 0;
  629. }
  630. }
  631. }
  632. //------------------------------------------------------------//
  633. // mobilize workers first, then the overseer.
  634. //------------------------------------------------------------//
  635. short overseerRecno = overseer_recno;
  636. if(patrol_all_soldier() && overseer_recno)
  637. {
  638. Unit* unitPtr = unit_array[overseer_recno];
  639. err_when(unitPtr->rank_id!=RANK_GENERAL && unitPtr->rank_id!=RANK_KING);
  640. unitPtr->team_id = unit_array.cur_team_id-1; // set it to the same team as the soldiers which are defined in mobilize_all_worker()
  641. if( nation_recno == nation_array.player_recno )
  642. {
  643. unitPtr->selected_flag = 1;
  644. unit_array.selected_recno = overseer_recno;
  645. unit_array.selected_count++;
  646. }
  647. }
  648. assign_overseer(0);
  649. //---------------------------------------------------//
  650. if(overseerRecno && !overseer_recno) // has overseer and the overseer is mobilized
  651. {
  652. Unit* overseerUnit = unit_array[overseerRecno];
  653. if(overseerUnit->is_own() )
  654. {
  655. se_res.sound( overseerUnit->cur_x_loc(), overseerUnit->cur_y_loc(), 1,
  656. 'S', overseerUnit->sprite_id, "SEL");
  657. }
  658. err_when( patrol_unit_count > MAX_WORKER );
  659. //--- add the overseer into the patrol_unit_array[] of this camp ---//
  660. patrol_unit_array[patrol_unit_count++] = overseerRecno;
  661. err_when( patrol_unit_count > 9 );
  662. //------- set the team_info of the overseer -------//
  663. err_when( !overseerUnit->team_info );
  664. for( int i=0 ; i<patrol_unit_count ; i++ )
  665. overseerUnit->team_info->member_unit_array[i] = patrol_unit_array[i];
  666. overseerUnit->team_info->member_count = patrol_unit_count;
  667. }
  668. //-------- display info --------//
  669. if( nation_recno == nation_array.player_recno ) // for player's camp, patrol() can only be called when the player presses the button.
  670. info.disp();
  671. err_when( patrol_unit_count < 0 );
  672. err_when( patrol_unit_count > 9 );
  673. }
  674. //----------- End of function FirmCamp::patrol -----------//
  675. //--------- Begin of function FirmCamp::patrol_all_soldier ---------//
  676. //
  677. // return 1 if there is enough space for patroling all soldiers
  678. // return 0 otherwise
  679. //
  680. int FirmCamp::patrol_all_soldier()
  681. {
  682. err_when(!worker_array); // this function shouldn't be called if this firm does not need worker
  683. //------- detect buttons on hiring firm workers -------//
  684. err_when(worker_count>MAX_WORKER);
  685. #ifdef DEBUG
  686. int loopCount=0;
  687. #endif
  688. short unitRecno;
  689. int mobileWorkerId = 1;
  690. patrol_unit_count = 0; // reset it, it will be increased later
  691. while(worker_count>0 && mobileWorkerId<=worker_count)
  692. {
  693. err_when(++loopCount > 100);
  694. if(worker_array[mobileWorkerId-1].skill_id==SKILL_LEADING)
  695. {
  696. unitRecno = mobilize_worker(mobileWorkerId, COMMAND_AUTO);
  697. patrol_unit_array[patrol_unit_count++] = unitRecno;
  698. err_when(patrol_unit_count>MAX_WORKER);
  699. }
  700. else
  701. {
  702. mobileWorkerId++;
  703. continue;
  704. }
  705. if(!unitRecno)
  706. return 0; // keep the rest workers as there is no space for creating the unit
  707. if(overseer_recno)
  708. {
  709. Unit* unitPtr = unit_array[unitRecno];
  710. unitPtr->team_id = unit_array.cur_team_id; // define it as a team
  711. unitPtr->leader_unit_recno = overseer_recno;
  712. unitPtr->update_loyalty(); // the unit is just assigned to a new leader, set its target loyalty
  713. err_when( unit_array[overseer_recno]->rank_id != RANK_KING &&
  714. unit_array[overseer_recno]->rank_id != RANK_GENERAL );
  715. if( nation_recno == nation_array.player_recno )
  716. {
  717. unitPtr->selected_flag = 1;
  718. unit_array.selected_count++;
  719. }
  720. }
  721. }
  722. unit_array.cur_team_id++;
  723. return 1;
  724. }
  725. //----------- End of function FirmCamp::patrol_all_soldier -----------//
  726. //--------- Begin of function FirmCamp::mobilize_overseer --------//
  727. //
  728. int FirmCamp::mobilize_overseer()
  729. {
  730. int unitRecno = Firm::mobilize_overseer();
  731. //--- set the home camp firm recno of the unit for later return ---//
  732. if( unitRecno )
  733. {
  734. unit_array[unitRecno]->home_camp_firm_recno = firm_recno;
  735. return unitRecno;
  736. }
  737. else
  738. return 0;
  739. }
  740. //----------- End of function FirmCamp::mobilize_overseer --------//
  741. //--------- Begin of function FirmCamp::mobilize_worker ---------//
  742. //
  743. int FirmCamp::mobilize_worker(int workerId, char remoteAction)
  744. {
  745. int unitRecno = Firm::mobilize_worker(workerId, remoteAction);
  746. //--- set the home camp firm recno of the unit for later return ---//
  747. if( unitRecno )
  748. {
  749. unit_array[unitRecno]->home_camp_firm_recno = firm_recno;
  750. return unitRecno;
  751. }
  752. else
  753. return 0;
  754. }
  755. //----------- End of function FirmCamp::mobilize_worker -----------//
  756. //--------- Begin of function FirmCamp::defense ---------//
  757. //### begin alex 15/10 ###//
  758. //void FirmCamp::defense(short targetRecno)
  759. void FirmCamp::defense(short targetRecno, int useRangeAttack)
  760. //#### end alex 15/10 ####//
  761. {
  762. //### begin alex 15/10 ###//
  763. //--******* BUGHERE , please provide a reasonable condition to set useRangeAttack to 1
  764. if(unit_array[targetRecno]->mobile_type!=UNIT_LAND)
  765. useRangeAttack = 1;
  766. else
  767. useRangeAttack = 0;
  768. //#### end alex 15/10 ####//
  769. if( !defense_flag )
  770. return;
  771. //--------------- define parameters ------------------//
  772. DefenseUnit *defPtr, *defPtr2;
  773. Unit *unitPtr;
  774. short unitRecno;
  775. int numOfUnitInside = worker_count + (overseer_recno>0);
  776. int i, j;
  777. if(employ_new_worker)
  778. {
  779. //---------- reset unit's parameters in the previous defense -----------//
  780. defPtr = defense_array;
  781. for(int i=0; i<=MAX_WORKER; i++, defPtr++)
  782. {
  783. if(defPtr->status==OUTSIDE_CAMP && defPtr->unit_recno && !unit_array.is_deleted(defPtr->unit_recno))
  784. {
  785. unitPtr = unit_array[defPtr->unit_recno];
  786. if(unitPtr->nation_recno==nation_recno && unitPtr->action_misc==ACTION_MISC_DEFENSE_CAMP_RECNO &&
  787. unitPtr->action_misc_para==firm_recno)
  788. {
  789. unitPtr->clear_unit_defense_mode();
  790. err_when(unitPtr->in_auto_defense_mode());
  791. }
  792. }
  793. }
  794. memset(defense_array, 0, sizeof(DefenseUnit)*(MAX_WORKER+1));
  795. }
  796. //------------------------------------------------------------------//
  797. // check all the exist(not dead) units outside the camp and arrange
  798. // them in the front part of the array.
  799. //------------------------------------------------------------------//
  800. j = 0;
  801. defPtr2 = defense_array;
  802. if(!employ_new_worker) // some soliders may be outside the camp
  803. {
  804. for(i=0, defPtr=defense_array; i<=MAX_WORKER; i++, defPtr++)
  805. {
  806. if(!defPtr->unit_recno)
  807. continue; // a free slot
  808. if(unit_array.is_deleted(defPtr->unit_recno))
  809. {
  810. defPtr->unit_recno = 0;
  811. continue; // unit is dead
  812. }
  813. //----------------------------------------------------------------//
  814. // arrange the recno in the array front part
  815. //----------------------------------------------------------------//
  816. if(defPtr->status==OUTSIDE_CAMP)
  817. {
  818. unitPtr = unit_array[defPtr->unit_recno];
  819. //-------------- ignore this unit if it is dead --------------------//
  820. if(unitPtr->is_unit_dead())
  821. continue;
  822. if(!unitPtr->in_auto_defense_mode())
  823. continue; // the unit is ordered by the player to do other thing, so cannot control it afterwards
  824. //--------------- the unit is in defense mode ----------------//
  825. defPtr2->unit_recno = defPtr->unit_recno;
  826. defPtr2->status = OUTSIDE_CAMP;
  827. j++;
  828. defPtr2++;
  829. }
  830. }
  831. err_when(defPtr2 + (MAX_WORKER-j+1) > defense_array + MAX_WORKER + 1);
  832. memset(defPtr2, 0, sizeof(DefenseUnit)*(MAX_WORKER-j+1));
  833. }
  834. set_employ_worker(0);
  835. //------------------------------------------------------------------//
  836. // the unit outside the camp should be in defense mode and ready to
  837. // attack new target
  838. //------------------------------------------------------------------//
  839. for(i=0, defPtr=defense_array; i<j; i++, defPtr++)
  840. {
  841. //------------------------------------------------------------------//
  842. // order those unit outside the camp to attack the target
  843. //------------------------------------------------------------------//
  844. unitPtr = unit_array[defPtr->unit_recno];
  845. defense_outside_camp(defPtr->unit_recno, targetRecno);
  846. unitPtr->action_misc = ACTION_MISC_DEFENSE_CAMP_RECNO;
  847. unitPtr->action_misc_para = firm_recno;
  848. }
  849. int mobilizePos = 0;
  850. //### begin alex 13/10 ###//
  851. //for(; i<MAX_WORKER && worker_count; i++, defPtr++)
  852. for(; i<MAX_WORKER && mobilizePos<worker_count; i++, defPtr++)
  853. //#### end alex 13/10 ####//
  854. {
  855. err_when(mobilizePos >= worker_count);
  856. //------------------------------------------------------------------//
  857. // order those soldier inside the firm to move to target for attacking
  858. // keep those unable to attack inside the firm
  859. //------------------------------------------------------------------//
  860. //### begin alex 13/10 ###//
  861. //if(worker_array[mobilizePos].unit_id==UNIT_EXPLOSIVE_CART)
  862. if(worker_array[mobilizePos].unit_id==UNIT_EXPLOSIVE_CART ||
  863. (useRangeAttack && worker_array[mobilizePos].max_attack_range()==1))
  864. //#### end alex 13/10 ####//
  865. {
  866. mobilizePos++;
  867. continue;
  868. }
  869. unitRecno = mobilize_worker(mobilizePos+1, COMMAND_AUTO);
  870. //unitRecno = mobilize_worker(1, COMMAND_AUTO); // always record 1 as the workers info are moved forward from the back to the front
  871. if(!unitRecno)
  872. break;
  873. Unit* unitPtr = unit_array[unitRecno];
  874. unitPtr->team_id = unit_array.cur_team_id; // define it as a team
  875. unitPtr->action_misc = ACTION_MISC_DEFENSE_CAMP_RECNO;
  876. unitPtr->action_misc_para = firm_recno; // store the firm_recno for going back camp
  877. defense_inside_camp(unitRecno, targetRecno);
  878. defPtr->unit_recno = unitRecno;
  879. defPtr->status = OUTSIDE_CAMP;
  880. }
  881. /*if(overseer_recno>0)
  882. {
  883. //------------------------------------------------------------------//
  884. // order those overseer inside the firm to move to target for attacking
  885. //------------------------------------------------------------------//
  886. unitPtr = unit_array[overseer_recno];
  887. assign_overseer(0);
  888. unitPtr->team_id = unit_array.cur_team_id; // define it as a team
  889. unitPtr->action_misc = ACTION_MISC_DEFENSE_CAMP_RECNO;
  890. unitPtr->action_misc_para = firm_recno; // store the firm_recno for going back camp
  891. defense_inside_camp(unitPtr->sprite_recno, targetRecno);
  892. defPtr->unit_recno = unitPtr->sprite_recno;
  893. defPtr->status = OUTSIDE_CAMP;
  894. }*/
  895. unit_array.cur_team_id++;
  896. }
  897. //----------- End of function FirmCamp::defense -----------//
  898. //--------- Begin of function FirmCamp::defense_inside_camp ---------//
  899. void FirmCamp::defense_inside_camp(short unitRecno, short targetRecno)
  900. {
  901. Unit *unitPtr = unit_array[unitRecno];
  902. unitPtr->defense_attack_unit(targetRecno);
  903. // err_when(unitPtr->action_mode2!=ACTION_AUTO_DEFENSE_ATTACK_TARGET);
  904. if(unitPtr->action_mode==ACTION_STOP && !unitPtr->action_para && unitPtr->action_x_loc==-1 && unitPtr->action_y_loc==-1)
  905. unitPtr->defense_detect_target();
  906. }
  907. //----------- End of function FirmCamp::defense_inside_camp -----------//
  908. //--------- Begin of function FirmCamp::defense_outside_camp ---------//
  909. void FirmCamp::defense_outside_camp(short unitRecno, short targetRecno)
  910. {
  911. Unit *unitPtr = unit_array[unitRecno];
  912. if(unitPtr->action_mode2==ACTION_AUTO_DEFENSE_DETECT_TARGET || unitPtr->action_mode2==ACTION_AUTO_DEFENSE_BACK_CAMP ||
  913. (unitPtr->action_mode2==ACTION_AUTO_DEFENSE_ATTACK_TARGET && unitPtr->cur_action==SPRITE_IDLE))
  914. {
  915. //----------------- attack new target now -------------------//
  916. unitPtr->defense_attack_unit(targetRecno);
  917. err_when(unitPtr->action_mode2!=ACTION_AUTO_DEFENSE_ATTACK_TARGET && unitPtr->action_mode2!=ACTION_AUTO_DEFENSE_DETECT_TARGET);
  918. if(unitPtr->action_mode==ACTION_STOP && !unitPtr->action_para && unitPtr->action_x_loc==-1 && unitPtr->action_y_loc==-1)
  919. unitPtr->defense_detect_target();
  920. }
  921. }
  922. //----------- End of function FirmCamp::defense_outside_camp -----------//
  923. //--------- Begin of function FirmCamp::set_employ_worker ---------//
  924. void FirmCamp::set_employ_worker(char flag)
  925. {
  926. employ_new_worker = flag;
  927. if(!flag)
  928. ai_status = CAMP_IN_DEFENSE;
  929. else
  930. ai_status = FIRM_WITHOUT_ACTION;
  931. /*
  932. //------- a button should exist for accept new worker or not ---------//
  933. //-*********** codes here **********-//
  934. Town *townPtr;
  935. for(int i=0; i<linked_town_count; i++)
  936. {
  937. err_when(!linked_town_array[i] || town_array.is_deleted(linked_town_array[i]));
  938. townPtr = town_array[linked_town_array[i]];
  939. if(nation_recno == townPtr->nation_recno)
  940. toggle_town_link(i+1, employ_new_worker, COMMAND_AUTO); // enable links if employ_new_worker is true, otherwise disable
  941. }
  942. */
  943. }
  944. //----------- End of function FirmCamp::set_employ_worker -----------//
  945. //--------- Begin of function FirmCamp::update_defense_unit ---------//
  946. void FirmCamp::update_defense_unit(short unitRecno)
  947. {
  948. DefenseUnit *defPtr = defense_array;
  949. int allInCamp = 1;
  950. int found=0;
  951. for(int i=0; i<=MAX_WORKER; i++, defPtr++)
  952. {
  953. if(!defPtr->unit_recno)
  954. continue; // empty slot
  955. if(unit_array.is_deleted(defPtr->unit_recno))
  956. {
  957. defPtr->unit_recno = 0;
  958. defPtr->status = INSIDE_CAMP;
  959. continue;
  960. }
  961. if(defPtr->unit_recno==unitRecno)
  962. {
  963. defPtr->unit_recno = 0;
  964. defPtr->status = INSIDE_CAMP;
  965. Unit *unitPtr = unit_array[unitRecno];
  966. unitPtr->stop2();
  967. unitPtr->reset_action_misc_para();
  968. err_when(unitPtr->in_auto_defense_mode());
  969. found++;
  970. }
  971. else
  972. allInCamp = 0; // some units are still outside camp
  973. }
  974. if(allInCamp)
  975. {
  976. set_employ_worker(1);
  977. memset(defense_array, 0, sizeof(DefenseUnit)*(MAX_WORKER+1));
  978. }
  979. // err_when(!found); //**BUGHERE
  980. }
  981. //----------- End of function FirmCamp::update_defense_unit -----------//
  982. //-------- Begin of function FirmCamp::is_worker_full ------//
  983. //
  984. int FirmCamp::is_worker_full()
  985. {
  986. return worker_count + patrol_unit_count + coming_unit_count >= MAX_WORKER;
  987. }
  988. //----------- End of function FirmCamp::is_worker_full ---------//
  989. //--------- Begin of function FirmCamp::sort_soldier ---------//
  990. //
  991. // Sort units in camp by their leaderhip.
  992. //
  993. void FirmCamp::sort_soldier()
  994. {
  995. if( worker_count > 1 )
  996. {
  997. //--- prepare worker_id_array[] for later preserving the currently worker selected ---//
  998. short worker_id_array[MAX_WORKER];
  999. int i;
  1000. for( i=0 ; i<worker_count ; i++ )
  1001. worker_id_array[i] = i+1;
  1002. cur_firm_ptr = this;
  1003. err_when( selected_worker_id < 0 );
  1004. err_when( selected_worker_id > worker_count );
  1005. qsort( worker_id_array, worker_count, sizeof(short), sort_soldier_id_function );
  1006. qsort( worker_array, worker_count, sizeof(Worker), sort_soldier_function );
  1007. //---- scan worker_id_array[] for preserving the currently worker selected ---//
  1008. if( selected_worker_id )
  1009. {
  1010. for( i=0 ; i<worker_count ; i++ )
  1011. {
  1012. if( worker_id_array[i] == selected_worker_id )
  1013. {
  1014. selected_worker_id = i+1;
  1015. break;
  1016. }
  1017. }
  1018. err_when( i==worker_count );
  1019. }
  1020. }
  1021. }
  1022. //----------- End of function FirmCamp::sort_soldier -----------//
  1023. //--------- Begin of function sort_soldier_function ---------//
  1024. //
  1025. static int sort_soldier_function( const void *a, const void *b )
  1026. {
  1027. return ((Worker*)b)->skill_level - ((Worker*)a)->skill_level;
  1028. }
  1029. //----------- End of function sort_soldier_function -----------//
  1030. //--------- Begin of function sort_soldier_id_function ---------//
  1031. //
  1032. static int sort_soldier_id_function( const void *a, const void *b )
  1033. {
  1034. int workerId1 = *((short*)a);
  1035. int workerId2 = *((short*)b);
  1036. return cur_firm_ptr->worker_array[workerId2-1].skill_level -
  1037. cur_firm_ptr->worker_array[workerId1-1].skill_level;
  1038. }
  1039. //----------- End of function sort_soldier_id_function -----------//
  1040. #ifdef DEBUG
  1041. //----------- Begin of static function disp_debug_info -----------//
  1042. static void disp_debug_info(FirmCamp* firmPtr, int refreshFlag)
  1043. {
  1044. if( refreshFlag == INFO_REPAINT )
  1045. vga.d3_panel_up( INFO_X1, INFO_Y2-40, INFO_X2, INFO_Y2 );
  1046. int x=INFO_X1+3, y=INFO_Y2-37, x2=x+120;
  1047. font_san.field( x, y , "patrol unit count", x2, firmPtr->patrol_unit_count, 1, INFO_X2, refreshFlag);
  1048. font_san.field( x, y+16, "coming unit count", x2, firmPtr->coming_unit_count, 1, INFO_X2, refreshFlag);
  1049. font_san.put( x+180, y, firmPtr->firm_recno );
  1050. }
  1051. //----------- End of static function disp_debug_info -----------//
  1052. #endif