OUNIT.cpp 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757
  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 : OUNIT.CPP
  21. //Description : Object Unit
  22. #include <ALL.h>
  23. #include <ODATE.h>
  24. #include <OWORLD.h>
  25. #include <OVGA.h>
  26. #include <OSTR.h>
  27. #include <ONEWS.h>
  28. #include <OREBEL.h>
  29. #include <OSPY.h>
  30. #include <ONATION.h>
  31. #include <OFONT.h>
  32. #include <OBULLET.h>
  33. #include <OGAME.h>
  34. #include <OTOWN.h>
  35. #include <ORACERES.h>
  36. #include <ORAWRES.h>
  37. #include <OPOWER.h>
  38. #include <OU_VEHI.h>
  39. #include <OU_MARI.h>
  40. #include <OU_MONS.h>
  41. #include <OF_CAMP.h>
  42. #include <OF_MONS.h>
  43. #include <OF_HARB.h>
  44. #include <OMONSRES.h>
  45. #include <OREMOTE.h>
  46. #include <OSYS.h>
  47. #if(GAME_FRAMES_PER_DAY!=FRAMES_PER_DAY)
  48. #error
  49. #endif
  50. #ifdef NO_DEBUG_UNIT
  51. #undef err_when
  52. #undef err_here
  53. #undef err_if
  54. #undef err_else
  55. #undef err_now
  56. #define err_when(cond)
  57. #define err_here()
  58. #define err_if(cond)
  59. #define err_else
  60. #define err_now(msg)
  61. #undef DEBUG
  62. #endif
  63. //--------- Begin of function Unit::Unit ---------//
  64. //
  65. Unit::Unit()
  66. {
  67. // ##### patch begin Gilbert 21/1 ######//
  68. // unit_id = 0;
  69. memset( sizeof(Sprite) + (char *)this, 0, sizeof(Unit) - sizeof(Sprite));
  70. // ##### patch end Gilbert 21/1 ######//
  71. }
  72. //----------- End of function Unit::Unit -----------//
  73. //--------- Begin of function Unit::~Unit ---------//
  74. //
  75. Unit::~Unit()
  76. {
  77. deinit();
  78. }
  79. //----------- End of function Unit::~Unit -----------//
  80. //--------- Begin of function Unit::init ---------//
  81. //
  82. // <int> unitId - the id. of the unit
  83. // <int> nationRecno - the recno of nation
  84. // [int] rankId - rank id. of the unit (none for non-human unit)
  85. // [int] unitLoyalty - loyalty of the unit (none for non-human unit)
  86. // [int] startXLoc, startYLoc - the starting location of the unit
  87. // (if startXLoc < 0, this is a unit for hire, and is not a unit of the game yet. init_sprite() won't be called for this unit)
  88. // (default: -1, -1)
  89. //
  90. // Note: sprite_recno must be initialized first before calling Unit::init()
  91. //
  92. void Unit::init(int unitId, int nationRecno, int rankId, int unitLoyalty, int startXLoc, int startYLoc)
  93. {
  94. //------------ set basic vars -------------//
  95. nation_recno = (char) nationRecno;
  96. rank_id = rankId; // rank_id must be initialized before init_unit_id() as init_unit_id() may overwrite it
  97. nation_contribution = 0; // nation_contribution must be initialized before init_unit_id() as init_unit_id() may overwrite it
  98. if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
  99. {
  100. team_info = (TeamInfo*) mem_add( sizeof(TeamInfo) );
  101. team_info->member_count = 0;
  102. }
  103. else
  104. team_info = NULL;
  105. init_unit_id(unitId);
  106. group_select_id = 0;
  107. unit_group_id = unit_array.cur_group_id++;
  108. race_id = (char) unit_res[unit_id]->race_id;
  109. //------- init unit name ---------//
  110. if( race_id )
  111. {
  112. name_id = race_res[race_id]->get_new_name_id();
  113. }
  114. else //---- init non-human unit series no. ----//
  115. {
  116. if( nation_recno )
  117. name_id = ++nation_array[nation_recno]->last_unit_name_id_array[unit_id-1];
  118. else
  119. name_id = 0;
  120. }
  121. //------- init ai_unit ----------//
  122. if( nation_recno )
  123. ai_unit = nation_array[nation_recno]->nation_type == NATION_AI;
  124. else
  125. ai_unit = 0;
  126. err_when( unitLoyalty < 0 || unitLoyalty > 100 );
  127. //----------------------------------------------//
  128. ai_action_id = 0;
  129. action_misc = ACTION_MISC_STOP;
  130. action_misc_para = 0;
  131. action_mode2 = action_mode = ACTION_STOP;
  132. action_para2 = action_para = 0;
  133. action_x_loc2 = action_y_loc2 = action_x_loc = action_y_loc = -1;
  134. memset(blocked_edge, 0, sizeof(char)*4);
  135. attack_range = 0; //store the attack range of the current attack mode if the unit is ordered to attack
  136. leader_unit_recno= 0;
  137. team_id = 0;
  138. selected_flag = 0;
  139. waiting_term = 0;
  140. swapping = 0; // indicate whether swapping is processed.
  141. spy_recno = 0;
  142. range_attack_x_loc = -1;
  143. range_attack_y_loc = -1;
  144. //------- initialize path seek vars -------//
  145. result_node_array = NULL;
  146. result_node_count = result_node_recno = result_path_dist = 0;
  147. //------- initialize way point vars -------//
  148. way_point_array = NULL;
  149. way_point_array_size = 0;
  150. way_point_count = 0;
  151. //---------- initialize game vars ----------//
  152. unit_mode = 0;
  153. unit_mode_para = 0;
  154. max_hit_points = unit_res[unit_id]->hit_points;
  155. hit_points = max_hit_points;
  156. loyalty = unitLoyalty;
  157. can_guard_flag = 0;
  158. can_attack_flag = 1;
  159. force_move_flag = 0;
  160. ai_no_suitable_action = 0;
  161. cur_power = 0;
  162. max_power = 0;
  163. total_reward = 0;
  164. home_camp_firm_recno = 0;
  165. seek_path_fail_count = 0;
  166. ignore_power_nation = 0;
  167. aggressive_mode = 1; // the default mode is 1
  168. err_when( loyalty<0 || loyalty>100 );
  169. //--------- init skill potential ---------//
  170. if( m.random(10)==0 ) // 1 out of 10 has a higher than normal potential in this skill
  171. {
  172. skill.skill_potential = 50+m.random(51); // 50 to 100 potential
  173. }
  174. //------ initialize the base Sprite class -------//
  175. if( startXLoc >= 0 )
  176. init_sprite( startXLoc, startYLoc );
  177. else
  178. {
  179. cur_x = -1;
  180. }
  181. //------------- set attack_dir ------------//
  182. attack_dir = final_dir;
  183. //-------------- update loyalty -------------//
  184. update_loyalty();
  185. //--------------- init AI info -------------//
  186. if( ai_unit )
  187. {
  188. Nation* nationPtr = nation_array[nation_recno];
  189. if( rank_id==RANK_GENERAL || rank_id==RANK_KING )
  190. nationPtr->add_general_info(sprite_recno);
  191. switch( unit_res[unit_id]->unit_class )
  192. {
  193. case UNIT_CLASS_CARAVAN:
  194. nationPtr->add_caravan_info(sprite_recno);
  195. break;
  196. case UNIT_CLASS_SHIP:
  197. nationPtr->add_ship_info(sprite_recno);
  198. break;
  199. }
  200. }
  201. //----------- init derived class ----------//
  202. init_derived();
  203. }
  204. //----------- End of function Unit::init -----------//
  205. //--------- Begin of function Unit::init_unit_id ---------//
  206. void Unit::init_unit_id(int unitId)
  207. {
  208. unit_id = unitId;
  209. UnitInfo* unitInfo = unit_res[unit_id];
  210. sprite_id = unitInfo->sprite_id;
  211. sprite_info = sprite_res[sprite_id];
  212. mobile_type = unitInfo->mobile_type;
  213. //--- if this unit is a weapon unit with multiple versions ---//
  214. set_combat_level(100); // set combat level default to 100, for human units, it will be adjusted later by individual functions
  215. int techLevel;
  216. if( nation_recno &&
  217. unitInfo->unit_class == UNIT_CLASS_WEAPON &&
  218. (techLevel=unitInfo->nation_tech_level_array[nation_recno-1]) > 0 )
  219. {
  220. set_weapon_version(techLevel);
  221. }
  222. fix_attack_info();
  223. //-------- set unit count ----------//
  224. if( nation_recno )
  225. {
  226. if( rank_id != RANK_KING )
  227. unitInfo->inc_nation_unit_count(nation_recno);
  228. if( rank_id == RANK_GENERAL )
  229. unitInfo->inc_nation_general_count(nation_recno);
  230. }
  231. //--------- increase monster count ----------//
  232. if( unit_res[unit_id]->unit_class == UNIT_CLASS_MONSTER )
  233. unit_res.mobile_monster_count++;
  234. }
  235. //----------- End of function Unit::init_unit_id -----------//
  236. //--------- Begin of function Unit::deinit_unit_id ---------//
  237. void Unit::deinit_unit_id()
  238. {
  239. if( sys.signal_exit_flag )
  240. return;
  241. //-----------------------------------------//
  242. UnitInfo *unitInfo = unit_res[unit_id];
  243. if( nation_recno )
  244. {
  245. if( rank_id != RANK_KING )
  246. unitInfo->dec_nation_unit_count(nation_recno);
  247. if( rank_id == RANK_GENERAL )
  248. unitInfo->dec_nation_general_count(nation_recno);
  249. }
  250. //--------- if the unit is a spy ----------//
  251. //
  252. // A spy has double identity and is counted
  253. // by both the true controlling nation and
  254. // the deceiving nation.
  255. //
  256. //-----------------------------------------//
  257. if( spy_recno && true_nation_recno() != nation_recno )
  258. {
  259. err_when( !race_id );
  260. int trueNationRecno = true_nation_recno();
  261. if( rank_id != RANK_KING )
  262. unitInfo->dec_nation_unit_count(trueNationRecno);
  263. if( rank_id == RANK_GENERAL )
  264. unitInfo->dec_nation_general_count(trueNationRecno);
  265. }
  266. //--------- decrease monster count ----------//
  267. if( unit_res[unit_id]->unit_class == UNIT_CLASS_MONSTER )
  268. {
  269. unit_res.mobile_monster_count--;
  270. err_when( unit_res.mobile_monster_count < 0 );
  271. }
  272. }
  273. //----------- End of function Unit::deinit_unit_id -----------//
  274. //--------- Begin of function Unit::set_spy ---------//
  275. void Unit::set_spy(int spyRecno)
  276. {
  277. spy_recno = spyRecno;
  278. }
  279. //---------- End of function Unit::set_spy ---------//
  280. //--------- Begin of function Unit::init_sprite ---------//
  281. //
  282. // <int> startXLoc, startYLoc - the starting location of the unit
  283. //
  284. void Unit::init_sprite(int startXLoc, int startYLoc)
  285. {
  286. err_when( !world.get_loc(startXLoc, startYLoc)->can_move(unit_res[unit_id]->mobile_type) );
  287. err_when(unit_res[unit_id]->unit_class==UNIT_CLASS_SHIP && (startXLoc%2 || startYLoc%2));
  288. Sprite::init(unit_res[unit_id]->sprite_id, startXLoc, startYLoc);
  289. //--------------------------------------------------------------------//
  290. // move_to_?_loc is always the current location of the unit as
  291. // cur_action == SPRITE_IDLE
  292. //--------------------------------------------------------------------//
  293. original_action_mode = 0;
  294. ai_original_target_x_loc = -1;
  295. attack_range = 0;
  296. move_to_x_loc = next_x_loc();
  297. move_to_y_loc = next_y_loc();
  298. go_x = next_x;
  299. go_y = next_y;
  300. //-------- set the cargo_recno -------------//
  301. char w, h;
  302. short x, y;
  303. err_if(!sprite_recno) // sprite_recno must be initialized first before calling Unit::init()
  304. err_here();
  305. for(h=0, y=startYLoc; h<sprite_info->loc_height; h++, y++)
  306. {
  307. for(w=0, x=startXLoc; w<sprite_info->loc_width; w++, x++)
  308. {
  309. err_if( world.get_unit_recno(x, y, mobile_type) ) // it must be 0 to put the sprite in this location
  310. err_here();
  311. world.set_unit_recno(x, y, mobile_type, sprite_recno);
  312. }
  313. }
  314. if( is_own() ||
  315. (nation_recno && nation_array[nation_recno]->is_allied_with_player) )
  316. {
  317. world.unveil(startXLoc, startYLoc, startXLoc+sprite_info->loc_width-1,
  318. startYLoc+sprite_info->loc_height-1 );
  319. world.visit(startXLoc, startYLoc, startXLoc+sprite_info->loc_width-1,
  320. startYLoc+sprite_info->loc_height-1, unit_res[unit_id]->visual_range,
  321. unit_res[unit_id]->visual_extend);
  322. }
  323. err_when(result_node_array || result_path_dist);
  324. }
  325. //----------- End of function Unit::init_sprite -----------//
  326. //--------- Begin of function Unit::deinit ---------//
  327. void Unit::deinit()
  328. {
  329. err_when( unit_array.is_truly_deleted(sprite_recno) );
  330. if( !unit_id )
  331. return;
  332. //-------- if this is a king --------//
  333. if( !sys.signal_exit_flag && nation_recno )
  334. {
  335. if( rank_id == RANK_KING ) // check nation_recno because monster kings will die also.
  336. {
  337. king_die();
  338. err_when( unit_array.is_truly_deleted(sprite_recno) );
  339. }
  340. else if( rank_id == RANK_GENERAL )
  341. {
  342. general_die();
  343. err_when( unit_array.is_truly_deleted(sprite_recno) );
  344. }
  345. }
  346. //------------ free up team_info -----------//
  347. if( team_info )
  348. {
  349. mem_del(team_info);
  350. team_info = NULL;
  351. }
  352. //---- if this is a general, deinit its link with its soldiers ----//
  353. //
  354. // We do not use team_info because monsters and rebels also use
  355. // leader_unit_recno and they do not use keep the member info
  356. // in team_info.
  357. //
  358. //-----------------------------------------------------------------//
  359. if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
  360. {
  361. for( int i=unit_array.size() ; i>0 ; i-- )
  362. {
  363. if( unit_array.is_deleted(i) )
  364. continue;
  365. if( unit_array[i]->leader_unit_recno == sprite_recno )
  366. unit_array[i]->leader_unit_recno = 0;
  367. }
  368. }
  369. //----- if this is a unit on a ship ------//
  370. if( unit_mode == UNIT_MODE_ON_SHIP )
  371. {
  372. if( !unit_array.is_deleted(unit_mode_para) ) // the ship may have been destroyed at the same time. Actually when the ship is destroyed, all units onboard are killed and this function is called.
  373. {
  374. Unit* unitPtr = unit_array[unit_mode_para];
  375. err_when( unit_res[unitPtr->unit_id]->unit_class != UNIT_CLASS_SHIP );
  376. ((UnitMarine*)unitPtr)->del_unit(sprite_recno);
  377. }
  378. }
  379. //----- if this is a ship in the harbor -----//
  380. else if( unit_mode == UNIT_MODE_IN_HARBOR )
  381. {
  382. if( !firm_array.is_deleted(unit_mode_para) ) // the ship may have been destroyed at the same time. Actually when the ship is destroyed, all firms onboard are killed and this function is called.
  383. {
  384. Firm* firmPtr = firm_array[unit_mode_para];
  385. err_when( firmPtr->firm_id != FIRM_HARBOR );
  386. ((FirmHarbor*)firmPtr)->del_hosted_ship(sprite_recno);
  387. }
  388. }
  389. //----- if this unit is a constructor in a firm -------//
  390. else if( unit_mode == UNIT_MODE_CONSTRUCT )
  391. {
  392. err_when( firm_array[unit_mode_para]->builder_recno != sprite_recno );
  393. firm_array[unit_mode_para]->builder_recno = 0;
  394. }
  395. //-------- if this is a spy ---------//
  396. if( spy_recno )
  397. {
  398. spy_array.del_spy( spy_recno );
  399. spy_recno = 0;
  400. }
  401. //---------- reset command ----------//
  402. if( power.command_unit_recno == sprite_recno )
  403. power.reset_command();
  404. //-----------------------------------//
  405. deinit_unit_id();
  406. //-------- reset seek path ----------//
  407. reset_path();
  408. //----- if cur_x == -1, the unit has not yet been hired -----//
  409. if( cur_x >= 0 )
  410. deinit_sprite();
  411. //------------------------------------------------//
  412. //
  413. // Prime rule:
  414. //
  415. // world.get_loc(next_x_loc() and next_y_loc())->cargo_recno
  416. // is always = sprite_recno
  417. //
  418. // no matter what cur_action is.
  419. //
  420. //------------------------------------------------//
  421. //
  422. // Relationship between (next_x, next_y) and (cur_x, cur_y)
  423. //
  424. // when SPRITE_WAIT, SPRITE_IDLE, SPRITE_READY_TO_MOVE,
  425. // SPRITE_ATTACK, SPRITE_DIE:
  426. //
  427. // (next_x, next_y) == (cur_x, cur_y), it's the location of the sprite.
  428. //
  429. // when SPRITE_MOVE:
  430. //
  431. // (next_x, next_y) != (cur_x, cur_y)
  432. // (next_x, next_y) is where the sprite is moving towards.
  433. // (cur_x , cur_y ) is the location of the sprite.
  434. //
  435. //------------------------------------------------//
  436. //--------------- deinit AI info -------------//
  437. if( ai_unit )
  438. {
  439. if( !nation_array.is_deleted(nation_recno) )
  440. {
  441. Nation* nationPtr = nation_array[nation_recno];
  442. if( rank_id==RANK_GENERAL || rank_id==RANK_KING )
  443. nationPtr->del_general_info(sprite_recno);
  444. switch( unit_res[unit_id]->unit_class )
  445. {
  446. case UNIT_CLASS_CARAVAN:
  447. nationPtr->del_caravan_info(sprite_recno);
  448. break;
  449. case UNIT_CLASS_SHIP:
  450. nationPtr->del_ship_info(sprite_recno);
  451. break;
  452. }
  453. }
  454. }
  455. //-------------- reset unit_id ---------------//
  456. unit_id = 0;
  457. }
  458. //----------- End of function Unit::deinit -----------//
  459. //--------- Begin of function Unit::deinit_sprite ---------//
  460. //
  461. // [int] keepSelected - keep it selected if it is current selected.
  462. // (default: 0)
  463. //
  464. void Unit::deinit_sprite(int keepSelected)
  465. {
  466. err_when(result_node_array!=NULL);
  467. if( cur_x == -1 )
  468. return;
  469. //---- if this unit is led by a leader, only mobile units has leader_unit_recno assigned to a leader -----//
  470. if( leader_unit_recno )
  471. {
  472. if( !unit_array.is_deleted(leader_unit_recno) ) // the leader unit may have been killed at the same time
  473. unit_array[leader_unit_recno]->del_team_member(sprite_recno);
  474. leader_unit_recno = 0;
  475. }
  476. //-------- clear the cargo_recno ----------//
  477. short w, h;
  478. short x, y;
  479. for(h=0, y=next_y_loc(); h<sprite_info->loc_height; h++, y++)
  480. {
  481. for(w=0, x=next_x_loc(); w<sprite_info->loc_width; w++, x++)
  482. {
  483. err_if( world.get_unit_recno(x, y, mobile_type) != sprite_recno ) // it must be 0 to put the sprite in this location
  484. err_here();
  485. world.set_unit_recno(x, y, mobile_type, 0);
  486. }
  487. }
  488. cur_x = -1;
  489. //---- reset other parameters related to this unit ----//
  490. if( !keepSelected )
  491. {
  492. if( unit_array.selected_recno == sprite_recno )
  493. {
  494. unit_array.selected_recno = 0;
  495. info.disp();
  496. }
  497. if( power.command_unit_recno == sprite_recno )
  498. power.command_id = 0;
  499. }
  500. //------- deinit unit mode -------//
  501. deinit_unit_mode();
  502. }
  503. //----------- End of function Unit::deinit_sprite -----------//
  504. //--------- Begin of function Unit::deinit_unit_mode ---------//
  505. //
  506. void Unit::deinit_unit_mode()
  507. {
  508. if( sys.signal_exit_flag )
  509. return;
  510. //----- this unit was defending the town before it gets killed ----//
  511. if(unit_mode==UNIT_MODE_DEFEND_TOWN)
  512. {
  513. if(!town_array.is_deleted(unit_mode_para))
  514. {
  515. Town *townPtr = town_array[unit_mode_para];
  516. if(nation_recno == townPtr->nation_recno)
  517. townPtr->reduce_defender_count();
  518. }
  519. set_mode(0); // reset mode
  520. }
  521. //----- this is a monster unit defending its town ------//
  522. else if( unit_mode==UNIT_MODE_MONSTER && unit_mode_para )
  523. {
  524. if(((UnitMonster*)this)->monster_action_mode!=MONSTER_ACTION_DEFENSE)
  525. return;
  526. FirmMonster* firmMonster = (FirmMonster*) firm_array[unit_mode_para];
  527. err_when( firmMonster->firm_id != FIRM_MONSTER );
  528. firmMonster->reduce_defender_count(rank_id);
  529. }
  530. }
  531. //----------- End of function Unit::deinit_unit_mode -----------//
  532. //--------- Begin of function Unit::king_die ---------//
  533. //
  534. void Unit::king_die()
  535. {
  536. //--------- add news ---------//
  537. news_array.king_die(nation_recno);
  538. //--- see if the units, firms and towns of the nation are all destroyed ---//
  539. Nation* nationPtr = nation_array[nation_recno];
  540. nationPtr->king_unit_recno = 0;
  541. }
  542. //----------- End of function Unit::king_die -----------//
  543. //--------- Begin of function Unit::general_die ---------//
  544. //
  545. void Unit::general_die()
  546. {
  547. //--------- add news ---------//
  548. if( nation_recno == nation_array.player_recno )
  549. news_array.general_die(sprite_recno);
  550. }
  551. //----------- End of function Unit::general_die -----------//
  552. //--------- Begin of function Unit::unit_name ---------//
  553. //
  554. // [int] withTitle - whether return a string with the title of the unit
  555. // or not. (default: 1)
  556. //
  557. char* Unit::unit_name(int withTitle)
  558. {
  559. static String str;
  560. UnitInfo* unitInfo = unit_res[unit_id];
  561. //------------------------------------//
  562. if( race_id )
  563. {
  564. str = "";
  565. if( withTitle )
  566. {
  567. if( unit_mode == UNIT_MODE_REBEL )
  568. {
  569. if( rank_id == RANK_GENERAL )
  570. str = "Rebel Leader ";
  571. }
  572. else
  573. {
  574. if( rank_id == RANK_KING )
  575. str = "King ";
  576. else if( rank_id == RANK_GENERAL )
  577. str = "General ";
  578. }
  579. }
  580. str = translate.process(str);
  581. if( rank_id == RANK_KING ) // use the player name
  582. str += nation_array[nation_recno]->king_name();
  583. else
  584. str += race_res[race_id]->get_name(name_id);
  585. }
  586. else
  587. {
  588. str = unitInfo->name;
  589. //--- for weapons, the rank_id is used to store the version of the weapon ---//
  590. if( unitInfo->unit_class == UNIT_CLASS_WEAPON && get_weapon_version() > 1 )
  591. {
  592. str += " ";
  593. str += m.roman_number(get_weapon_version());
  594. }
  595. if( unitInfo->unit_class != UNIT_CLASS_GOD ) // God doesn't have any series no.
  596. {
  597. str += " ";
  598. str += name_id; // name id is the series no. of the unit
  599. }
  600. }
  601. return str;
  602. }
  603. //----------- End of function Unit::unit_name ---------//
  604. //--------- Begin of function Unit::set_name ---------//
  605. //
  606. // Set the name id. of this unit.
  607. //
  608. void Unit::set_name(WORD newNameId)
  609. {
  610. //------- free up the existing name id. ------//
  611. race_res[race_id]->free_name_id(name_id);
  612. //------- set the new name id. ---------//
  613. name_id = newNameId;
  614. //-------- register usage of the new name id. ------//
  615. race_res[race_id]->use_name_id(name_id);
  616. }
  617. //----------- End of function Unit::set_name ---------//
  618. //--------- Begin of function Unit::is_own ---------//
  619. //
  620. int Unit::is_own()
  621. {
  622. return is_nation(nation_array.player_recno);
  623. }
  624. //----------- End of function Unit::is_own ---------//
  625. //--------- Begin of function Unit::is_own_spy ---------//
  626. //
  627. int Unit::is_own_spy()
  628. {
  629. return spy_recno && spy_array[spy_recno]->true_nation_recno == nation_array.player_recno;
  630. }
  631. //----------- End of function Unit::is_own_spy ---------//
  632. //--------- Begin of function Unit::is_nation ---------//
  633. //
  634. // Whether the unit belongs to the specific nation.
  635. //
  636. int Unit::is_nation(int nationRecno)
  637. {
  638. if( nation_recno == nationRecno )
  639. return 1;
  640. if( spy_recno && spy_array[spy_recno]->true_nation_recno == nationRecno )
  641. return 1;
  642. return 0;
  643. }
  644. //----------- End of function Unit::is_nation ---------//
  645. //--------- Begin of function Unit::is_civilian ---------//
  646. //
  647. int Unit::is_civilian()
  648. {
  649. return race_id>0 && skill.combat_level<20 &&
  650. skill.skill_id != SKILL_LEADING &&
  651. unit_mode != UNIT_MODE_DEFEND_TOWN &&
  652. unit_mode != UNIT_MODE_REBEL;
  653. }
  654. //----------- End of function Unit::is_civilian ---------//
  655. //--------- Begin of function Unit::true_nation_recno ---------//
  656. //
  657. // The true nation recno of the unit, taking care of the
  658. // situation where the unit is a spy.
  659. //
  660. int Unit::true_nation_recno()
  661. {
  662. if( spy_recno )
  663. return spy_array[spy_recno]->true_nation_recno;
  664. else
  665. return nation_recno;
  666. }
  667. //----------- End of function Unit::true_nation_recno ---------//
  668. //--------- Begin of function Unit::next_day ---------//
  669. //
  670. void Unit::next_day()
  671. {
  672. int unitRecno = sprite_recno;
  673. err_when( unit_array.is_deleted(unitRecno) );
  674. err_when( race_id && !is_visible() && unit_mode==0 );
  675. #ifdef DEBUG
  676. if( unit_mode == UNIT_MODE_UNDER_TRAINING )
  677. {
  678. Town* townPtr =town_array[unit_mode_para];
  679. err_when( townPtr->train_unit_recno != sprite_recno );
  680. err_when( townPtr->nation_recno != nation_recno );
  681. }
  682. #endif
  683. //------- functions for non-independent nations only ------//
  684. if( nation_recno )
  685. {
  686. pay_expense();
  687. if( unit_array.is_deleted(unitRecno) ) // if its hit points go down to 0, is_deleted() will return 1.
  688. return;
  689. //------- update loyalty -------------//
  690. if( info.game_date%30 == sprite_recno%30 )
  691. {
  692. update_loyalty();
  693. err_when( unit_array.is_deleted(unitRecno) );
  694. }
  695. //------- think about rebeling -------------//
  696. if( info.game_date%15 == sprite_recno%15 )
  697. {
  698. if( think_betray() )
  699. return;
  700. }
  701. }
  702. //------- recover from damage -------//
  703. if( info.game_date%15 == sprite_recno%15 ) // recover one point per two weeks
  704. {
  705. process_recover();
  706. err_when( unit_array.is_deleted(unitRecno) );
  707. }
  708. //------- restore cur_power --------//
  709. cur_power += 5;
  710. if( cur_power > max_power)
  711. cur_power = max_power;
  712. //------- king undie flag (for testing games only) --------//
  713. if( config.king_undie_flag && rank_id == RANK_KING &&
  714. nation_recno && !nation_array[nation_recno]->is_ai() )
  715. {
  716. hit_points = max_hit_points;
  717. }
  718. //-------- if aggresive_mode is 1 --------//
  719. if( nation_recno && is_visible() )
  720. think_aggressive_action();
  721. //---------- debug ------------//
  722. #ifdef DEBUG
  723. err_when( unit_res[unit_id]->unit_class != UNIT_CLASS_HUMAN && race_id );
  724. if( spy_recno )
  725. {
  726. err_when( spy_array.is_deleted(spy_recno) );
  727. Spy* spyPtr = spy_array[spy_recno];
  728. err_when( nation_recno != spyPtr->cloaked_nation_recno );
  729. if( unit_mode == UNIT_MODE_OVERSEE )
  730. {
  731. err_when( spyPtr->spy_place != SPY_FIRM );
  732. err_when( spyPtr->spy_place_para != unit_mode_para );
  733. }
  734. else
  735. {
  736. err_when( spyPtr->spy_place != SPY_MOBILE );
  737. err_when( spyPtr->spy_place_para != sprite_recno );
  738. }
  739. }
  740. if( leader_unit_recno )
  741. {
  742. Unit* unitPtr = unit_array[leader_unit_recno];
  743. err_when( unitPtr->rank_id != RANK_GENERAL && unitPtr->rank_id != RANK_KING );
  744. }
  745. err_when( (rank_id == RANK_GENERAL || rank_id == RANK_KING) &&
  746. !team_info );
  747. if( leader_unit_recno )
  748. {
  749. err_when( unit_array.is_truly_deleted(leader_unit_recno) );
  750. err_when( unit_array[leader_unit_recno]->nation_recno != nation_recno );
  751. // err_when( unit_array[leader_unit_recno]->team_id != team_id );
  752. }
  753. err_when( hit_points > max_hit_points );
  754. err_when( max_hit_points == 0 );
  755. err_when( skill.combat_level<=0 );
  756. err_when( skill.combat_level>100 );
  757. err_when( unit_mode==UNIT_MODE_REBEL && spy_recno ); // no rebel spies
  758. err_when( unit_mode==UNIT_MODE_REBEL && nation_recno ); // all rebels must be independent units
  759. err_when( unit_mode==UNIT_MODE_DEFEND_TOWN && spy_recno ); // no rebel spies
  760. err_when( loyalty < 0 || loyalty > 100 );
  761. err_when( skill.skill_id == SKILL_SPYING ); // skill.skill_id should never be SKILL_SPYING, it will be shown in spy_recno if it's a spy
  762. err_when( nation_contribution < 0 );
  763. err_when( nation_contribution > MAX_NATION_CONTRIBUTION );
  764. err_when( ai_unit && ( !nation_recno || !nation_array[nation_recno]->is_ai() ) );
  765. #else // fix bug on fly in the release version
  766. if( skill.combat_level > 100 )
  767. skill.combat_level = 100;
  768. #endif
  769. }
  770. //----------- End of function Unit::next_day -----------//
  771. //--------- Begin of function Unit::process_recover ---------//
  772. //
  773. void Unit::process_recover()
  774. {
  775. if( hit_points==0 || hit_points == max_hit_points ) // this unit is dead already
  776. return;
  777. err_when( hit_points > max_hit_points );
  778. //---- overseers in firms and ships in harbors recover faster ----//
  779. int hitPointsInc;
  780. if( unit_mode == UNIT_MODE_OVERSEE ||
  781. unit_mode == UNIT_MODE_IN_HARBOR )
  782. {
  783. hitPointsInc = 2;
  784. }
  785. //------ for units on ships --------//
  786. else if( unit_mode == UNIT_MODE_ON_SHIP )
  787. {
  788. //--- if the ship where the unit is on is in the harbor, the unit recovers faster ---//
  789. if( unit_array[unit_mode_para]->unit_mode == UNIT_MODE_IN_HARBOR )
  790. hitPointsInc = 2;
  791. else
  792. hitPointsInc = 1;
  793. }
  794. //----- only recover when the unit is not moving -----//
  795. else if( cur_action == SPRITE_IDLE )
  796. {
  797. hitPointsInc = 1;
  798. }
  799. else
  800. return;
  801. //---------- recover now -----------//
  802. hit_points += hitPointsInc;
  803. if( hit_points > max_hit_points )
  804. hit_points = max_hit_points;
  805. }
  806. //----------- End of function Unit::process_recover -----------//
  807. //--------- Begin of function Unit::update_loyalty ---------//
  808. //
  809. // How loyalty of units are updated:
  810. //
  811. // General: in a military camp - updated in FirmCamp::update_loyalty()
  812. // mobile - no update
  813. //
  814. // Soldiers led by a general: in a military camp - updated in FirmCamp::update_loyalty()
  815. // mobile - updated here
  816. //
  817. // Other units: no update.
  818. //
  819. void Unit::update_loyalty()
  820. {
  821. if( !nation_recno || rank_id==RANK_KING || !unit_res[unit_id]->race_id )
  822. return;
  823. if( unit_mode == UNIT_MODE_CONSTRUCT ) // constructor worker will not change their loyalty when they are in a building
  824. return;
  825. //----- if this unit is a spy, set its fake loyalty ------//
  826. if( spy_recno ) // a spy's loyalty is always >= 70
  827. {
  828. if( loyalty < 70 )
  829. loyalty = 70+m.random(20); // initialize it to be a number between 70 and 90
  830. target_loyalty = loyalty;
  831. return;
  832. }
  833. //-------- if this is a general ---------//
  834. Nation* ownNation = nation_array[nation_recno];
  835. int rc=0;
  836. if( rank_id==RANK_GENERAL )
  837. {
  838. //----- the general's power affect his loyalty ----//
  839. int targetLoyalty = commander_power();
  840. //----- the king's race affects the general's loyalty ----//
  841. if( ownNation->race_id == race_id )
  842. targetLoyalty += 20;
  843. //----- the kingdom's reputation affects the general's loyalty ----//
  844. targetLoyalty += (int)ownNation->reputation/4;
  845. //--- the king's leadership also affect the general's loyalty -----//
  846. if( ownNation->king_unit_recno )
  847. targetLoyalty += unit_array[ownNation->king_unit_recno]->skill.skill_level / 4;
  848. //-- if the unit is rewarded less than the amount of contribution he made, he will become unhappy --//
  849. if( nation_contribution > total_reward*2 )
  850. {
  851. int decLoyalty = (nation_contribution - total_reward*2)/2;
  852. targetLoyalty -= min(50, decLoyalty); // this affect 50 points at maximum
  853. }
  854. targetLoyalty = min( targetLoyalty, 100 );
  855. target_loyalty = max( targetLoyalty, 0 );
  856. }
  857. //-------- if this is a soldier ---------//
  858. else if( rank_id==RANK_SOLDIER )
  859. {
  860. if( leader_unit_recno )
  861. {
  862. //----------------------------------------//
  863. //
  864. // If this soldier is led by a general,
  865. // the targeted loyalty
  866. //
  867. // = race friendliness between the unit and the general / 2
  868. // + the leader unit's leadership / 2
  869. //
  870. //----------------------------------------//
  871. if( unit_array.is_deleted(leader_unit_recno) )
  872. {
  873. leader_unit_recno = 0;
  874. return;
  875. }
  876. Unit* leaderUnit = unit_array[leader_unit_recno];
  877. int targetLoyalty = 30 + leaderUnit->skill.get_skill(SKILL_LEADING);
  878. //---------------------------------------------------//
  879. //
  880. // Soldiers with higher combat and leadership skill
  881. // will get discontented if they are led by a general
  882. // with low leadership.
  883. //
  884. //---------------------------------------------------//
  885. targetLoyalty -= skill.combat_level/2;
  886. targetLoyalty -= skill.skill_level;
  887. if( leaderUnit->rank_id == RANK_KING )
  888. targetLoyalty += 20;
  889. if( race_res.is_same_race(race_id, leaderUnit->race_id) )
  890. targetLoyalty += 20;
  891. if( targetLoyalty < 0 )
  892. targetLoyalty = 0;
  893. targetLoyalty = min( targetLoyalty, 100 );
  894. target_loyalty = max( targetLoyalty, 0 );
  895. }
  896. else
  897. {
  898. target_loyalty = 0;
  899. }
  900. }
  901. //--------- update loyalty ---------//
  902. err_when( target_loyalty < 0 || target_loyalty > 100 );
  903. if( target_loyalty > loyalty ) // only increase, no decrease. Decrease are caused by events. Increases are made gradually
  904. {
  905. int incValue = (target_loyalty - loyalty)/10;
  906. int newLoyalty = (int) loyalty + max(1, incValue);
  907. if( newLoyalty > target_loyalty )
  908. newLoyalty = target_loyalty;
  909. loyalty = newLoyalty;
  910. }
  911. else if( target_loyalty < loyalty ) // only increase, no decrease. Decrease are caused by events. Increases are made gradually
  912. {
  913. loyalty--;
  914. }
  915. err_when( loyalty < 0 || loyalty > 100 );
  916. }
  917. //-------- End of function Unit::update_loyalty -----------//
  918. //--------- Begin of function Unit::commander_power ---------//
  919. //
  920. // A commander's power is determined:
  921. //
  922. // -Population of the towns he controls
  923. // -The employment rate of the towns he controls, the higher the
  924. // employment rate, the higher his power is
  925. // -If there are any other commanders controls the towns at the same time.
  926. // -the no. of soldiers led by the commander and their combat levels.
  927. //
  928. int Unit::commander_power()
  929. {
  930. //---- if the commander is in a military camp -----//
  931. int commanderPower=0;
  932. if( unit_mode == UNIT_MODE_OVERSEE )
  933. {
  934. Firm* firmPtr = firm_array[unit_mode_para];
  935. if( firmPtr->firm_id == FIRM_CAMP )
  936. {
  937. Town* townPtr;
  938. for( int i=firmPtr->linked_town_count-1 ; i>=0 ; i-- )
  939. {
  940. if( firmPtr->linked_town_enable_array[i] == LINK_EE )
  941. {
  942. townPtr = town_array[firmPtr->linked_town_array[i]];
  943. commanderPower += townPtr->population / townPtr->linked_active_camp_count();
  944. }
  945. }
  946. commanderPower += firmPtr->worker_count*3; // 0 to 24
  947. }
  948. else if( firmPtr->firm_id == FIRM_BASE )
  949. {
  950. commanderPower = 60;
  951. }
  952. }
  953. else
  954. {
  955. commanderPower = team_info->member_count*3; // 0 to 24
  956. }
  957. return commanderPower;
  958. }
  959. //----------- End of function Unit::commander_power -----------//
  960. //--------- Begin of function Unit::think_betray ---------//
  961. //
  962. int Unit::think_betray()
  963. {
  964. int unitRecno = sprite_recno;
  965. err_when( unit_array.is_deleted(unitRecno) );
  966. if( spy_recno ) // spies do not betray here, spy has its own functions for betrayal
  967. return 0;
  968. //----- if the unit is in training or is constructing a building, do not rebel -------//
  969. if( !is_visible() && unit_mode != UNIT_MODE_OVERSEE )
  970. return 0;
  971. if( loyalty >= UNIT_BETRAY_LOYALTY ) // you when unit is
  972. return 0;
  973. if( !unit_res[unit_id]->race_id || !nation_recno ||
  974. rank_id==RANK_KING || spy_recno )
  975. {
  976. return 0;
  977. }
  978. err_when(unit_res[unit_id]->unit_class == UNIT_CLASS_GOD);
  979. err_when(unit_id==UNIT_CARAVAN);
  980. //------ turn towards other nation --------//
  981. int i, bestNationRecno=0, nationScore, bestScore=loyalty; // the score must be larger than the current loyalty
  982. Nation *curNation, *nationPtr;
  983. int unitRegionId = region_id();
  984. if( loyalty==0 ) // if the loyalty is 0, it will definitely betray
  985. bestScore = -100;
  986. curNation = nation_array[nation_recno];
  987. for( i=nation_array.size() ; i>0 ; i-- )
  988. {
  989. if( nation_array.is_deleted(i) )
  990. continue;
  991. if( !curNation->get_relation(i)->has_contact || i==nation_recno )
  992. continue;
  993. nationPtr = nation_array[i];
  994. //--- only if the nation has a base town in the region where the unit stands ---//
  995. if( !region_array.nation_has_base_town(unitRegionId, i) )
  996. continue;
  997. //------------------------------------------------//
  998. nationScore = (int) nationPtr->reputation
  999. + (nationPtr->overall_rating - curNation->overall_rating);
  1000. if( race_res.is_same_race(nationPtr->race_id, race_id) )
  1001. nationScore += 30;
  1002. if( nationScore > bestScore )
  1003. {
  1004. bestScore = nationScore;
  1005. bestNationRecno = i;
  1006. }
  1007. }
  1008. err_when( unit_array.is_deleted(unitRecno) );
  1009. if( bestNationRecno )
  1010. {
  1011. return betray(bestNationRecno);
  1012. }
  1013. else if( loyalty==0 )
  1014. {
  1015. //----------------------------------------------//
  1016. // If there is no good nation to turn towards to and
  1017. // the loyalty has dropped to 0, resign itself and
  1018. // leave the nation.
  1019. //
  1020. // However, if the unit is spy, it will stay with the
  1021. // nation as it has never been really loyal to the nation.
  1022. //---------------------------------------------//
  1023. if( rank_id != RANK_KING && is_visible() &&
  1024. !spy_recno )
  1025. {
  1026. resign(COMMAND_AUTO);
  1027. return 1;
  1028. }
  1029. }
  1030. return 0;
  1031. }
  1032. //-------- End of function Unit::think_betray -----------//
  1033. //--------- Begin of function Unit::betray ---------//
  1034. //
  1035. // If this unit is a spy, this function betray() will be
  1036. // called by Unit::spy_change_nation() or Firm::capture_firm().
  1037. //
  1038. // If this is not a spy, this function will only be called
  1039. // by think_betray() and other nation deinit functions.
  1040. //
  1041. int Unit::betray(int newNationRecno)
  1042. {
  1043. int unitRecno = sprite_recno;
  1044. //### begin alex 18/3 ###//
  1045. //err_when( unit_array.is_deleted(unitRecno) );
  1046. err_when( unit_array.is_truly_deleted(unitRecno) );
  1047. //#### end alex 18/3 ####//
  1048. err_when( rank_id == RANK_KING );
  1049. if( nation_recno == newNationRecno )
  1050. return 0;
  1051. if( unit_mode == UNIT_MODE_CONSTRUCT || // don't change nation when the unit is constructing a firm
  1052. unit_mode == UNIT_MODE_ON_SHIP ) // don't change nation when the unit is constructing a firm
  1053. {
  1054. return 0;
  1055. }
  1056. //---------- add news -----------//
  1057. if( nation_recno == nation_array.player_recno ||
  1058. newNationRecno == nation_array.player_recno )
  1059. {
  1060. //--- if this is a spy, don't display news message for betrayal as it is already displayed in Unit::spy_change_nation() ---//
  1061. if( !spy_recno )
  1062. news_array.unit_betray(sprite_recno, newNationRecno);
  1063. }
  1064. //------ change nation now ------//
  1065. //### begin alex 18/3 ###//
  1066. //err_when( unit_array.is_deleted(unitRecno) );
  1067. err_when( unit_array.is_truly_deleted(unitRecno) );
  1068. //#### end alex 18/3 ####//
  1069. change_nation(newNationRecno);
  1070. //### begin alex 18/3 ###//
  1071. //err_when( unit_array.is_deleted(unitRecno) );
  1072. err_when( unit_array.is_truly_deleted(unitRecno) );
  1073. //#### end alex 18/3 ####//
  1074. //-------- set the loyalty of the unit -------//
  1075. if( nation_recno )
  1076. {
  1077. Nation* nationPtr = nation_array[nation_recno];
  1078. loyalty = UNIT_BETRAY_LOYALTY + m.random(5);
  1079. if( nationPtr->reputation > 0 )
  1080. change_loyalty( (int) nationPtr->reputation );
  1081. if( race_res.is_same_race( nationPtr->race_id, race_id ) )
  1082. change_loyalty( 30 );
  1083. err_when( loyalty < 0 || loyalty > 100 );
  1084. update_loyalty(); // update target loyalty
  1085. }
  1086. else //------ if change to independent rebel -------//
  1087. {
  1088. loyalty = 0; // no loyalty needed
  1089. }
  1090. //--- if this unit is a general, change nation for the units he commands ---//
  1091. DWORD newTeamId = unit_array.cur_team_id++;
  1092. if( rank_id==RANK_GENERAL )
  1093. {
  1094. Unit* unitPtr;
  1095. int i, nationReputation = (int) nation_array[nation_recno]->reputation;
  1096. for( i=unit_array.size() ; i>0 ; i-- )
  1097. {
  1098. if( unit_array.is_deleted(i) )
  1099. continue;
  1100. unitPtr = unit_array[i];
  1101. //---- capture the troop this general commands -----//
  1102. if( unitPtr->leader_unit_recno == sprite_recno &&
  1103. unitPtr->rank_id == RANK_SOLDIER && unitPtr->is_visible() )
  1104. {
  1105. if( unitPtr->spy_recno ) // if the unit is a spy
  1106. unitPtr->spy_change_nation(newNationRecno, COMMAND_AUTO);
  1107. else
  1108. unitPtr->change_nation(newNationRecno);
  1109. unitPtr->team_id = newTeamId; // assign new team_id or checking for nation_recno
  1110. }
  1111. }
  1112. }
  1113. team_id = newTeamId;
  1114. //### begin alex 18/3 ###//
  1115. //err_when( unit_array.is_deleted(unitRecno) );
  1116. err_when( unit_array.is_truly_deleted(unitRecno) );
  1117. //#### end alex 18/3 ####//
  1118. //------ go to meet the new master -------//
  1119. if( is_visible() && nation_recno )
  1120. {
  1121. if( !spy_recno || spy_array[spy_recno]->notify_cloaked_nation_flag )
  1122. {
  1123. if( rank_id == RANK_GENERAL ) // generals shouldn't automatically be assigned to camps, they should just move near your villages
  1124. ai_move_to_nearby_town();
  1125. else
  1126. think_normal_human_action(); // this is an AI function in OUNITAI.CPP
  1127. }
  1128. }
  1129. //### begin alex 18/3 ###//
  1130. //err_when( unit_array.is_deleted(unitRecno) );
  1131. err_when( unit_array.is_truly_deleted(unitRecno) );
  1132. //#### end alex 18/3 ####//
  1133. return 1;
  1134. }
  1135. //-------- End of function Unit::betray -----------//
  1136. //--------- Begin of function Unit::change_nation ---------//
  1137. //
  1138. // This function is called when a unit change nation.
  1139. // It is not necessarily a result of betray, when a spy
  1140. // hands over his new nation to his parent nation, this
  1141. // function will also be called.
  1142. //
  1143. // <int> newNationRecno - change the nation of the unit.
  1144. //
  1145. void Unit::change_nation(int newNationRecno)
  1146. {
  1147. err_when( newNationRecno && nation_array.is_deleted(newNationRecno) );
  1148. err_when( unit_mode == UNIT_MODE_REBEL ); // rebels do not change nation
  1149. //---------------------------------//
  1150. int oldAiUnit = ai_unit;
  1151. int oldNationRecno = nation_recno;
  1152. group_select_id = 0; // clear group select id
  1153. if(way_point_count)
  1154. reset_way_point_array();
  1155. //-- if the player is giving a command to this unit, cancel the command --//
  1156. if( nation_recno == nation_array.player_recno &&
  1157. sprite_recno == unit_array.selected_recno &&
  1158. power.command_id )
  1159. {
  1160. power.command_id = 0;
  1161. }
  1162. //---------- stop all action to attack this unit ------------//
  1163. unit_array.stop_attack_unit(sprite_recno);
  1164. //---- update nation_unit_count_array[] ----//
  1165. unit_res[unit_id]->unit_change_nation(newNationRecno, nation_recno, rank_id);
  1166. //------- if the nation has an AI action -------//
  1167. stop2(); // clear the existing order
  1168. //---------------- update vars ----------------//
  1169. unit_group_id = unit_array.cur_group_id++; // separate from the current group
  1170. nation_recno = newNationRecno;
  1171. home_camp_firm_recno = 0; // reset it
  1172. original_action_mode = 0;
  1173. if( race_id )
  1174. {
  1175. nation_contribution = 0; // contribution to the nation
  1176. total_reward = 0;
  1177. }
  1178. //-------- if change to one of the existing nations ------//
  1179. ai_unit = nation_recno && nation_array[nation_recno]->is_ai();
  1180. //------------ update AI info --------------//
  1181. if( oldAiUnit )
  1182. {
  1183. Nation* nationPtr = nation_array[oldNationRecno];
  1184. if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
  1185. nationPtr->del_general_info(sprite_recno);
  1186. else if( unit_res[unit_id]->unit_class == UNIT_CLASS_CARAVAN )
  1187. nationPtr->del_caravan_info(sprite_recno);
  1188. else if( unit_res[unit_id]->unit_class == UNIT_CLASS_SHIP )
  1189. nationPtr->del_ship_info(sprite_recno);
  1190. }
  1191. if( ai_unit && nation_recno != 0 )
  1192. {
  1193. Nation* nationPtr = nation_array[nation_recno];
  1194. if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
  1195. nationPtr->add_general_info(sprite_recno);
  1196. else if( unit_res[unit_id]->unit_class == UNIT_CLASS_CARAVAN )
  1197. nationPtr->add_caravan_info(sprite_recno);
  1198. else if( unit_res[unit_id]->unit_class == UNIT_CLASS_SHIP )
  1199. nationPtr->add_ship_info(sprite_recno);
  1200. }
  1201. //------ if this unit oversees a firm -----//
  1202. if( unit_mode==UNIT_MODE_OVERSEE )
  1203. firm_array[unit_mode_para]->change_nation(newNationRecno);
  1204. //----- this unit was defending the town before it gets killed ----//
  1205. else if( unit_mode==UNIT_MODE_DEFEND_TOWN )
  1206. {
  1207. if( !town_array.is_deleted(unit_mode_para) )
  1208. town_array[unit_mode_para]->reduce_defender_count();
  1209. set_mode(0); // reset unit mode
  1210. }
  1211. //---- if the unit is no longer the same nation as the leader ----//
  1212. if( leader_unit_recno )
  1213. {
  1214. Unit* leaderUnit = unit_array[leader_unit_recno];
  1215. if( leaderUnit->nation_recno != nation_recno )
  1216. {
  1217. leaderUnit->del_team_member(sprite_recno);
  1218. leader_unit_recno = 0;
  1219. team_id = 0;
  1220. }
  1221. }
  1222. //------ if it is currently selected -------//
  1223. if( selected_flag )
  1224. info.disp();
  1225. }
  1226. //----------- End of function Unit::change_nation -----------//
  1227. //--------- Begin of function Unit::pay_expense ---------//
  1228. //
  1229. void Unit::pay_expense()
  1230. {
  1231. if( game.game_mode == GAME_TEST ) // no deduction in testing game
  1232. return;
  1233. if( !nation_recno )
  1234. return;
  1235. //--- if it's a mobile spy or the spy is in its own firm, no need to pay salary here as Spy::pay_expense() will do that ---//
  1236. //
  1237. // -If your spies are mobile:
  1238. // >your nation pays them 1 food and $5 dollars per month
  1239. //
  1240. // -If your spies are in an enemy's town or firm:
  1241. // >the enemy pays them 1 food and the normal salary of their jobs.
  1242. //
  1243. // >your nation pays them $5 dollars per month. (your nation pays them no food)
  1244. //
  1245. // -If your spies are in your own town or firm:
  1246. // >your nation pays them 1 food and $5 dollars per month
  1247. //
  1248. //------------------------------------------------------//
  1249. if( spy_recno )
  1250. {
  1251. if( is_visible() ) // the cost will be deducted in spy_array
  1252. return;
  1253. if( unit_mode == UNIT_MODE_OVERSEE &&
  1254. firm_array[unit_mode_para]->nation_recno == true_nation_recno() )
  1255. {
  1256. return;
  1257. }
  1258. }
  1259. //---------- if it's a human unit -----------//
  1260. //
  1261. // The unit is paid even during its training period in a town
  1262. //
  1263. //-------------------------------------------//
  1264. Nation* nationPtr = nation_array[nation_recno];
  1265. if( unit_res[unit_id]->race_id )
  1266. {
  1267. //---------- reduce cash -----------//
  1268. if( nationPtr->cash > 0 )
  1269. {
  1270. if( rank_id == RANK_SOLDIER )
  1271. nationPtr->add_expense( EXPENSE_MOBILE_UNIT, (float) SOLDIER_YEAR_SALARY / 365, 1 );
  1272. if( rank_id == RANK_GENERAL )
  1273. nationPtr->add_expense( EXPENSE_GENERAL, (float) GENERAL_YEAR_SALARY / 365, 1 );
  1274. }
  1275. else // decrease loyalty if the nation cannot pay the unit
  1276. {
  1277. change_loyalty(-1);
  1278. }
  1279. //---------- reduce food -----------//
  1280. if( unit_res[unit_id]->race_id ) // if it's a human unit
  1281. {
  1282. if( nationPtr->food > 0 )
  1283. nationPtr->consume_food((float) PERSON_FOOD_YEAR_CONSUMPTION / 365);
  1284. else
  1285. {
  1286. if( info.game_date%NO_FOOD_LOYALTY_DECREASE_INTERVAL == 0 ) // decrease 1 loyalty point every 2 days
  1287. change_loyalty(-1);
  1288. }
  1289. }
  1290. }
  1291. else //----- it's a non-human unit ------//
  1292. {
  1293. if( nationPtr->cash > 0 )
  1294. {
  1295. int expenseType;
  1296. switch(unit_res[unit_id]->unit_class)
  1297. {
  1298. case UNIT_CLASS_WEAPON:
  1299. expenseType = EXPENSE_WEAPON;
  1300. break;
  1301. case UNIT_CLASS_SHIP:
  1302. expenseType = EXPENSE_SHIP;
  1303. break;
  1304. case UNIT_CLASS_CARAVAN:
  1305. expenseType = EXPENSE_CARAVAN;
  1306. break;
  1307. default:
  1308. expenseType = EXPENSE_MOBILE_UNIT;
  1309. }
  1310. nationPtr->add_expense( expenseType, (float) unit_res[unit_id]->year_cost / 365, 1 );
  1311. }
  1312. else // decrease hit points if the nation cannot pay the unit
  1313. {
  1314. if( unit_res[unit_id]->unit_class != UNIT_CLASS_CARAVAN ) // Even when caravans are not paid, they still stay in your service.
  1315. {
  1316. if( hit_points > 0 )
  1317. {
  1318. hit_points--;
  1319. if( hit_points < 0 )
  1320. hit_points = (float) 0;
  1321. //--- when the hit points drop to zero and the unit is destroyed ---//
  1322. if( hit_points==0 )
  1323. {
  1324. if( nation_recno == nation_array.player_recno )
  1325. {
  1326. int unitClass = unit_res[unit_id]->unit_class;
  1327. if( unitClass==UNIT_CLASS_WEAPON )
  1328. news_array.weapon_ship_worn_out(unit_id, get_weapon_version());
  1329. else if( unitClass==UNIT_CLASS_SHIP )
  1330. news_array.weapon_ship_worn_out(unit_id, 0);
  1331. }
  1332. }
  1333. }
  1334. }
  1335. }
  1336. }
  1337. }
  1338. //----------- End of function Unit::pay_expense -----------//
  1339. //--------- Begin of function Unit::change_hit_points ---------//
  1340. //
  1341. void Unit::change_hit_points(float changePoints)
  1342. {
  1343. hit_points += changePoints;
  1344. if( hit_points < 0 )
  1345. hit_points = (float) 0;
  1346. if( hit_points > max_hit_points )
  1347. hit_points = max_hit_points;
  1348. }
  1349. //-------- End of function Unit::change_hit_points -----------//
  1350. //--------- Begin of function Unit::change_loyalty ---------//
  1351. //
  1352. // <int> changeAmt - amount of loyalty to be changed.
  1353. //
  1354. void Unit::change_loyalty(int changeAmt)
  1355. {
  1356. int newLoyalty = loyalty + changeAmt;
  1357. newLoyalty = max(0, newLoyalty);
  1358. loyalty = min(100, newLoyalty);
  1359. }
  1360. //----------- End of function Unit::change_loyalty -----------//
  1361. //------- Begin of function Unit::inc_minor_combat_level --------//
  1362. //
  1363. void Unit::inc_minor_combat_level(int incLevel)
  1364. {
  1365. err_when( incLevel<0 || incLevel>100 ); // it cannot be larger than 100, because the current code can't handle it
  1366. skill.combat_level_minor += incLevel;
  1367. if( skill.combat_level_minor > 100 )
  1368. {
  1369. if( skill.combat_level < 100 )
  1370. set_combat_level(skill.combat_level+1);
  1371. skill.combat_level_minor -= 100;
  1372. }
  1373. }
  1374. //-------- End of function Unit::inc_minor_combat_level ---------//
  1375. //------- Begin of function Unit::inc_minor_skill_level --------//
  1376. //
  1377. void Unit::inc_minor_skill_level(int incLevel)
  1378. {
  1379. err_when( incLevel<0 || incLevel>100 );
  1380. skill.skill_level_minor += incLevel;
  1381. if( skill.skill_level_minor > 100 )
  1382. {
  1383. if( skill.skill_level < 100 )
  1384. skill.skill_level++;
  1385. skill.skill_level_minor -= 100;
  1386. }
  1387. }
  1388. //-------- End of function Unit::inc_minor_skill_level ---------//
  1389. //--------- Begin of function Unit::set_combat_level ---------//
  1390. //
  1391. void Unit::set_combat_level(int combatLevel)
  1392. {
  1393. err_when( combatLevel<=0 || combatLevel>100 );
  1394. skill.combat_level = combatLevel;
  1395. UnitInfo* unitInfo = unit_res[unit_id];
  1396. int oldMaxHitPoints = max_hit_points;
  1397. max_hit_points = unitInfo->hit_points * combatLevel / 100;
  1398. hit_points = hit_points * max_hit_points / oldMaxHitPoints;
  1399. hit_points = min(hit_points, max_hit_points);
  1400. // --------- update can_guard_flag -------//
  1401. if( combatLevel >= unitInfo->guard_combat_level)
  1402. {
  1403. can_guard_flag = sprite_info->can_guard_flag;
  1404. #ifdef AMPLUS
  1405. if( unit_id == UNIT_ZULU )
  1406. can_guard_flag |= 4; // shield during attack delay
  1407. #endif
  1408. }
  1409. else
  1410. {
  1411. can_guard_flag = 0;
  1412. }
  1413. max_power = skill.combat_level + 50;
  1414. cur_power = min(cur_power, max_power);
  1415. }
  1416. //-------- End of function Unit::set_combat_level -----------//
  1417. //--------- Begin of function Unit::set_rank ---------//
  1418. //
  1419. // Only if the unit has leadership skill, it can be a general or king.
  1420. //
  1421. void Unit::set_rank(int rankId)
  1422. {
  1423. err_when( !race_id );
  1424. #ifdef DEBUG
  1425. if( !is_visible() )
  1426. {
  1427. err_when( rank_id==RANK_GENERAL && rankId==RANK_SOLDIER );
  1428. err_when( rank_id==RANK_SOLDIER && rankId==RANK_GENERAL );
  1429. }
  1430. #endif
  1431. if( rank_id == rankId )
  1432. return;
  1433. //------- promote --------//
  1434. if( rankId > rank_id )
  1435. change_loyalty(PROMOTE_LOYALTY_INCREASE);
  1436. //------- demote -----------//
  1437. else if( rankId < rank_id && rank_id != RANK_KING ) // no decrease in loyalty if a spy king hands his nation to his parent nation and become a general again
  1438. change_loyalty(-DEMOTE_LOYALTY_DECREASE);
  1439. //---- update nation_general_count_array[] ----//
  1440. if( nation_recno )
  1441. {
  1442. UnitInfo* unitInfo = unit_res[unit_id];
  1443. if( rank_id == RANK_GENERAL ) // if it was a general originally
  1444. unitInfo->dec_nation_general_count(nation_recno);
  1445. if( rankId == RANK_GENERAL ) // if the new rank is general
  1446. unitInfo->inc_nation_general_count(nation_recno);
  1447. //------ if demote a king to a unit ------//
  1448. if( rank_id == RANK_KING && rankId != RANK_KING )
  1449. unitInfo->inc_nation_unit_count(nation_recno); // since kings are not included in nation_unit_count, when it is no longer a king, we need to re-increase it.
  1450. //------ if promote a unit to a king ------//
  1451. if( rank_id != RANK_KING && rankId == RANK_KING )
  1452. unitInfo->dec_nation_unit_count(nation_recno); // since kings are not included in nation_unit_count, we need to decrease it
  1453. }
  1454. //----- reset leader_unit_recno if demote a general to soldier ----//
  1455. if( rank_id == RANK_GENERAL && rankId == RANK_SOLDIER )
  1456. {
  1457. //----- reset leader_unit_recno of the units he commands ----//
  1458. for( int i=unit_array.size() ; i>0 ; i-- )
  1459. {
  1460. Unit* unitPtr = (Unit*) unit_array.get_ptr(i); // don't use is_deleted() as it filters out units that are currently dying
  1461. if( unitPtr && unitPtr->leader_unit_recno == sprite_recno )
  1462. {
  1463. unitPtr->leader_unit_recno = 0;
  1464. unitPtr->team_id = 0;
  1465. }
  1466. }
  1467. //--------- deinit team_info ---------//
  1468. err_when( !team_info );
  1469. mem_del(team_info);
  1470. team_info = NULL;
  1471. team_id = 0;
  1472. }
  1473. //----- if this is a soldier being promoted to a general -----//
  1474. else if( rank_id == RANK_SOLDIER && rankId == RANK_GENERAL )
  1475. {
  1476. //-- if this soldier is formerly commanded by a general, detech it ---//
  1477. if( leader_unit_recno )
  1478. {
  1479. if( !unit_array.is_deleted(leader_unit_recno) ) // the leader unit may have been killed at the same time
  1480. unit_array[leader_unit_recno]->del_team_member(sprite_recno);
  1481. leader_unit_recno = 0;
  1482. }
  1483. }
  1484. //-------------- update AI info --------------//
  1485. if( ai_unit )
  1486. {
  1487. if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
  1488. nation_array[nation_recno]->del_general_info(sprite_recno);
  1489. rank_id = rankId;
  1490. if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
  1491. nation_array[nation_recno]->add_general_info(sprite_recno);
  1492. }
  1493. else
  1494. {
  1495. rank_id = rankId;
  1496. }
  1497. //----- if this is a general/king ------//
  1498. if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
  1499. {
  1500. //--------- init team_info -------//
  1501. if( !team_info )
  1502. {
  1503. team_info = (TeamInfo*) mem_add( sizeof(TeamInfo) );
  1504. team_info->member_count = 0;
  1505. }
  1506. //--- set leadership if this unit does not have any now ----//
  1507. if( skill.skill_id != SKILL_LEADING )
  1508. {
  1509. skill.skill_id = SKILL_LEADING;
  1510. skill.skill_level = 10 + m.random(40);
  1511. }
  1512. }
  1513. //------ refresh if the current unit is selected -----//
  1514. if( unit_array.selected_recno == sprite_recno )
  1515. info.disp();
  1516. }
  1517. //-------- End of function Unit::set_rank -----------//
  1518. //--------- Begin of function Unit::embark ---------//
  1519. //
  1520. // Order this unit to embark an vehicle
  1521. //
  1522. // <int> vehicleRecno - recno of the vehicle.
  1523. //
  1524. void Unit::embark(int vehicleRecno)
  1525. {
  1526. err_here(); // this function is no longer functional
  1527. Unit* vehiclePtr = unit_array[vehicleRecno];
  1528. if( unit_res[unit_id]->vehicle_id == vehiclePtr->unit_id ) // not the right vehicle
  1529. return;
  1530. int vehicleUnitId = unit_res[unit_id]->vehicle_unit_id;
  1531. float vehicleHitPoints = vehiclePtr->hit_points;
  1532. int xLoc = vehiclePtr->cur_x_loc();
  1533. int yLoc = vehiclePtr->cur_y_loc();
  1534. //------- delete the vehicle unit --------//
  1535. unit_array.del(vehicleRecno); // delete the vehicle (e.g. horse)
  1536. //--------- add the combined unit -------//
  1537. int newUnitRecno = unit_array.add_unit(vehicleUnitId, nation_recno, rank_id, loyalty, xLoc, yLoc); // add the combined unit (e.g. cavalry)
  1538. UnitVehicle* unitVehicle = (UnitVehicle*) unit_array[newUnitRecno];
  1539. unitVehicle->skill = skill;
  1540. unitVehicle->set_combat_level(skill.combat_level);
  1541. unitVehicle->solider_hit_points = (int) hit_points;
  1542. unitVehicle->vehicle_hit_points = (int) vehicleHitPoints;
  1543. unitVehicle->hit_points = (float) unitVehicle->solider_hit_points +
  1544. unitVehicle->vehicle_hit_points;
  1545. //-------- delete the solider unit ---------//
  1546. unit_array.del(sprite_recno); // delete the embarker (e.g. knight)
  1547. }
  1548. //-------- End of function Unit::embark -----------//
  1549. //--------- Begin of function Unit::reward ---------//
  1550. //
  1551. // <int> rewardNationRecno - the nation which does this reward.
  1552. //
  1553. void Unit::reward(int rewardNationRecno)
  1554. {
  1555. // ###### patch begin Gilbert 24/9 ########//
  1556. if( nation_array[rewardNationRecno]->cash < REWARD_COST )
  1557. return;
  1558. // ###### patch end Gilbert 24/9 ########//
  1559. //--------- if this is a spy ---------//
  1560. if( spy_recno && true_nation_recno() == rewardNationRecno ) // if the spy's owning nation rewards the spy
  1561. {
  1562. spy_array[spy_recno]->change_loyalty(REWARD_LOYALTY_INCREASE);
  1563. }
  1564. //--- if this spy's nation_recno & true_nation_recno() are both == rewardNationRecno, it's true loyalty and cloaked loyalty will both be increased ---//
  1565. if( nation_recno == rewardNationRecno )
  1566. {
  1567. total_reward += REWARD_COST;
  1568. change_loyalty(REWARD_LOYALTY_INCREASE);
  1569. }
  1570. nation_array[rewardNationRecno]->add_expense(EXPENSE_REWARD_UNIT, (float)REWARD_COST);
  1571. }
  1572. //----------- End of function Unit::reward -----------//
  1573. //------- Begin of function Unit::overseer_migrate ---------//
  1574. //
  1575. // Order the overseer migrate to a new town but still keeps
  1576. // working for the same firm.
  1577. //
  1578. // <int> destTownRecno - the recno of the town the worker should
  1579. // migrate to.
  1580. //
  1581. void Unit::overseer_migrate(int destTownRecno)
  1582. {
  1583. err_when( unit_mode!=UNIT_MODE_OVERSEE );
  1584. int curTownRecno = firm_array[unit_mode_para]->overseer_town_recno;
  1585. //------- decrease the population of the unit's home town ------//
  1586. town_array[curTownRecno]->dec_pop(race_id, 1);
  1587. //--------- increase the population of the target town ------//
  1588. town_array[destTownRecno]->inc_pop(race_id, 1, loyalty );
  1589. }
  1590. //-------- End of function Unit::overseer_migrate ---------//
  1591. //--------- Begin of function Unit::group_transform ---------//
  1592. void Unit::group_transform(char remoteAction, short *selectedArray, short selectedCount)
  1593. {
  1594. }
  1595. //----------- End of function Unit::group_transform -----------//
  1596. //--------- Begin of function Unit::transform ---------//
  1597. //
  1598. // Transform the unit into another unit type.
  1599. //
  1600. void Unit::transform()
  1601. {
  1602. /*
  1603. UnitInfo* unitInfo = unit_res[unit_id];
  1604. if( unitInfo->transform_unit_id==0 )
  1605. return;
  1606. UnitInfo* newUnitInfo = unit_res[unitInfo->transform_unit_id];
  1607. //--- check if the unit has the required combat level ---//
  1608. if( skill.combat_level < unitInfo->transform_combat_level )
  1609. return;
  1610. //------ free up space on the map for the new unit -----//
  1611. int xLoc=next_x_loc(), yLoc=next_y_loc();
  1612. stop();
  1613. deinit_sprite(1); // 1-keep the unit selected if it is currently selected
  1614. //---- locate the space for the new unit as their size, mobile type may be different ----//
  1615. SpriteInfo* spriteInfo = sprite_res[newUnitInfo->sprite_id];
  1616. int xLoc2 = xLoc + spriteInfo->loc_width-1;
  1617. int yLoc2 = yLoc + spriteInfo->loc_height-1;
  1618. if( !world.check_unit_space(xLoc, yLoc, xLoc2, yLoc2, newUnitInfo->mobile_type) ) // first check if if is free to create unit on the same location
  1619. {
  1620. if( !world.locate_space( xLoc, yLoc, xLoc+spriteInfo->loc_width-1,
  1621. yLoc+spriteInfo->loc_height-1, spriteInfo->loc_width,
  1622. spriteInfo->loc_height, newUnitInfo->mobile_type) )
  1623. {
  1624. init_sprite( xLoc, yLoc ); // not able to find space for the new unit, transformation cancelled.
  1625. return;
  1626. }
  1627. }
  1628. //--------- transform now ------------//
  1629. deinit_unit_id();
  1630. init_unit_id(unitInfo->transform_unit_id);
  1631. init_sprite( xLoc, yLoc );
  1632. */
  1633. }
  1634. //----------- End of function Unit::transform -----------//
  1635. //--------- Begin of function Unit::spy_change_nation ---------//
  1636. //
  1637. // Change the deceiving nation recno of a spy unit which you control.
  1638. //
  1639. // <int> newNationRecno - the new nation the spy changes its cloack to
  1640. // <char> remoteAction - remote action type
  1641. //
  1642. void Unit::spy_change_nation(int newNationRecno, char remoteAction)
  1643. {
  1644. if( newNationRecno == nation_recno )
  1645. return;
  1646. if( newNationRecno && nation_array.is_deleted(newNationRecno) ) // this can happen in a multiplayer message
  1647. return;
  1648. //------- if this is a remote action -------//
  1649. if( !remoteAction && remote.is_enable() )
  1650. {
  1651. // packet structure <unit recno> <new nation Recno>
  1652. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_UNIT_SPY_NATION, 2*sizeof(short) );
  1653. *shortPtr = sprite_recno;
  1654. shortPtr[1] = newNationRecno;
  1655. return;
  1656. }
  1657. //----- update the var in Spy ------//
  1658. Spy* spyPtr = spy_array[spy_recno];
  1659. //--- when a spy change cloak to another nation, he can't cloak as a general, he must become a soldier first ---//
  1660. if( is_visible() && // if the spy is a commander in a camp, don't set its rank to soldier
  1661. rank_id == RANK_GENERAL &&
  1662. newNationRecno != spyPtr->true_nation_recno )
  1663. {
  1664. set_rank(RANK_SOLDIER);
  1665. }
  1666. //---------------------------------------------------//
  1667. //
  1668. // If this spy unit is a general or an overseer of the
  1669. // cloaked nation, when he changes nation, that will
  1670. // inevitably be noticed by the cloaked nation.
  1671. //
  1672. //---------------------------------------------------//
  1673. if( spyPtr->true_nation_recno != nation_array.player_recno ) // only send news message if he is not the player's own spy
  1674. {
  1675. if( rank_id == RANK_GENERAL || unit_mode == UNIT_MODE_OVERSEE ||
  1676. spyPtr->notify_cloaked_nation_flag )
  1677. {
  1678. //-- if this spy's cloaked nation is the player's nation, the player will be notified --//
  1679. if( nation_recno == nation_array.player_recno )
  1680. news_array.unit_betray(sprite_recno, newNationRecno);
  1681. }
  1682. //---- send news to the cloaked nation if notify flag is on ---//
  1683. if( spyPtr->notify_cloaked_nation_flag )
  1684. {
  1685. if( newNationRecno == nation_array.player_recno ) // cloaked as the player's nation
  1686. news_array.unit_betray(sprite_recno, newNationRecno);
  1687. }
  1688. }
  1689. //--------- change nation recno now --------//
  1690. spyPtr->cloaked_nation_recno = newNationRecno;
  1691. betray(newNationRecno); // call the betray function to change natino. There is no difference between a spy changing nation and a unit truly betrays
  1692. }
  1693. //----------- End of function Unit::spy_change_nation -----------//
  1694. //--------- Begin of function Unit::can_spy_change_nation ---------//
  1695. //
  1696. // Whether the spy unit can change its spy cloak now or not.
  1697. //
  1698. // If there are enemy nearby, the unit cannot change its cloak.
  1699. //
  1700. int Unit::can_spy_change_nation()
  1701. {
  1702. if( !spy_recno )
  1703. return 0;
  1704. //--------------------------------------------//
  1705. int xLoc1=cur_x_loc()-SPY_ENEMY_RANGE, yLoc1=cur_y_loc()-SPY_ENEMY_RANGE;
  1706. int xLoc2=cur_x_loc()+SPY_ENEMY_RANGE, yLoc2=cur_y_loc()+SPY_ENEMY_RANGE;
  1707. xLoc1 = max(0, xLoc1);
  1708. yLoc1 = max(0, yLoc1);
  1709. xLoc2 = min(MAX_WORLD_X_LOC-1, xLoc2);
  1710. yLoc2 = min(MAX_WORLD_Y_LOC-1, yLoc2);
  1711. int xLoc, yLoc;
  1712. int unitRecno, trueNationRecno = true_nation_recno();
  1713. Location* locPtr;
  1714. for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
  1715. {
  1716. locPtr = world.get_loc(xLoc1, yLoc);
  1717. for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
  1718. {
  1719. if( locPtr->has_unit(UNIT_LAND) )
  1720. unitRecno = locPtr->unit_recno(UNIT_LAND);
  1721. else if( locPtr->has_unit(UNIT_SEA) )
  1722. unitRecno = locPtr->unit_recno(UNIT_SEA);
  1723. else if( locPtr->has_unit(UNIT_AIR) )
  1724. unitRecno = locPtr->unit_recno(UNIT_AIR);
  1725. else
  1726. continue;
  1727. if( unit_array.is_deleted(unitRecno) ) // the unit is dying, its recno is still in the location
  1728. continue;
  1729. if( unit_array[unitRecno]->true_nation_recno() != trueNationRecno )
  1730. return 0;
  1731. }
  1732. }
  1733. return 1;
  1734. }
  1735. //----------- End of function Unit::can_spy_change_nation -----------//
  1736. //--------- Begin of function Unit::resign ---------//
  1737. //
  1738. // Resign the unit.
  1739. //
  1740. void Unit::resign(int remoteAction)
  1741. {
  1742. if( !remoteAction && remote.is_enable() )
  1743. {
  1744. // packet structure : <unit recno> <nation recno>
  1745. short *shortPtr = (short *)remote.new_send_queue_msg(MSG_UNIT_RESIGN, 2*sizeof(short));
  1746. *shortPtr = sprite_recno;
  1747. shortPtr[1] = nation_array.player_recno;
  1748. return;
  1749. }
  1750. //---- increase the wandering count when a unit is disbanded ----//
  1751. if( race_id )
  1752. town_array.race_wander_pop_array[race_id-1] += 2; // disbanding one resulted in two wandering units to make the effect more significant
  1753. //--- if the unit is visible, call stop2() so if it has an AI action queue, that will be reset ---//
  1754. if( is_visible() )
  1755. stop2();
  1756. //--- if the spy is resigned by an enemy, display a message ---//
  1757. if( spy_recno && true_nation_recno() != nation_recno ) // the spy is cloaked in an enemy nation when it is resigned
  1758. {
  1759. //------ decrease reputation ------//
  1760. nation_array[true_nation_recno()]->change_reputation((float)-SPY_KILLED_REPUTATION_DECREASE);
  1761. //------- add news message -------//
  1762. if( true_nation_recno() == nation_array.player_recno || // display when the player's spy is revealed or the player has revealed an enemy spy
  1763. nation_recno == nation_array.player_recno )
  1764. {
  1765. //--- If a spy is caught, the spy's nation's reputation wil decrease ---//
  1766. news_array.spy_killed(spy_recno);
  1767. }
  1768. }
  1769. //----------------------------------------------//
  1770. if( rank_id == RANK_GENERAL ) // if this is a general, news_array.general_die() will be called, set news_add_flag to 0 to suppress the display of thew news
  1771. news_array.news_add_flag=0;
  1772. unit_array.del( sprite_recno );
  1773. news_array.news_add_flag=1;
  1774. }
  1775. //----------- End of function Unit::resign -----------//
  1776. //--------- Begin of function Unit::region_id ---------//
  1777. //
  1778. // Return the region id. of this unit.
  1779. //
  1780. BYTE Unit::region_id()
  1781. {
  1782. if( is_visible() )
  1783. {
  1784. return world.get_region_id( next_x_loc(), next_y_loc() );
  1785. }
  1786. else
  1787. {
  1788. if( unit_mode == UNIT_MODE_OVERSEE )
  1789. return firm_array[unit_mode_para]->region_id;
  1790. }
  1791. return 0;
  1792. }
  1793. //----------- End of function Unit::region_id -----------//
  1794. //--------- Begin of function Unit::del_team_member ---------//
  1795. //
  1796. // Delete a specific member of the team led by this leader.
  1797. //
  1798. void Unit::del_team_member(int unitRecno)
  1799. {
  1800. err_when( !team_info );
  1801. for( int i=0 ; i<team_info->member_count ; i++ )
  1802. {
  1803. if( team_info->member_unit_array[i] == unitRecno )
  1804. {
  1805. err_when( team_info->member_count > MAX_TEAM_MEMBER );
  1806. m.del_array_rec( team_info->member_unit_array, team_info->member_count,
  1807. sizeof( team_info->member_unit_array[0] ), i+1 );
  1808. team_info->member_count--;
  1809. return;
  1810. }
  1811. }
  1812. //-------------------------------------------------------//
  1813. //
  1814. // Note: for rebels and monsters, although they have
  1815. // leader_unit_recno, their team_info is not used.
  1816. // So del_team_member() won't be able to match the
  1817. // unit in its member_unit_array[].
  1818. //
  1819. //-------------------------------------------------------//
  1820. }
  1821. //----------- End of function Unit::del_team_member -----------//
  1822. //--------- Begin of function Unit::validate_team ---------//
  1823. //
  1824. // Validate the member in this commander's team. If there
  1825. // are any units with hit_points <= 0, delete them.
  1826. //
  1827. // Those unit may just be killed, so soon that the Unit's set_die()
  1828. // function hsa been called yet. validate_team() function must
  1829. // be called before all issunig any new team actions.
  1830. //
  1831. void Unit::validate_team()
  1832. {
  1833. err_when( !team_info );
  1834. int unitRecno;
  1835. for( int i=team_info->member_count-1 ; i>=0 ; i-- )
  1836. {
  1837. unitRecno = team_info->member_unit_array[i];
  1838. if( unit_array.is_deleted(unitRecno) )
  1839. {
  1840. err_when( team_info->member_count > MAX_TEAM_MEMBER );
  1841. m.del_array_rec( team_info->member_unit_array, team_info->member_count,
  1842. sizeof( team_info->member_unit_array[0] ), i+1 );
  1843. team_info->member_count--;
  1844. }
  1845. }
  1846. }
  1847. //----------- End of function Unit::validate_team -----------//
  1848. //--------- Begin of function Unit::commanded_soldier_count ---------//
  1849. //
  1850. // Return the no. of soldiers commanded by this unit.
  1851. //
  1852. int Unit::commanded_soldier_count()
  1853. {
  1854. if( rank_id != RANK_GENERAL && rank_id != RANK_KING )
  1855. return 0;
  1856. //--------------------------------------//
  1857. err_when( !team_info );
  1858. int soldierCount=0;
  1859. if( is_visible() )
  1860. {
  1861. soldierCount = team_info->member_count-1;
  1862. if( soldierCount < 0 ) // member_count can be 0
  1863. soldierCount = 0;
  1864. }
  1865. else
  1866. {
  1867. if( unit_mode == UNIT_MODE_OVERSEE )
  1868. {
  1869. Firm* firmPtr = firm_array[unit_mode_para];
  1870. if( firmPtr->firm_id == FIRM_CAMP ) // it can be an overseer of a seat of powre
  1871. soldierCount = firmPtr->worker_count;
  1872. }
  1873. }
  1874. return soldierCount;
  1875. }
  1876. //----------- End of function Unit::commanded_soldier_count -----------//
  1877. //----------- Begin of function Unit::fix_attack_info -----------//
  1878. void Unit::fix_attack_info()
  1879. {
  1880. int techLevel;
  1881. UnitInfo *unitInfo = unit_res[unit_id];
  1882. attack_count = unitInfo->attack_count;
  1883. if( attack_count > 0 && unitInfo->first_attack > 0)
  1884. attack_info_array = unit_res.attack_info_array+unitInfo->first_attack-1;
  1885. else
  1886. attack_info_array = NULL;
  1887. if( unitInfo->unit_class == UNIT_CLASS_WEAPON &&
  1888. (techLevel=get_weapon_version()) > 0 )
  1889. {
  1890. switch( unit_id )
  1891. {
  1892. case UNIT_BALLISTA:
  1893. #ifdef AMPLUS
  1894. case UNIT_F_BALLISTA:
  1895. #endif
  1896. attack_count = 2;
  1897. break;
  1898. case UNIT_EXPLOSIVE_CART:
  1899. attack_count = 0;
  1900. break;
  1901. default:
  1902. attack_count = 1;
  1903. }
  1904. if( attack_count > 0)
  1905. {
  1906. attack_info_array += (techLevel-1) * attack_count;
  1907. }
  1908. else
  1909. {
  1910. // no attack like explosive cart
  1911. attack_info_array = NULL;
  1912. }
  1913. }
  1914. }
  1915. //----------- End of function Unit::fix_attack_info -----------//
  1916. //----------- Begin of function Unit::return_camp -----------//
  1917. //
  1918. // Order this unit to return to the camp. For ordering many
  1919. // units to return to a camp, UnitArray::return_camp() should
  1920. // be called instead.
  1921. //
  1922. int Unit::return_camp()
  1923. {
  1924. if( !home_camp_firm_recno )
  1925. return 0;
  1926. err_when( firm_array.is_deleted(home_camp_firm_recno) );
  1927. Firm* firmPtr = firm_array[home_camp_firm_recno];
  1928. if( firmPtr->region_id != region_id() )
  1929. return 0;
  1930. err_when( firmPtr->firm_id != FIRM_CAMP );
  1931. err_when( firmPtr->nation_recno != nation_recno );
  1932. //--------- assign now ---------//
  1933. assign(firmPtr->loc_x1, firmPtr->loc_y1);
  1934. force_move_flag = 1;
  1935. return cur_action != SPRITE_IDLE;
  1936. }
  1937. //----------- End of function Unit::return_camp -----------//
  1938. //----------- Begin of function Unit::unit_power -----------//
  1939. //
  1940. // Return a power index of the weapon, this is for calculating
  1941. // the total combat level of a target.
  1942. //
  1943. int Unit::unit_power()
  1944. {
  1945. UnitInfo* unitInfo = unit_res[unit_id];
  1946. if( unitInfo->unit_class == UNIT_CLASS_WEAPON )
  1947. {
  1948. return (int) hit_points + (unitInfo->weapon_power + get_weapon_version() - 1) * 15;
  1949. }
  1950. else
  1951. {
  1952. return (int) hit_points;
  1953. }
  1954. }
  1955. //----------- End of function Unit::unit_power -----------//
  1956. //----------- Begin of function Unit::get_cur_loc -----------//
  1957. //
  1958. // <short&> xLoc, yLoc - reference vars for returning the
  1959. // location of this unit
  1960. //
  1961. // return : 0 - if this unit is invisible
  1962. // 1 - if a location has been returned.
  1963. //
  1964. int Unit::get_cur_loc(short& xLoc, short& yLoc)
  1965. {
  1966. if( is_visible() )
  1967. {
  1968. xLoc = next_x_loc(); // update location
  1969. yLoc = next_y_loc();
  1970. }
  1971. else if( unit_mode == UNIT_MODE_OVERSEE ||
  1972. unit_mode==UNIT_MODE_CONSTRUCT ||
  1973. unit_mode == UNIT_MODE_IN_HARBOR )
  1974. {
  1975. Firm* firmPtr = firm_array[unit_mode_para];
  1976. xLoc = firmPtr->center_x;
  1977. yLoc = firmPtr->center_y;
  1978. }
  1979. else if( unit_mode == UNIT_MODE_ON_SHIP )
  1980. {
  1981. Unit* unitPtr = unit_array[unit_mode_para];
  1982. //### begin alex 22/10 ###//
  1983. //xLoc = unitPtr->next_x_loc();
  1984. //yLoc = unitPtr->next_y_loc();
  1985. if(unitPtr->is_visible())
  1986. {
  1987. xLoc = unitPtr->next_x_loc();
  1988. yLoc = unitPtr->next_y_loc();
  1989. }
  1990. else
  1991. {
  1992. err_when(unitPtr->unit_mode!=UNIT_MODE_IN_HARBOR);
  1993. Firm *firmPtr = firm_array[unitPtr->unit_mode_para];
  1994. xLoc = firmPtr->center_x;
  1995. yLoc = firmPtr->center_y;
  1996. }
  1997. //#### end alex 22/10 ####//
  1998. }
  1999. else
  2000. return 0;
  2001. return 1;
  2002. }
  2003. //----------- End of function Unit::get_cur_loc -----------//
  2004. //----------- Begin of function Unit::add_way_point -----------//
  2005. // Add the point to the way_point_array if it is not in the array.
  2006. // Otherwise, remove the point from the way_point_array.
  2007. //
  2008. // <short> x - x coordinate of the point
  2009. // <short> y - y coordinate of the point
  2010. //
  2011. void Unit::add_way_point(short x, short y)
  2012. {
  2013. if(way_point_count>=100)
  2014. return; // too many way point
  2015. if(way_point_count>1) // don't allow to remove the 1st node, since the unit is moving there
  2016. {
  2017. ResultNode *nodePtr = way_point_array + 1;
  2018. for(int i=1; i<way_point_count; ++i, nodePtr++)
  2019. {
  2020. if(nodePtr->node_x == x && nodePtr->node_y == y) // remove this node
  2021. {
  2022. m.del_array_rec(way_point_array, way_point_count, sizeof(ResultNode), i+1); // remove 1st node
  2023. way_point_count--;
  2024. return; // there should be one and only one node with the same value
  2025. }
  2026. }
  2027. }
  2028. //-------------- add new node -----------------//
  2029. if(way_point_count>=way_point_array_size) // buffer full
  2030. {
  2031. way_point_array_size += WAY_POINT_ADJUST_SIZE;
  2032. if(way_point_count)
  2033. way_point_array = (ResultNode*) mem_resize(way_point_array, way_point_array_size*sizeof(ResultNode));
  2034. else
  2035. way_point_array = (ResultNode*) mem_add(sizeof(ResultNode)*WAY_POINT_ADJUST_SIZE);
  2036. }
  2037. ResultNode *nodePtr = way_point_array + way_point_count;
  2038. nodePtr->node_x = x;
  2039. nodePtr->node_y = y;
  2040. way_point_count++;
  2041. if(way_point_count==1)
  2042. move_to(x, y);
  2043. }
  2044. //----------- End of function Unit::add_way_point -----------//
  2045. //----------- Begin of function Unit::reset_way_point_array -----------//
  2046. void Unit::reset_way_point_array()
  2047. {
  2048. //------------------------------------------------------------------------------------//
  2049. // There are nly two conditions to reset the way_point_array
  2050. // 1) action_mode2!=ACTION_MOVE in Unit::stop()
  2051. // 2) dest? != node_? in the first node of way_point_array in calling Unit::move_to()
  2052. //------------------------------------------------------------------------------------//
  2053. if(way_point_array_size)
  2054. {
  2055. mem_del(way_point_array);
  2056. way_point_array = NULL;
  2057. way_point_array_size = 0;
  2058. way_point_count = 0;
  2059. }
  2060. }
  2061. //----------- End of function Unit::reset_way_point_array -----------//
  2062. //----------- Begin of function Unit::process_way_point -----------//
  2063. // move to the next way point and remove this point from the
  2064. // way_point_array
  2065. //
  2066. void Unit::process_way_point()
  2067. {
  2068. err_when(action_mode!=ACTION_STOP || action_mode2!=ACTION_STOP || cur_action!=SPRITE_IDLE);
  2069. int destX, destY;
  2070. if(way_point_count>1)
  2071. {
  2072. ResultNode *nodePtr = way_point_array+1;
  2073. destX = nodePtr->node_x;
  2074. destY = nodePtr->node_y;
  2075. m.del_array_rec(way_point_array, way_point_count, sizeof(ResultNode), 1); // remove 1st node
  2076. way_point_count--;
  2077. }
  2078. else // only one unprocessed node
  2079. {
  2080. ResultNode *nodePtr = way_point_array;
  2081. destX = nodePtr->node_x;
  2082. destY = nodePtr->node_y;
  2083. //m.del_array_rec(way_point_array, way_point_count, sizeof(ResultNode), 1); // remove 1st node
  2084. //way_point_count--;
  2085. }
  2086. move_to(destX, destY);
  2087. }
  2088. //----------- End of function Unit::process_way_point -----------//
  2089. //----------- Begin of function TeamInfo::TeamInfo ---------//
  2090. TeamInfo::TeamInfo()
  2091. {
  2092. memset( this, 0, sizeof(TeamInfo) );
  2093. }
  2094. //----------- End of function TeamInfo::TeamInfo ---------//