OSPY.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433
  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 : OSPY.CPP
  21. //Description : Object Spy
  22. #include <OPOWER.h>
  23. #include <OGAME.h>
  24. #include <ODATE.h>
  25. #include <ONEWS.h>
  26. #include <OFONT.h>
  27. #include <OUNIT.h>
  28. #include <OWORLD.h>
  29. #include <OBUTTON.h>
  30. #include <OFIRM.h>
  31. #include <OTOWN.h>
  32. #include <ONATION.h>
  33. #include <ORACERES.h>
  34. #include <OSYS.h>
  35. #include <OSPY.h>
  36. #include <OREMOTE.h>
  37. // ###### begin Gilbert 10/10 #######//
  38. #include <OSE.h>
  39. // ###### end Gilbert 10/10 #######//
  40. //--------- Begin of function Spy::Spy ----------//
  41. //
  42. Spy::Spy()
  43. {
  44. memset( this, 0, sizeof(Spy) );
  45. }
  46. //---------- End of function Spy::Spy ----------//
  47. //--------- Begin of function Spy::deinit ----------//
  48. //
  49. void Spy::deinit()
  50. {
  51. set_place(SPY_UNDEFINED, 0); // reset spy place vars
  52. race_res[race_id]->free_name_id(name_id);
  53. spy_recno = 0;
  54. }
  55. //---------- End of function Spy::deinit ----------//
  56. //--------- Begin of function Spy::set_action_mode ----------//
  57. //
  58. void Spy::set_action_mode(int actionMode)
  59. {
  60. action_mode = actionMode;
  61. }
  62. //---------- End of function Spy::set_action_mode ----------//
  63. //--------- Begin of function Spy::set_place ----------//
  64. //
  65. // Meaning of spy_place_para:
  66. //
  67. // SPY_MOBILE - unit recno of the spy
  68. // SPY_TOWN - town recno
  69. // SPY_FIRM - firm recno
  70. // SPY_SHIP - unit recno of the ship
  71. //
  72. void Spy::set_place(int spyPlace, int spyPlacePara)
  73. {
  74. //----- reset spy counter of the current place ----//
  75. if( spy_place == SPY_FIRM )
  76. {
  77. if( true_nation_recno == nation_array.player_recno )
  78. {
  79. if( !firm_array.is_deleted(spy_place_para) )
  80. {
  81. firm_array[spy_place_para]->player_spy_count--;
  82. err_when( firm_array[spy_place_para]->player_spy_count<0 );
  83. }
  84. }
  85. }
  86. else if( spy_place == SPY_TOWN )
  87. {
  88. if( !town_array.is_deleted(spy_place_para) )
  89. {
  90. town_array[spy_place_para]->race_spy_count_array[race_id-1]--;
  91. err_when( town_array[spy_place_para]->race_spy_count_array[race_id-1]<0 );
  92. }
  93. }
  94. //------- set the spy place now ---------//
  95. spy_place = spyPlace;
  96. spy_place_para = spyPlacePara;
  97. action_mode = SPY_IDLE; // reset the spy mode
  98. //------- set the spy counter of the new place ------//
  99. if( spy_place == SPY_FIRM )
  100. {
  101. if( true_nation_recno == nation_array.player_recno )
  102. firm_array[spy_place_para]->player_spy_count++;
  103. cloaked_nation_recno = (char) firm_array[spy_place_para]->nation_recno;
  104. if( firm_array[spy_place_para]->nation_recno != true_nation_recno )
  105. notify_cloaked_nation_flag = 1; // when a spy has been assigned to a firm, its notification flag should be set to 1, so the nation can control it as it is one of its own units
  106. }
  107. else if( spy_place == SPY_TOWN )
  108. {
  109. town_array[spy_place_para]->race_spy_count_array[race_id-1]++;
  110. //-----------------------------------------------------------//
  111. // We need to update it here as this spy may have resigned from
  112. // a foreign firm and go back to its home village. And the
  113. // nation recno of the foreign firm and the home village are
  114. // different.
  115. //-----------------------------------------------------------//
  116. cloaked_nation_recno = (char) town_array[spy_place_para]->nation_recno;
  117. if( town_array[spy_place_para]->nation_recno != true_nation_recno ) // if it's our own town, don't change notify_cloaked_nation_flag
  118. notify_cloaked_nation_flag = 1;
  119. }
  120. }
  121. //---------- End of function Spy::set_place ----------//
  122. //--------- Begin of function Spy::get_loc ----------//
  123. //
  124. // Return the location of the spy.
  125. //
  126. // <int&> xLoc, yLoc - vars for returning the locatin.
  127. //
  128. int Spy::get_loc(int& xLoc, int& yLoc)
  129. {
  130. switch( spy_place )
  131. {
  132. case SPY_FIRM:
  133. if( !firm_array.is_deleted(spy_place_para) )
  134. {
  135. xLoc = firm_array[spy_place_para]->center_x;
  136. yLoc = firm_array[spy_place_para]->center_y;
  137. return 1;
  138. }
  139. break;
  140. case SPY_TOWN:
  141. if( !town_array.is_deleted(spy_place_para) )
  142. {
  143. xLoc = town_array[spy_place_para]->center_x;
  144. yLoc = town_array[spy_place_para]->center_y;
  145. return 1;
  146. }
  147. break;
  148. case SPY_MOBILE:
  149. if( !unit_array.is_deleted(spy_place_para) )
  150. {
  151. xLoc = unit_array[spy_place_para]->next_x_loc();
  152. yLoc = unit_array[spy_place_para]->next_y_loc();
  153. return 1;
  154. }
  155. break;
  156. }
  157. return 0;
  158. }
  159. //---------- End of function Spy::get_loc ----------//
  160. //------ Begin of function Spy::spy_place_nation_recno -------//
  161. //
  162. // Return the nation recno of the place where the spy stays.
  163. //
  164. int Spy::spy_place_nation_recno()
  165. {
  166. if( spy_place == SPY_TOWN )
  167. return town_array[spy_place_para]->nation_recno;
  168. else if( spy_place == SPY_FIRM )
  169. return firm_array[spy_place_para]->nation_recno;
  170. else
  171. return 0;
  172. }
  173. //-------- End of function Spy::spy_place_nation_recno --------//
  174. //--------- Begin of function Spy::next_day ----------//
  175. //
  176. void Spy::next_day()
  177. {
  178. //------- pay expenses --------//
  179. pay_expense();
  180. //------ when the spy has been exposed -------//
  181. if( exposed_flag )
  182. {
  183. //-- he will be killed immediately unless he is back in his original nation color ---//
  184. if( true_nation_recno != cloaked_nation_recno )
  185. {
  186. get_killed();
  187. return;
  188. }
  189. else
  190. exposed_flag = 0; // reset exposed_flag.
  191. }
  192. //------ process actions ---------//
  193. if( info.game_date%30 == spy_recno%30 )
  194. {
  195. if( spy_place == SPY_TOWN )
  196. process_town_action();
  197. else if( spy_place == SPY_FIRM )
  198. process_firm_action();
  199. }
  200. //------ increase skill --------//
  201. int rc;
  202. if( action_mode==SPY_IDLE ) // increase slower when in sleep mode
  203. rc = info.game_date%80 == spy_recno%80;
  204. else
  205. rc = info.game_date%40 == spy_recno%40;
  206. if( rc && spy_skill < 100 )
  207. spy_skill++;
  208. //----- update loyalty & think betray -------//
  209. if( info.game_date%60 == spy_recno%60 )
  210. {
  211. update_loyalty();
  212. if( think_betray() )
  213. return;
  214. }
  215. //----------- visit map (for fog of war) ----------//
  216. if( true_nation_recno == nation_array.player_recno )
  217. {
  218. if( spy_place == SPY_TOWN )
  219. {
  220. Town* townPtr = town_array[spy_place_para];
  221. world.visit( townPtr->loc_x1, townPtr->loc_y1, townPtr->loc_x2, townPtr->loc_y2, EXPLORE_RANGE-1 );
  222. }
  223. else if( spy_place == SPY_FIRM )
  224. {
  225. Firm* firmPtr = firm_array[spy_place_para];
  226. world.visit( firmPtr->loc_x1, firmPtr->loc_y1, firmPtr->loc_x2, firmPtr->loc_y2, EXPLORE_RANGE-1 );
  227. }
  228. }
  229. //---------- debug code -----------//
  230. #ifdef DEBUG
  231. err_when( race_id<1 || race_id>MAX_RACE );
  232. switch( spy_place )
  233. {
  234. case SPY_MOBILE:
  235. {
  236. Unit* unitPtr = unit_array[spy_place_para];
  237. err_when( unitPtr->rank_id == RANK_KING );
  238. err_when( unitPtr->spy_recno != spy_recno );
  239. err_when( unitPtr->skill.skill_id == SKILL_SPYING );
  240. break;
  241. }
  242. case SPY_TOWN:
  243. err_when( town_array[spy_place_para]->nation_recno != cloaked_nation_recno );
  244. break;
  245. case SPY_FIRM:
  246. err_when( firm_array.is_deleted(spy_place_para) );
  247. {
  248. Firm* firmPtr = firm_array[spy_place_para];
  249. int i;
  250. for( i=0 ; i<firmPtr->worker_count ; i++ )
  251. {
  252. if( firmPtr->worker_array[i].spy_recno==spy_recno )
  253. break;
  254. }
  255. if( i==firmPtr->worker_count ) // not found in worker_array
  256. {
  257. err_when( !firmPtr->overseer_recno ||
  258. unit_array[firmPtr->overseer_recno]->spy_recno != spy_recno );
  259. }
  260. }
  261. break;
  262. }
  263. #endif
  264. }
  265. //---------- End of function Spy::next_day ----------//
  266. //--------- Begin of function Spy::process_town_action ----------//
  267. //
  268. void Spy::process_town_action()
  269. {
  270. Town* townPtr = town_array[spy_place_para];
  271. if( action_mode == SPY_SOW_DISSENT )
  272. {
  273. if( townPtr->race_pop_array[race_id-1] > townPtr->race_spy_count_array[race_id-1] ) // only when there are non-spy people
  274. {
  275. float decValue = (float)spy_skill / 5 / townPtr->race_pop_array[race_id-1]; // the more people there, the longer it takes to decrease the loyalty
  276. //----- if this is an independent town -----//
  277. if( townPtr->nation_recno==0 )
  278. {
  279. townPtr->race_resistance_array[race_id-1][true_nation_recno-1] -= decValue;
  280. if( townPtr->race_resistance_array[race_id-1][true_nation_recno-1] < 0 )
  281. townPtr->race_resistance_array[race_id-1][true_nation_recno-1] = (float) 0;
  282. }
  283. //--- if this is an enemy town, decrease the town people's loyalty ---//
  284. else
  285. {
  286. townPtr->race_loyalty_array[race_id-1] -= decValue;
  287. if( townPtr->race_loyalty_array[race_id-1] < (float) 0 )
  288. townPtr->race_loyalty_array[race_id-1] = (float) 0;
  289. }
  290. }
  291. }
  292. }
  293. //---------- End of function Spy::process_town_action ----------//
  294. //--------- Begin of function Spy::process_firm_action ----------//
  295. //
  296. void Spy::process_firm_action()
  297. {
  298. Firm* firmPtr = firm_array[spy_place_para];
  299. //---------- Sow Dissent ----------//
  300. if( action_mode == SPY_SOW_DISSENT )
  301. {
  302. //---- decrease the loyalty of the overseer if there is any -----//
  303. if( firmPtr->overseer_recno )
  304. {
  305. Unit* unitPtr = unit_array[firmPtr->overseer_recno];
  306. if( unitPtr->race_id == race_id )
  307. {
  308. if( m.random(10 - spy_skill/10 + unitPtr->skill.skill_level/10)==0 // a commander with a higher leadership skill will be less influenced by the spy's dissents
  309. && unitPtr->loyalty>0 )
  310. {
  311. unitPtr->change_loyalty( -1 );
  312. }
  313. }
  314. }
  315. //----- decrease the loyalty of the workers in the firm -----//
  316. Worker* workerPtr = firmPtr->worker_array;
  317. for( int i=0 ; i<firmPtr->worker_count ; i++, workerPtr++ )
  318. {
  319. if( workerPtr->race_id != race_id )
  320. continue;
  321. //---- if the worker lives in a town ----//
  322. if( workerPtr->town_recno )
  323. {
  324. Town* townPtr = town_array[workerPtr->town_recno];
  325. int raceId = workerPtr->race_id;
  326. if( townPtr->race_pop_array[raceId-1] > townPtr->race_spy_count_array[raceId-1] ) // only when there are non-spy people
  327. {
  328. townPtr->change_loyalty( raceId, (float) -spy_skill / 5 / townPtr->race_pop_array[raceId-1] ); // the more people there, the longer it takes to decrease the loyalty
  329. }
  330. }
  331. else //---- if the worker does not live in a town ----//
  332. {
  333. if( !workerPtr->spy_recno ) // the loyalty of the spy himself does not change
  334. {
  335. if( m.random(10-spy_skill/10)==0 && workerPtr->worker_loyalty>0 )
  336. workerPtr->worker_loyalty--;
  337. }
  338. }
  339. }
  340. }
  341. }
  342. //---------- End of function Spy::process_firm_action ----------//
  343. //--------- Begin of function Spy::set_next_action_mode ----------//
  344. //
  345. void Spy::set_next_action_mode()
  346. {
  347. if( spy_place==SPY_TOWN )
  348. {
  349. if( action_mode == SPY_IDLE )
  350. set_action_mode(SPY_SOW_DISSENT);
  351. else
  352. set_action_mode(SPY_IDLE);
  353. }
  354. else if( spy_place==SPY_FIRM )
  355. {
  356. switch( action_mode )
  357. {
  358. case SPY_IDLE:
  359. if( can_sabotage() )
  360. {
  361. set_action_mode(SPY_SABOTAGE);
  362. break;
  363. }
  364. case SPY_SABOTAGE:
  365. set_action_mode(SPY_SOW_DISSENT);
  366. break;
  367. case SPY_SOW_DISSENT:
  368. set_action_mode(SPY_IDLE);
  369. break;
  370. }
  371. }
  372. else
  373. err_here();
  374. }
  375. //---------- End of function Spy::set_next_action_mode ----------//
  376. //--------- Begin of function Spy::can_sabotage ----------//
  377. //
  378. int Spy::can_sabotage()
  379. {
  380. return spy_place == SPY_FIRM &&
  381. firm_array[spy_place_para]->firm_id != FIRM_CAMP; // no sabotage actino for military camp
  382. }
  383. //---------- End of function Spy::can_sabotage ----------//
  384. //--------- Begin of function Spy::get_killed ----------//
  385. //
  386. // [int] dispNews - whether display a news message or not
  387. // (default: 1)
  388. //
  389. void Spy::get_killed(int dispNews)
  390. {
  391. //-------- add news --------//
  392. if( true_nation_recno == nation_array.player_recno || // the player's spy is killed
  393. cloaked_nation_recno == nation_array.player_recno ) // a spy cloaked as the player's people is killed in the player's firm or firm
  394. {
  395. news_array.spy_killed(spy_recno);
  396. // ####### begin Gilbert 10/10 #######//
  397. se_ctrl.immediate_sound("SPY_DIE");
  398. // ####### end Gilbert 10/10 #######//
  399. }
  400. //--- If a spy is caught, the spy's nation's reputation wil decrease ---//
  401. nation_array[true_nation_recno]->change_reputation((float)-SPY_KILLED_REPUTATION_DECREASE);
  402. //------- if the spy is in a town -------//
  403. int hostNationRecno=0;
  404. //### begin alex 31/3 ###//
  405. int mobileUnit = 0;
  406. //#### end alex 31/3 ####//
  407. if( spy_place==SPY_TOWN )
  408. {
  409. Town* townPtr = town_array[spy_place_para];
  410. hostNationRecno = townPtr->nation_recno;
  411. townPtr->dec_pop(race_id, 0);
  412. }
  413. //------- if the spy is in a firm -------//
  414. else if( spy_place==SPY_FIRM )
  415. {
  416. Firm* firmPtr = firm_array[spy_place_para];
  417. hostNationRecno = firmPtr->nation_recno;
  418. //------- check if the overseer is the spy -------//
  419. if( firmPtr->overseer_recno )
  420. {
  421. Unit* unitPtr = unit_array[firmPtr->overseer_recno];
  422. if( unitPtr->spy_recno == spy_recno )
  423. {
  424. firmPtr->kill_overseer();
  425. return;
  426. }
  427. }
  428. //---- check if any of the workers is the spy ----//
  429. for( int i=0 ; i<firmPtr->worker_count ; i++ )
  430. {
  431. if( firmPtr->worker_array[i].spy_recno == spy_recno )
  432. {
  433. firmPtr->kill_worker(i+1);
  434. return;
  435. }
  436. }
  437. err_here(); // the spy is not found here
  438. }
  439. else if( spy_place == SPY_MOBILE )
  440. {
  441. //### begin alex 31/3 ###//
  442. //err_here(); // only spies in towns and firms will get killed instantly
  443. unit_array.del(spy_place_para);
  444. mobileUnit = 1;
  445. //#### end alex 31/3 ####//
  446. }
  447. else
  448. {
  449. err_here();
  450. }
  451. //--- If the spy is in an AI town or firm, the AI's relationship towards the spy's owner nation will decrease ---//
  452. if( hostNationRecno && nation_array[hostNationRecno]->is_ai() )
  453. {
  454. nation_array[hostNationRecno]->change_ai_relation_level(true_nation_recno, -5);
  455. }
  456. //---- delete the spy from spy_array ----//
  457. //### begin alex 31/3 ###//
  458. if(!mobileUnit)
  459. spy_array.del_spy(spy_recno);
  460. //else spy_array.del_spy() is called in unit_array.del()
  461. //#### end alex 31/3 ####//
  462. }
  463. //---------- End of function Spy::get_killed ----------//
  464. //--------- Begin of function Spy::action_str ----------//
  465. //
  466. char* Spy::action_str()
  467. {
  468. switch( action_mode )
  469. {
  470. case SPY_IDLE:
  471. {
  472. //---- if the spy is in a firm or town of its own nation ---//
  473. if( (spy_place==SPY_TOWN &&
  474. town_array[spy_place_para]->nation_recno == true_nation_recno) ||
  475. (spy_place==SPY_FIRM &&
  476. firm_array[spy_place_para]->nation_recno == true_nation_recno) )
  477. {
  478. return "Counter-Spy";
  479. }
  480. else
  481. return "Sleep";
  482. }
  483. case SPY_SOW_DISSENT:
  484. return "Sow Dissent";
  485. case SPY_SABOTAGE:
  486. return "Sabotage";
  487. default:
  488. err_here();
  489. }
  490. return "";
  491. }
  492. //---------- End of function Spy::action_str ----------//
  493. //--------- Begin of function Spy::pay_expense ---------//
  494. //
  495. // -Each spy costs $5 dollars to maintain per month.
  496. //
  497. // -If your spies are mobile:
  498. // >your nation pays them 1 food and $5 dollars per month
  499. //
  500. // -If your spies are in an enemy's town or firm:
  501. // >the enemy pays them 1 food and the normal salary of their jobs.
  502. // >your nation pays them $5 dollars per month. (your nation pays them no food)
  503. //
  504. // -If your spies are in your own town or firm:
  505. // >your nation pays them 1 food and $5 dollars per month
  506. //
  507. void Spy::pay_expense()
  508. {
  509. Nation* nationPtr = nation_array[true_nation_recno];
  510. //---------- reduce cash -----------//
  511. if( nationPtr->cash > 0 )
  512. {
  513. nationPtr->add_expense( EXPENSE_SPY, (float) SPY_YEAR_SALARY / 365, 1 );
  514. }
  515. else // decrease loyalty if the nation cannot pay the unit
  516. {
  517. change_loyalty(-1);
  518. }
  519. //---------- reduce food -----------//
  520. int inOwnFirm=0;
  521. if( spy_place == SPY_FIRM )
  522. {
  523. Firm* firmPtr = firm_array[spy_place_para];
  524. if( firmPtr->nation_recno == true_nation_recno &&
  525. firmPtr->overseer_recno &&
  526. unit_array[firmPtr->overseer_recno]->spy_recno == spy_recno )
  527. {
  528. inOwnFirm = 1;
  529. }
  530. }
  531. if( spy_place == SPY_MOBILE || inOwnFirm )
  532. {
  533. if( nationPtr->food > 0 )
  534. {
  535. nationPtr->consume_food((float) PERSON_FOOD_YEAR_CONSUMPTION / 365);
  536. }
  537. else
  538. {
  539. if( info.game_date%NO_FOOD_LOYALTY_DECREASE_INTERVAL == 0 ) // decrease 1 loyalty point every 2 days
  540. change_loyalty(-1);
  541. }
  542. }
  543. }
  544. //----------- End of function Spy::pay_expense -----------//
  545. //--------- Begin of function Spy::update_loyalty ----------//
  546. //
  547. void Spy::update_loyalty()
  548. {
  549. Nation* ownNation = nation_array[true_nation_recno];
  550. int targetLoyalty = 50 + (int)ownNation->reputation/4 +
  551. ownNation->overall_rank_rating()/4;
  552. if( race_id == ownNation->race_id )
  553. targetLoyalty += 20;
  554. targetLoyalty = min( targetLoyalty, 100 );
  555. if( spy_loyalty > targetLoyalty )
  556. spy_loyalty--;
  557. else if( spy_loyalty < targetLoyalty )
  558. spy_loyalty++;
  559. }
  560. //---------- End of function Spy::update_loyalty ----------//
  561. //--------- Begin of function Spy::change_loyalty ----------//
  562. //
  563. void Spy::change_loyalty(int changeAmt)
  564. {
  565. int newLoyalty = spy_loyalty + changeAmt;
  566. newLoyalty = max(0, newLoyalty);
  567. spy_loyalty = min(100, newLoyalty);
  568. }
  569. //---------- End of function Spy::change_loyalty ----------//
  570. //--------- Begin of function Spy::think_betray ----------//
  571. //
  572. // Think about turning towards to the current cloaked nation,
  573. // become a normal unit and lose its spy identity.
  574. //
  575. int Spy::think_betray()
  576. {
  577. if( spy_loyalty >= UNIT_BETRAY_LOYALTY ) // you when unit is
  578. return 0;
  579. if( cloaked_nation_recno == true_nation_recno || cloaked_nation_recno==0 )
  580. return 0;
  581. //--- think whether the spy should turn towards the nation ---//
  582. Nation* nationPtr = nation_array[cloaked_nation_recno];
  583. int nationScore = (int) nationPtr->reputation; // reputation can be negative
  584. if( race_res.is_same_race(nationPtr->race_id, race_id) )
  585. nationScore += 30;
  586. if( spy_loyalty < nationScore || spy_loyalty==0 )
  587. {
  588. drop_spy_identity();
  589. return 1;
  590. }
  591. return 0;
  592. }
  593. //---------- End of function Spy::think_betray ----------//
  594. //--------- Begin of function Spy::drop_spy_identity ----------//
  595. //
  596. // Drop its spy identity. If it is currently cloaked to another
  597. // nation, it will become units of that nation.
  598. //
  599. void Spy::drop_spy_identity()
  600. {
  601. if( spy_place == SPY_FIRM )
  602. {
  603. Firm* firmPtr = firm_array[spy_place_para];
  604. int rc = 0;
  605. if( firmPtr->overseer_recno )
  606. {
  607. Unit* unitPtr = unit_array[firmPtr->overseer_recno];
  608. if( unitPtr->spy_recno == spy_recno )
  609. {
  610. unitPtr->spy_recno = 0;
  611. rc = 1;
  612. }
  613. }
  614. if( !rc )
  615. {
  616. for( int i=0 ; i<firmPtr->worker_count ; i++ )
  617. {
  618. if( firmPtr->worker_array[i].spy_recno==spy_recno )
  619. {
  620. firmPtr->worker_array[i].spy_recno = 0;
  621. rc = 1;
  622. break;
  623. }
  624. }
  625. err_when( !rc );
  626. }
  627. }
  628. else if( spy_place == SPY_MOBILE )
  629. {
  630. Unit* unitPtr = unit_array[spy_place_para];
  631. unitPtr->spy_recno = 0;
  632. }
  633. //------ delete this Spy record from spy_array ----//
  634. spy_array.del_spy(spy_recno); // Spy::deinit() will take care of the rest of the initialization for the spy
  635. }
  636. //---------- End of function Spy::drop_spy_identity ----------//
  637. //--------- Begin of function Spy::change_true_nation ----------//
  638. //
  639. // Change the spy's true nation recno.
  640. //
  641. void Spy::change_true_nation(int newNationRecno)
  642. {
  643. err_when( nation_array.is_deleted(newNationRecno) );
  644. true_nation_recno = newNationRecno;
  645. //--- update Firm::player_spy_count if the spy is in a firm ---//
  646. if( spy_place == SPY_FIRM )
  647. {
  648. spy_array.update_firm_spy_count(spy_place_para);
  649. }
  650. }
  651. //---------- End of function Spy::change_true_nation ----------//
  652. //--------- Begin of function Spy::change_cloaked_nation ----------//
  653. //
  654. // Change a spy's cloaked nation. This nation is when the caller
  655. // only have spy_recno as the reference. While Unit::spy_change_nation()
  656. // is called when the caller has unit_recno as the reference.
  657. //
  658. // <int> newNationRecno - the new nation the spy changes its cloack to
  659. //
  660. void Spy::change_cloaked_nation(int newNationRecno)
  661. {
  662. if( newNationRecno == cloaked_nation_recno )
  663. return;
  664. //--- only mobile units and overseers can change nation, spies in firms or towns cannot change nation, their nation recno must be the same as the town or the firm's nation recno
  665. if( spy_place == SPY_MOBILE )
  666. {
  667. unit_array[spy_place_para]->spy_change_nation(newNationRecno, COMMAND_AUTO);
  668. return;
  669. }
  670. else if( spy_place == SPY_FIRM )
  671. {
  672. Firm* firmPtr = firm_array[spy_place_para];
  673. if( firmPtr->overseer_recno &&
  674. unit_array[firmPtr->overseer_recno]->spy_recno == spy_recno )
  675. {
  676. unit_array[firmPtr->overseer_recno]->spy_change_nation(newNationRecno, COMMAND_AUTO);
  677. return;
  678. }
  679. }
  680. err_here(); // cannot change a spy's cloaked_nation_recno in a firm and town as the spy's cloaked nation recno must be the same as the firm and town's nation recno
  681. }
  682. //---------- End of function Spy::change_cloaked_nation ----------//
  683. //--------- Begin of function Spy::can_change_cloaked_nation ----------//
  684. //
  685. // Return whether this spy can change its cloaked to the specific
  686. // nation right now.
  687. //
  688. // <int> newNationRecno - the new nation the spy changes its cloak to
  689. //
  690. int Spy::can_change_cloaked_nation(int newNationRecno)
  691. {
  692. //---- can always change back to its original nation ----//
  693. if( newNationRecno == true_nation_recno )
  694. return 1;
  695. //--- only mobile units and overseers can change nation, spies in firms or towns cannot change nation, their nation recno must be the same as the town or the firm's nation recno
  696. if( spy_place == SPY_MOBILE )
  697. {
  698. return unit_array[spy_place_para]->can_spy_change_nation();
  699. }
  700. else // can't change in firms or towns.
  701. {
  702. return 0;
  703. }
  704. }
  705. //---------- End of function Spy::can_change_cloaked_nation ----------//
  706. //--------- Begin of function Spy::capture_firm ----------//
  707. //
  708. // Order the spy to capture the firm he currently stays.
  709. //
  710. int Spy::capture_firm()
  711. {
  712. if( spy_place != SPY_FIRM )
  713. return 0;
  714. Firm* firmPtr = firm_array[spy_place_para];
  715. //------- if the spy is the overseer of the firm --------//
  716. if( firm_res[firmPtr->firm_id]->need_overseer )
  717. {
  718. //-----------------------------------------------------//
  719. //
  720. // If the firm needs an overseer, the firm can only be
  721. // captured if the spy is the overseer of the firm.
  722. //
  723. //-----------------------------------------------------//
  724. if( !firmPtr->overseer_recno ||
  725. unit_array[firmPtr->overseer_recno]->spy_recno != spy_recno )
  726. {
  727. return 0;
  728. }
  729. //---------------------------------------------------//
  730. //
  731. // For those soldiers who disagree with the spy general will
  732. // leave the command base and attack it. Soldiers who are not
  733. // racially homogenous to the spy general tend to disagree. Also
  734. // if the spy has a higher leadership, there will be a higher
  735. // chance for the soldiers to follow the general.
  736. //
  737. //---------------------------------------------------//
  738. Unit* unitPtr = unit_array[firmPtr->overseer_recno];
  739. if( !firm_res[firmPtr->firm_id]->live_in_town ) // if the workers of the firm do not live in towns
  740. {
  741. Worker* workerPtr = firmPtr->worker_array;
  742. int unitLeadership = unitPtr->skill.skill_level;
  743. int nationReputation = (int) nation_array[true_nation_recno]->reputation;
  744. int obeyChance, obeyFlag;
  745. for( int i=0 ; i<firmPtr->worker_count ; i++, workerPtr++ )
  746. {
  747. //-- if this worker is a spy, it will stay with you --//
  748. if( workerPtr->spy_recno )
  749. continue;
  750. //---- if this is a normal worker -----//
  751. obeyChance = unitLeadership/2 + nationReputation/2;
  752. if( race_res.is_same_race(workerPtr->race_id, race_id) )
  753. obeyChance += 50;
  754. obeyFlag = m.random(100) < obeyChance; // if obeyChance >= 100, all units will object the overseer
  755. //--- if the worker obey, update its loyalty ---//
  756. if( obeyFlag )
  757. workerPtr->worker_loyalty = max(UNIT_BETRAY_LOYALTY, obeyChance/2);
  758. //--- if the worker does not obey, it is mobilized and attack the base ---//
  759. else
  760. firmPtr->mobilize_worker(i+1, COMMAND_AUTO);
  761. }
  762. }
  763. //--------- add news message --------//
  764. if( firmPtr->nation_recno == nation_array.player_recno )
  765. news_array.firm_captured(spy_place_para, true_nation_recno, 1); // 1 - the capturer is a spy
  766. //-------- if this is an AI firm --------//
  767. if( firmPtr->firm_ai )
  768. firmPtr->ai_firm_captured(true_nation_recno);
  769. //----- the spy change nation and capture the firm -------//
  770. unitPtr->spy_change_nation(true_nation_recno, COMMAND_AUTO);
  771. }
  772. else
  773. {
  774. //------ otherwise the spy is a worker of the firm -------//
  775. //---- check whether it's true that the only units in the firms are our spies ---//
  776. Worker* workerPtr = firmPtr->worker_array;
  777. for( int i=0 ; i<firmPtr->worker_count ; i++, workerPtr++ )
  778. {
  779. if( !workerPtr->spy_recno ) // this worker is not a spy
  780. return 0;
  781. if( spy_array[workerPtr->spy_recno]->true_nation_recno != true_nation_recno )
  782. return 0; // this worker is a spy, but not belong to the same nation
  783. }
  784. //--------- add news message --------//
  785. if( firmPtr->nation_recno == nation_array.player_recno )
  786. news_array.firm_captured(spy_place_para, true_nation_recno, 1); // 1 - the capturer is a spy
  787. //-------- if this is an AI firm --------//
  788. if( firmPtr->firm_ai )
  789. firmPtr->ai_firm_captured(true_nation_recno);
  790. //----- change the firm's nation recno -----//
  791. firmPtr->change_nation(true_nation_recno); // the firm change nation and the spies inside the firm will have their cloaked nation recno changed
  792. }
  793. return 1;
  794. }
  795. //---------- End of function Spy::capture_firm ----------//
  796. //-------- Begin of function Spy::mobilize_spy ------//
  797. //
  798. // return: recno of the mobilized unit.
  799. //
  800. int Spy::mobilize_spy()
  801. {
  802. switch( spy_place )
  803. {
  804. case SPY_TOWN:
  805. return mobilize_town_spy();
  806. case SPY_FIRM:
  807. return mobilize_firm_spy();
  808. case SPY_MOBILE:
  809. err_when( !unit_array[spy_place_para]->is_visible() );
  810. return spy_place_para;
  811. default:
  812. return 0;
  813. }
  814. }
  815. //---------- End of function Spy::mobilize_spy --------//
  816. //-------- Begin of function Spy::mobilize_town_spy ------//
  817. //
  818. // [int] decPop - whether need to decrease the population of town when the spy is mobilized.
  819. // should set to no when it's calling from training a unit. (default: 1)
  820. //
  821. // return: recno of the mobilized unit.
  822. //
  823. int Spy::mobilize_town_spy(int decPop)
  824. {
  825. err_when( spy_place != SPY_TOWN );
  826. if( spy_place != SPY_TOWN )
  827. return 0;
  828. Town* townPtr = town_array[spy_place_para];
  829. int unitRecno = townPtr->mobilize_town_people(race_id, decPop, 1); //1-mobilize spies
  830. if( !unitRecno )
  831. return 0;
  832. Unit* unitPtr = unit_array[unitRecno]; // set the spy vars of the mobilized unit
  833. err_when( !unitPtr->is_visible() );
  834. unitPtr->spy_recno = spy_recno;
  835. unitPtr->set_name(name_id); // set the name id. of this unit
  836. set_place(SPY_MOBILE, unitRecno);
  837. return unitRecno;
  838. }
  839. //---------- End of function Spy::mobilize_town_spy --------//
  840. //-------- Begin of function Spy::mobilize_firm_spy ------//
  841. //
  842. // return: <int> unit recno of the spy mobilized.
  843. //
  844. int Spy::mobilize_firm_spy()
  845. {
  846. err_when( spy_place != SPY_FIRM );
  847. if( spy_place != SPY_FIRM )
  848. return 0;
  849. Firm* firmPtr = firm_array[spy_place_para];
  850. int spyUnitRecno=0;
  851. //---- check if the spy is the overseer of the firm -----//
  852. if( firmPtr->overseer_recno )
  853. {
  854. Unit* unitPtr = unit_array[firmPtr->overseer_recno];
  855. if( unitPtr->spy_recno == spy_recno )
  856. spyUnitRecno = firmPtr->mobilize_overseer();
  857. }
  858. //---- check if the spy is one of the workers of the firm ----//
  859. if( !spyUnitRecno )
  860. {
  861. int i;
  862. for( i=0 ; i<firmPtr->worker_count ; i++ )
  863. {
  864. if( firmPtr->worker_array[i].spy_recno == spy_recno )
  865. break;
  866. }
  867. err_when( i==firmPtr->worker_count );
  868. //---------- create a mobile unit ---------//
  869. spyUnitRecno = firmPtr->mobilize_worker(i+1, COMMAND_AUTO); // note: mobilize_woker() will decrease Firm::player_spy_count
  870. }
  871. return spyUnitRecno;
  872. }
  873. //---------- End of function Spy::mobilize_firm_spy --------//
  874. //-------- Begin of function Spy::think_become_king ------//
  875. //
  876. // If a nation has picked your spy to succeed to the died king,
  877. // you spy will either:
  878. //
  879. // >he captures the entire nation for you.
  880. // >he betrays you and rule his new empire.
  881. //
  882. void Spy::think_become_king()
  883. {
  884. err_when( spy_place != SPY_MOBILE ); // it must be mobile
  885. int hisNationPower = nation_array[cloaked_nation_recno]->overall_rating;
  886. int parentNationPower = nation_array[true_nation_recno]->overall_rating;
  887. //--- if his nation is more power than the player's nation, the chance of handing his nation over to his parent nation will be low unless the loyalty is very high ---//
  888. int acceptLoyalty = 90 + hisNationPower - parentNationPower;
  889. if( spy_loyalty >= acceptLoyalty &&
  890. nation_array[cloaked_nation_recno]->is_ai() ) // never will a spy take over the player's nation
  891. {
  892. //------ hand his nation over to his parent nation ------//
  893. nation_array[cloaked_nation_recno]->surrender(true_nation_recno);
  894. }
  895. else //--- betray his parent nation and rule the nation himself ---//
  896. {
  897. drop_spy_identity();
  898. }
  899. }
  900. //---------- End of function Spy::think_become_king --------//
  901. //-------- Begin of function Spy::cloaked_rank_id ------//
  902. //
  903. // Return the cloaked rank id. of this spy.
  904. //
  905. int Spy::cloaked_rank_id()
  906. {
  907. switch( spy_place )
  908. {
  909. case SPY_TOWN:
  910. return RANK_SOLDIER;
  911. case SPY_FIRM:
  912. {
  913. Firm* firmPtr = firm_array[spy_place_para];
  914. if( firmPtr->overseer_recno &&
  915. unit_array[firmPtr->overseer_recno]->spy_recno == spy_recno )
  916. {
  917. return RANK_GENERAL;
  918. }
  919. else
  920. {
  921. return RANK_SOLDIER;
  922. }
  923. }
  924. case SPY_MOBILE:
  925. return unit_array[spy_place_para]->rank_id;
  926. default:
  927. return RANK_SOLDIER;
  928. }
  929. }
  930. //---------- End of function Spy::cloaked_rank_id --------//
  931. //-------- Begin of function Spy::cloaked_skill_id ------//
  932. //
  933. // Return the cloaked skill id. of this spy.
  934. //
  935. int Spy::cloaked_skill_id()
  936. {
  937. switch( spy_place )
  938. {
  939. case SPY_TOWN:
  940. return 0;
  941. case SPY_FIRM:
  942. return firm_array[spy_place_para]->firm_skill_id;
  943. case SPY_MOBILE:
  944. return unit_array[spy_place_para]->skill.skill_id;
  945. default:
  946. return 0;
  947. }
  948. }
  949. //---------- End of function Spy::cloaked_skill_id --------//
  950. //-------- Begin of function Spy::reward ------//
  951. //
  952. // The owner nation of the spy rewards him.
  953. //
  954. void Spy::reward(int remoteAction)
  955. {
  956. if( !remoteAction && remote.is_enable() )
  957. {
  958. // packet structure <spy recno>
  959. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_SPY_REWARD, sizeof(short));
  960. shortPtr[0] = spy_recno;
  961. return;
  962. }
  963. change_loyalty(REWARD_LOYALTY_INCREASE);
  964. nation_array[true_nation_recno]->add_expense(EXPENSE_REWARD_UNIT, (float)REWARD_COST);
  965. }
  966. //---------- End of function Spy::reward --------//
  967. //-------- Begin of function Spy::set_exposed ------//
  968. //
  969. // Enable the exposed_flag of the spy. The spy will get killed
  970. // should when he has been exposed.
  971. //
  972. void Spy::set_exposed(int remoteAction)
  973. {
  974. // ##### begin Gilbert 26/9 #######//
  975. if( !remoteAction && remote.is_enable() )
  976. {
  977. // packet structure <spy recno>
  978. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_SPY_EXPOSED, sizeof(short));
  979. shortPtr[0] = spy_recno;
  980. return;
  981. }
  982. // ##### end Gilbert 26/9 #######//
  983. exposed_flag = 1;
  984. }
  985. //---------- End of function Spy::set_exposed --------//
  986. //-------- Begin of function Spy::assassinate ------//
  987. //
  988. // <int> targetUnitRecno - the recno of the unit to assassinate.
  989. // <int> remoteAction - remote action type.
  990. //
  991. // If this is a player's spy, the result of the assassination
  992. // will be set to Firm::assassinate_result.
  993. //
  994. int Spy::assassinate(int targetUnitRecno, int remoteAction)
  995. {
  996. if( !remoteAction && remote.is_enable() )
  997. {
  998. // packet structure <spy recno>
  999. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_SPY_ASSASSINATE, sizeof(short)*2);
  1000. shortPtr[0] = spy_recno;
  1001. shortPtr[1] = targetUnitRecno;
  1002. return 0;
  1003. }
  1004. //---------- validate first -----------//
  1005. if( spy_place != SPY_FIRM )
  1006. return 0;
  1007. Unit* targetUnit = unit_array[targetUnitRecno];
  1008. if( targetUnit->unit_mode != UNIT_MODE_OVERSEE )
  1009. return 0;
  1010. Firm* firmPtr = firm_array[ targetUnit->unit_mode_para ];
  1011. if( firmPtr->firm_recno != spy_place_para )
  1012. return 0;
  1013. //---- get the attack and defense rating ----//
  1014. int attackRating, defenseRating, otherDefenderCount;
  1015. if( !get_assassinate_rating(targetUnitRecno, attackRating, defenseRating, otherDefenderCount) )
  1016. return 0;
  1017. //-------------------------------------------//
  1018. int rc;
  1019. int trueNationRecno = true_nation_recno; // need to save it first as the spy may be killed later
  1020. if( attackRating >= defenseRating )
  1021. {
  1022. //--- whether the spy will be get caught and killed in the mission ---//
  1023. int spyKillFlag = otherDefenderCount > 0 && attackRating - defenseRating < 80;
  1024. //--- if the unit assassinated is the player's unit ---//
  1025. if( targetUnit->nation_recno == nation_array.player_recno )
  1026. news_array.unit_assassinated(targetUnit->sprite_recno, spyKillFlag);
  1027. firmPtr->kill_overseer();
  1028. //-----------------------------------------------------//
  1029. // If there are other defenders in the firm and
  1030. // the difference between the attack rating and defense rating
  1031. // is small, then then spy will be caught and executed.
  1032. //-----------------------------------------------------//
  1033. if( spyKillFlag )
  1034. {
  1035. get_killed(0); // 0 - don't display new message for the spy being killed
  1036. rc = ASSASSINATE_SUCCEED_KILLED;
  1037. }
  1038. else
  1039. {
  1040. rc = ASSASSINATE_SUCCEED_AT_LARGE;
  1041. }
  1042. }
  1043. else //----- if the assassination fails --------//
  1044. {
  1045. //-- if the spy is attempting to assassinate the player's general or king --//
  1046. // don't display the below news message as the killing of the spy will already be displayed in news_array.spy_killed()
  1047. // if( targetUnit->nation_recno == nation_array.player_recno )
  1048. // news_array.assassinator_caught(spy_recno, targetUnit->rank_id);
  1049. get_killed(0); // 0 - don't display new message for the spy being killed
  1050. rc = ASSASSINATE_FAIL;
  1051. }
  1052. //--- if this firm is the selected firm and the spy is the player's spy ---//
  1053. if( trueNationRecno == nation_array.player_recno &&
  1054. firmPtr->firm_recno == firm_array.selected_recno )
  1055. {
  1056. firmPtr->assassinate_result = rc;
  1057. firmPtr->firm_menu_mode = FIRM_MENU_ASSASSINATE_RESULT;
  1058. info.disp();
  1059. }
  1060. return rc;
  1061. }
  1062. //---------- End of function Spy::assassinate --------//
  1063. //-------- Begin of function Spy::get_assassinate_rating ------//
  1064. //
  1065. int Spy::get_assassinate_rating(int targetUnitRecno, int& attackRating, int& defenseRating, int& otherDefenderCount)
  1066. {
  1067. //---------- validate first -----------//
  1068. if( spy_place != SPY_FIRM )
  1069. return 0;
  1070. Unit* targetUnit = unit_array[targetUnitRecno];
  1071. if( targetUnit->unit_mode != UNIT_MODE_OVERSEE )
  1072. return 0;
  1073. Firm* firmPtr = firm_array[ targetUnit->unit_mode_para ];
  1074. if( firmPtr->firm_recno != spy_place_para )
  1075. return 0;
  1076. //------ get the hit points of the spy ----//
  1077. int spyHitPoints;
  1078. int i;
  1079. for( i=0 ; i<firmPtr->worker_count ; i++ )
  1080. {
  1081. if( firmPtr->worker_array[i].spy_recno == spy_recno )
  1082. {
  1083. spyHitPoints = firmPtr->worker_array[i].hit_points;
  1084. break;
  1085. }
  1086. }
  1087. err_when( i==firmPtr->worker_count );
  1088. //------ calculate success chance ------//
  1089. attackRating = spy_skill + spyHitPoints/2;
  1090. defenseRating = (int) targetUnit->hit_points/2;
  1091. otherDefenderCount=0;
  1092. if( targetUnit->spy_recno )
  1093. defenseRating += spy_array[targetUnit->spy_recno]->spy_skill;
  1094. if( targetUnit->rank_id == RANK_KING )
  1095. defenseRating += 50;
  1096. for( i=0 ; i<firmPtr->worker_count ; i++ )
  1097. {
  1098. int spyRecno = firmPtr->worker_array[i].spy_recno;
  1099. //------ if this worker is a spy ------//
  1100. if( spyRecno )
  1101. {
  1102. Spy* spyPtr = spy_array[spyRecno];
  1103. if( spyPtr->true_nation_recno == true_nation_recno ) // our spy
  1104. {
  1105. attackRating += spyPtr->spy_skill/4;
  1106. }
  1107. else if( spyPtr->true_nation_recno == firmPtr->nation_recno ) // enemy spy
  1108. {
  1109. defenseRating += spyPtr->spy_skill/2;
  1110. otherDefenderCount++;
  1111. }
  1112. }
  1113. else //----- if this worker is not a spy ------//
  1114. {
  1115. defenseRating += 4 + firmPtr->worker_array[i].hit_points/30;
  1116. otherDefenderCount++;
  1117. }
  1118. }
  1119. //-------- if the assassination succeeds -------//
  1120. defenseRating += 30 + m.random(30);
  1121. return 1;
  1122. }
  1123. //---------- End of function Spy::get_assassinate_rating --------//