OF_INN.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  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_INN.CPP
  21. //Description : Firm Military Inn
  22. #include <OINFO.h>
  23. #include <OBOX.h>
  24. #include <OVGA.h>
  25. #include <OSTR.h>
  26. #include <OFONT.h>
  27. #include <OMOUSE.h>
  28. #include <OHELP.h>
  29. #include <OVBROWIF.h>
  30. #include <OGAME.h>
  31. #include <OTOWN.h>
  32. #include <OBUTT3D.h>
  33. #include <ONATION.h>
  34. #include <ORAWRES.h>
  35. #include <ORACERES.h>
  36. #include <OWORLD.h>
  37. #include <OSPY.h>
  38. #include <OF_INN.h>
  39. #include <OREMOTE.h>
  40. #include <OSERES.h>
  41. //------------- Define coordinations -----------//
  42. enum { HIRE_BROWSE_X1 = INFO_X1,
  43. HIRE_BROWSE_Y1 = INFO_Y1+52,
  44. HIRE_BROWSE_X2 = INFO_X2,
  45. HIRE_BROWSE_Y2 = HIRE_BROWSE_Y1+144
  46. };
  47. enum { HIRE_DET_X1 = INFO_X1,
  48. HIRE_DET_Y1 = HIRE_BROWSE_Y2+5,
  49. HIRE_DET_X2 = INFO_X2,
  50. HIRE_DET_Y2 = HIRE_DET_Y1+54
  51. };
  52. //----------- Define static variables ----------//
  53. static VBrowseIF browse_hire;
  54. static Button3D button_hire;
  55. static int last_hire_count;
  56. static FirmInn* firm_inn_ptr;
  57. //----------- Define static functions ----------//
  58. static void put_hire_rec(int recNo, int x, int y, int refreshFlag);
  59. //--------- Begin of function FirmInn::FirmInn ---------//
  60. //
  61. FirmInn::FirmInn()
  62. {
  63. }
  64. //----------- End of function FirmInn::FirmInn -----------//
  65. //--------- Begin of function FirmInn::~FirmInn ---------//
  66. //
  67. FirmInn::~FirmInn()
  68. {
  69. }
  70. //----------- End of function FirmInn::~FirmInn -----------//
  71. //--------- Begin of function FirmInn::init_derived ---------//
  72. //
  73. void FirmInn::init_derived()
  74. {
  75. inn_unit_count = 0;
  76. next_skill_id = m.random(MAX_TRAINABLE_SKILL)+1;
  77. }
  78. //----------- End of function FirmInn::init_derived -----------//
  79. //--------- Begin of function FirmInn::assign_unit ---------//
  80. //
  81. void FirmInn::assign_unit(int unitRecno)
  82. {
  83. //------- if this is a construction worker -------//
  84. if( unit_array[unitRecno]->skill.skill_id == SKILL_CONSTRUCTION )
  85. {
  86. set_builder(unitRecno);
  87. return;
  88. }
  89. /*
  90. //--- can only assign if the unit is a spy cloaked into this firm's nation color ---//
  91. if( !unitPtr->spy_recno || unitPtr->nation_recno != nation_recno )
  92. return;
  93. //---------------------------------------------//
  94. if( inn_unit_count == MAX_INN_UNIT )
  95. return;
  96. err_when( inn_unit_count > MAX_INN_UNIT );
  97. err_when( !unitRecno );
  98. Unit* unitPtr = unit_array[unitRecno];
  99. //--------- add the InnUnit --------//
  100. InnUnit *innUnit = inn_unit_array+inn_unit_count;
  101. inn_unit_count++;
  102. //--------- set InnUnit vars -----------------//
  103. innUnit->unit_id = unitPtr->unit_id;
  104. innUnit->skill = unitPtr->skill;
  105. innUnit->spy_recno = unitPtr->spy_recno;
  106. innUnit->set_hire_cost();
  107. unitPtr->deinit_sprite();
  108. */
  109. }
  110. //----------- End of function FirmInn::assign_unit -----------//
  111. //--------- Begin of function FirmInn::put_info ---------//
  112. //
  113. void FirmInn::put_info(int refreshFlag)
  114. {
  115. firm_inn_ptr = this;
  116. disp_basic_info(INFO_Y1, refreshFlag);
  117. if( !should_show_info() )
  118. return;
  119. //----------- display browser -----------//
  120. if( refreshFlag == INFO_REPAINT )
  121. {
  122. browse_hire.init( HIRE_BROWSE_X1, HIRE_BROWSE_Y1, HIRE_BROWSE_X2, HIRE_BROWSE_Y2,
  123. 0, 25, inn_unit_count, put_hire_rec );
  124. browse_hire.open(1);
  125. }
  126. else
  127. {
  128. if( last_hire_count != inn_unit_count )
  129. {
  130. if( last_hire_count==0 || inn_unit_count==0 ) // repaint the whole area as the detail area needs to disappear
  131. {
  132. last_hire_count = inn_unit_count;
  133. info.disp();
  134. return;
  135. }
  136. last_hire_count = inn_unit_count;
  137. browse_hire.refresh(-1, inn_unit_count);
  138. if( last_hire_count==0 || inn_unit_count==0 )
  139. refreshFlag = INFO_REPAINT;
  140. }
  141. else
  142. browse_hire.update(); // update only
  143. }
  144. last_hire_count = inn_unit_count;
  145. put_det(refreshFlag);
  146. //---------- display spy button ----------//
  147. disp_spy_button(INFO_X1+BUTTON_ACTION_WIDTH, HIRE_DET_Y2+4, refreshFlag);
  148. }
  149. //----------- End of function FirmInn::put_info -----------//
  150. //--------- Begin of function FirmInn::detect_info ---------//
  151. //
  152. void FirmInn::detect_info()
  153. {
  154. firm_inn_ptr = this;
  155. if( detect_basic_info() )
  156. return;
  157. //-------- detect spy button ----------//
  158. if( !own_firm() )
  159. {
  160. detect_spy_button();
  161. return;
  162. }
  163. //-------------------------------------//
  164. if( browse_hire.detect() )
  165. {
  166. put_det(INFO_UPDATE);
  167. }
  168. if( button_hire.detect() && inn_unit_count > 0 )
  169. {
  170. // ###### begin Gilbert 31/7 #######//
  171. se_res.far_sound(center_x, center_y, 1, 'S',
  172. unit_res[inn_unit_array[browse_hire.recno()-1].unit_id]->sprite_id,
  173. "RDY" );
  174. // ###### end Gilbert 31/7 #######//
  175. if(remote.is_enable())
  176. {
  177. // packet structure : <firm recno>, <hire Id> <nation no>
  178. short *shortPtr=(short *)remote.new_send_queue_msg(MSG_F_INN_HIRE, 3*sizeof(short));
  179. shortPtr[0] = firm_recno;
  180. shortPtr[1] = browse_hire.recno();
  181. shortPtr[2] = nation_recno;
  182. }
  183. else
  184. {
  185. hire(browse_hire.recno());
  186. }
  187. }
  188. }
  189. //----------- End of function FirmInn::detect_info -----------//
  190. //--------- Begin of function FirmInn::hire ---------//
  191. //
  192. int FirmInn::hire(short recNo)
  193. {
  194. err_when( recNo < 1 );
  195. if( recNo > inn_unit_count ) // this may happen in a multiplayer game
  196. return 0;
  197. //--------- first check if you have enough money to hire ------//
  198. InnUnit* innUnit;
  199. Nation* nationPtr = nation_array[nation_recno];
  200. innUnit = inn_unit_array+recNo-1;
  201. if( nationPtr->cash < innUnit->hire_cost )
  202. return 0;
  203. //---------- add the unit now -----------//
  204. int unitRecno = create_unit( innUnit->unit_id );
  205. if(!unitRecno)
  206. return 0; // no space for creating the unit
  207. nationPtr->add_expense(EXPENSE_HIRE_UNIT, innUnit->hire_cost);
  208. //-------- set skills of the unit --------//
  209. Unit* unitPtr = unit_array[unitRecno];
  210. memcpy( &(unitPtr->skill), &(innUnit->skill), sizeof(Skill) );
  211. err_when( innUnit->skill.combat_level<=0 || innUnit->skill.combat_level>100 );
  212. unitPtr->set_combat_level( innUnit->skill.combat_level );
  213. //-------- if the unit's skill is spying -----//
  214. if( unitPtr->skill.skill_id == SKILL_SPYING )
  215. {
  216. unitPtr->spy_recno = spy_array.add_spy(unitRecno, unitPtr->skill.skill_level);
  217. unitPtr->skill.skill_id = 0; // reset its primary skill, its spying skill has been recorded in spy_array
  218. }
  219. //----------------------------------------//
  220. //
  221. // Loyalty of the hired unit
  222. //
  223. // = 30 + the nation's reputation / 2 + 30 if racially homogenous
  224. //
  225. //----------------------------------------//
  226. int unitLoyalty = 30 + (int)nationPtr->reputation/2;
  227. if( race_res.is_same_race(unitPtr->race_id, nationPtr->race_id) )
  228. unitLoyalty += 20;
  229. unitLoyalty = max( 40, unitLoyalty );
  230. unitLoyalty = min( 100, unitLoyalty );
  231. if( unitPtr->spy_recno )
  232. spy_array[unitPtr->spy_recno]->spy_loyalty = unitLoyalty;
  233. else
  234. unitPtr->loyalty = unitLoyalty;
  235. //---- remove the record from the hire list ----//
  236. del_inn_unit(recNo);
  237. if( firm_recno == firm_array.selected_recno &&
  238. nation_recno == nation_array.player_recno )
  239. {
  240. put_info(INFO_UPDATE);
  241. }
  242. return unitRecno;
  243. }
  244. //----------- End of function FirmInn::hire -----------//
  245. //--------- Begin of function FirmInn::put_det ---------//
  246. //
  247. void FirmInn::put_det(int refreshFlag)
  248. {
  249. if( browse_hire.none_record )
  250. {
  251. button_hire.reset();
  252. return;
  253. }
  254. //--------- display details ----------//
  255. InnUnit* innUnit = inn_unit_array+browse_hire.recno()-1;
  256. disp_unit_info(HIRE_DET_Y1, innUnit, refreshFlag );
  257. //------- paint buttons --------//
  258. if( own_firm() )
  259. {
  260. if( refreshFlag == INFO_REPAINT )
  261. {
  262. button_hire.paint( HIRE_DET_X1, HIRE_DET_Y2+4, 'A', "HIREUNIT" );
  263. }
  264. else
  265. {
  266. if( inn_unit_count > 0 &&
  267. (~nation_array)->cash >= inn_unit_array[browse_hire.recno()-1].hire_cost )
  268. {
  269. button_hire.enable();
  270. }
  271. else
  272. {
  273. button_hire.disable();
  274. }
  275. }
  276. }
  277. }
  278. //----------- End of function FirmInn::put_det -----------//
  279. //--------- Begin of function FirmInn::disp_unit_info ---------//
  280. //
  281. // Display the skill information of the people in the town.
  282. //
  283. // <int> dispY1 - the top y coordination of the info area
  284. // <InnUnit*> hireInfoPtr - pointer to a HireInfo structure
  285. // <int> refreshFlag - refresh flag
  286. //
  287. void FirmInn::disp_unit_info(int dispY1, InnUnit* hireInfoPtr, int refreshFlag)
  288. {
  289. Skill* skillPtr = &(hireInfoPtr->skill);
  290. //---------------- paint the panel --------------//
  291. if( refreshFlag == INFO_REPAINT )
  292. {
  293. vga.d3_panel_up( INFO_X1, dispY1, INFO_X2, dispY1+54 );
  294. }
  295. //------ display population composition of this resident town -----//
  296. int x=INFO_X1+4, y=dispY1+4, x1=x+100;
  297. String str;
  298. font_san.field( x, y, "Combat", x1, skillPtr->combat_level, 1, INFO_X2-10, refreshFlag );
  299. if( refreshFlag == INFO_REPAINT )
  300. {
  301. font_san.field( x, y+16, skillPtr->skill_des(), x1, skillPtr->skill_level , 1, INFO_X2-10, refreshFlag );
  302. }
  303. else
  304. {
  305. font_san.use_max_height();
  306. font_san.put( x+2, y+18, skillPtr->skill_des(), 1, x1-2 );
  307. font_san.use_std_height();
  308. font_san.update_field( x1, y+16, skillPtr->skill_level, 1, INFO_X2-10);
  309. }
  310. font_san.field( x, y+32, "Hiring Cost", x1, hireInfoPtr->hire_cost, 2, INFO_X2-10, refreshFlag);
  311. }
  312. //----------- End of function FirmInn::disp_unit_info -----------//
  313. //-------- Begin of static function put_hire_rec --------//
  314. //
  315. static void put_hire_rec(int recNo, int x, int y, int refreshFlag)
  316. {
  317. InnUnit* innUnit = firm_inn_ptr->inn_unit_array+recNo-1;
  318. //-------- display unit icon -------//
  319. vga_front.d3_panel_down(x+1, y+1, x+UNIT_SMALL_ICON_WIDTH+4, y+UNIT_SMALL_ICON_HEIGHT+4, 2, 0 );
  320. // ##### begin Gilbert 17/10 #######//
  321. vga_front.put_bitmap(x+3, y+3, unit_res[innUnit->unit_id]->get_small_icon_ptr(RANK_SOLDIER) );
  322. // ##### end Gilbert 17/10 #######//
  323. //--------- set help parameters --------//
  324. if( mouse.in_area(x+1, y+1, x+UNIT_SMALL_ICON_WIDTH+4, y+UNIT_SMALL_ICON_HEIGHT+4) )
  325. help.set_unit_help( innUnit->unit_id, 0, x+1, y+1, x+UNIT_SMALL_ICON_WIDTH+4, y+UNIT_SMALL_ICON_HEIGHT+4 );
  326. //---------- display info ----------//
  327. y+=6;
  328. font_san.use_max_height();
  329. if( innUnit->skill.skill_level > 0 )
  330. {
  331. font_san.put( x+32 , y, innUnit->skill.skill_des(1), 1, x+122 ); // 1-use short words
  332. font_san.put( x+116, y, innUnit->skill.skill_level, 1, x+146 );
  333. }
  334. else
  335. {
  336. font_san.put( x+32 , y, "Combat", 1, x+122 ); // 1-use short words
  337. font_san.put( x+116, y, innUnit->skill.combat_level, 1, x+146 );
  338. }
  339. font_san.use_std_height();
  340. font_san.put( x+140, y, m.format(innUnit->hire_cost,2), 1, x+browse_hire.rec_width-3 );
  341. }
  342. //----------- End of static function put_hire_rec -----------//
  343. //--------- Begin of function FirmInn::next_day ---------//
  344. //
  345. void FirmInn::next_day()
  346. {
  347. //----------- run next_day() of the base class -------------//
  348. Firm::next_day();
  349. //------------ update the hire list ------------//
  350. int updateInterveal = 10 + info.year_passed*2; // there will be less and less units to hire as the game passes
  351. if( info.game_date % updateInterveal == firm_recno % updateInterveal )
  352. update_add_hire_list();
  353. if( info.game_date % 10 == firm_recno % 10 )
  354. update_del_hire_list();
  355. }
  356. //----------- End of function FirmInn::next_day -----------//
  357. //---------- Begin of function FirmInn::update_add_hire_list --------//
  358. //
  359. void FirmInn::update_add_hire_list()
  360. {
  361. //-------- new units come by --------//
  362. if( inn_unit_count < MAX_INN_UNIT )
  363. {
  364. if( should_add_inn_unit() )
  365. {
  366. int unitId = race_res[m.random(MAX_RACE)+1]->basic_unit_id;
  367. if( unitId )
  368. add_inn_unit(unitId);
  369. }
  370. }
  371. }
  372. //----------- End of function FirmInn::update_add_hire_list ---------//
  373. //--------- Begin of function FirmInn::update_del_hire_list --------//
  374. //
  375. void FirmInn::update_del_hire_list()
  376. {
  377. //------- existing units leave -------//
  378. for( int i=inn_unit_count ; i>0 && inn_unit_count>0 ; i-- )
  379. {
  380. if( !inn_unit_array[i-1].spy_recno && --inn_unit_array[i-1].stay_count==0 )
  381. {
  382. del_inn_unit(i);
  383. if( firm_recno == firm_array.selected_recno )
  384. {
  385. if( browse_hire.recno() > i && browse_hire.recno() > 1 )
  386. browse_hire.refresh( browse_hire.recno()-1, inn_unit_count );
  387. }
  388. }
  389. }
  390. }
  391. //--------- End of function FirmInn::update_del_hire_list ---------//
  392. //-------- Begin of function FirmInn::should_add_inn_unit --------//
  393. //
  394. int FirmInn::should_add_inn_unit()
  395. {
  396. #define MAX_INN_UNIT_PER_REGION 10 // maximum no. of inn units in any single region
  397. FirmInn* firmInn;
  398. int totalInnUnit = inn_unit_count;
  399. for(int i=0; i<linked_firm_count; i++)
  400. {
  401. firmInn = (FirmInn*) firm_array[linked_firm_array[i]]; // links between inns are stored in linked_firm_array[] for quick scan only
  402. err_when( firmInn->firm_id != FIRM_INN );
  403. totalInnUnit += firmInn->inn_unit_count;
  404. }
  405. return totalInnUnit < MAX_INN_UNIT_PER_REGION;
  406. }
  407. //--------- End of function FirmInn::should_add_inn_unit ---------//
  408. //--------- Begin of function FirmInn::add_inn_unit ---------//
  409. void FirmInn::add_inn_unit(int unitId)
  410. {
  411. err_when( inn_unit_count >= MAX_INN_UNIT );
  412. InnUnit *innUnit = inn_unit_array+inn_unit_count;
  413. inn_unit_count++;
  414. innUnit->unit_id = unitId;
  415. //--------- set the skill now -----------------//
  416. char skillId = (char) next_skill_id;
  417. if( ++next_skill_id > MAX_TRAINABLE_SKILL )
  418. next_skill_id = 1;
  419. innUnit->skill.skill_id = skillId;
  420. if( skillId > 0 )
  421. innUnit->skill.skill_level = 30+m.random(70);
  422. else
  423. innUnit->skill.skill_level = 0;
  424. if( skillId==0 || skillId==SKILL_LEADING )
  425. innUnit->skill.combat_level = 30+m.random(70);
  426. else
  427. innUnit->skill.combat_level = 10;
  428. innUnit->set_hire_cost();
  429. innUnit->stay_count = 5 + m.random(5);
  430. innUnit->spy_recno = 0;
  431. }
  432. //----------- End of function FirmInn::add_inn_unit -----------//
  433. //--------- Begin of function InnUnit::set_hire_cost ---------//
  434. //
  435. void InnUnit::set_hire_cost()
  436. {
  437. hire_cost = skill.combat_level + (int)skill.skill_level*2;
  438. if( skill.skill_id==SKILL_LEADING ) // the cost of a leader unit is higher
  439. {
  440. hire_cost += skill.skill_level*2;
  441. for( int i=10 ; i<=100 ; i+=20 ) // increase the hiring cost with bigger steps when the skill level gets higher
  442. {
  443. if( i > skill.skill_level )
  444. hire_cost += i/5;
  445. }
  446. }
  447. else if( skill.skill_id==SKILL_SPYING ) // the cost of a leader unit is higher
  448. {
  449. hire_cost += skill.skill_level;
  450. }
  451. hire_cost *= 2;
  452. }
  453. //----------- End of function InnUnit::set_hire_cost -----------//
  454. //--------- Begin of function FirmInn::del_inn_unit ---------//
  455. void FirmInn::del_inn_unit(int recNo)
  456. {
  457. err_when( recNo<1 || recNo>MAX_INN_UNIT );
  458. err_when( inn_unit_count < 1 );
  459. err_when( inn_unit_count > MAX_INN_UNIT );
  460. m.del_array_rec(inn_unit_array, inn_unit_count, sizeof(InnUnit), recNo);
  461. inn_unit_count--;
  462. }
  463. //----------- End of function FirmInn::del_inn_unit -----------//
  464. //--------- Begin of function FirmInn::auto_defense ---------//
  465. void FirmInn::auto_defense(short targetRecno)
  466. {
  467. //---------- the area to check -----------//
  468. int xLoc1 = center_x - EFFECTIVE_FIRM_TOWN_DISTANCE;
  469. int yLoc1 = center_y - EFFECTIVE_FIRM_TOWN_DISTANCE;
  470. int xLoc2 = center_x + EFFECTIVE_FIRM_TOWN_DISTANCE;
  471. int yLoc2 = center_y + EFFECTIVE_FIRM_TOWN_DISTANCE;
  472. //----------- boundary checking ----------//
  473. if(xLoc1<0) xLoc1 = 0;
  474. if(yLoc1<0) yLoc1 = 0;
  475. if(xLoc2>=MAX_WORLD_X_LOC) xLoc2 = MAX_WORLD_X_LOC-1;
  476. if(yLoc2>=MAX_WORLD_Y_LOC) yLoc2 = MAX_WORLD_Y_LOC-1;
  477. int skipWidthDist = STD_TOWN_LOC_WIDTH;
  478. int skipHeightDist = STD_TOWN_LOC_HEIGHT;
  479. int xEnd, yEnd, xLimit, yLimit;
  480. int i, j, dist;
  481. Location *locPtr;
  482. Town *townPtr;
  483. //--------------------------------------------------//
  484. // check for our town in the effective area
  485. //--------------------------------------------------//
  486. xLimit = xLoc2+skipWidthDist-1;
  487. yLimit = yLoc2+skipHeightDist-1;
  488. for(xEnd=0, i=xLoc1; i<=xLimit && !xEnd; i+=skipWidthDist)
  489. {
  490. if(i>=xLoc2)
  491. {
  492. xEnd++; // final
  493. i = xLoc2;
  494. }
  495. for(yEnd=0, j=yLoc1; j<=yLimit && !yEnd; j+=skipHeightDist)
  496. {
  497. if(j>=yLoc2)
  498. {
  499. yEnd++; // final
  500. j = yLoc2;
  501. }
  502. err_when(i<xLoc1 || i>xLoc2 || j<yLoc1 || j>yLoc2);
  503. locPtr = world.get_loc(i, j);
  504. if(!locPtr->is_town())
  505. continue;
  506. err_when(!locPtr->town_recno() || town_array.is_deleted(locPtr->town_recno()));
  507. townPtr = town_array[locPtr->town_recno()];
  508. if(townPtr->nation_recno!=nation_recno)
  509. continue;
  510. dist = m.points_distance(center_x, center_y, townPtr->center_x, townPtr->center_y);
  511. if(dist <= EFFECTIVE_FIRM_TOWN_DISTANCE)
  512. townPtr->auto_defense(targetRecno);
  513. }
  514. }
  515. }
  516. //----------- End of function FirmInn::auto_defense -----------//