123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OF_CAMP2.CPP
- //Description : Firm Military Camp - AI functions
- #include <ONATION.h>
- #include <OINFO.h>
- #include <OCONFIG.h>
- #include <OTOWN.h>
- #include <OSPY.h>
- #include <OUNIT.h>
- #include <OF_CAMP.h>
- //--------- Begin of function FirmCamp::init_derived ---------//
- void FirmCamp::init_derived()
- {
- patrol_unit_count = 0;
- coming_unit_count = 0;
- ai_capture_town_recno = 0;
- ai_recruiting_soldier = 1;
- }
- //----------- End of function FirmCamp::init_derived -----------//
- //--------- Begin of function FirmCamp::process_ai ---------//
- void FirmCamp::process_ai()
- {
- if( info.game_date%15==firm_recno%15 ) // do not call too often as the penalty of accumulation is 10 days
- think_use_cash_to_capture();
- //------- assign overseer and workers -------//
- if( info.game_date%15==firm_recno%15 ) // do not call too often because when an AI action is queued, it will take a while to carry it out
- think_recruit();
- //---- if this firm is currently trying to capture a town ----//
- if( ai_capture_town_recno )
- {
- should_close_flag = 0; // disable should_close_flag when trying to capture a firm, should_close_flag is set in process_common_ai()
- if( nation_array[nation_recno]->attack_camp_count==0 && // only when attack_camp_count==0, the attack mission is complete
- patrol_unit_count==0 )
- {
- ai_capture_town_recno = 0;
- defense_flag = 1; // turn it on again after the capturing plan is finished
- return;
- }
- // process_ai_capturing();
- return;
- }
- //--- if the firm is empty and should be closed, sell/destruct it now ---//
- if( should_close_flag )
- {
- if( worker_count==0 )
- {
- ai_del_firm();
- return;
- }
- }
- //----- think about assigning a better commander -----//
- if( info.game_date%30==firm_recno%30 )
- think_assign_better_commander();
- //----- think about changing links to foreign town -----//
- if( info.game_date%30==firm_recno%30 )
- think_change_town_link();
- //------ think about attacking enemies nearby -------//
- int checkInterval = 13 - nation_array[nation_recno]->pref_military_development/10;
- if( info.game_date%checkInterval == firm_recno%checkInterval )
- think_attack_nearby_enemy();
- //------ think about capturing independent town -------//
- static short interval_days_array[] = { 60, 30, 20, 10 };
- int intervalDays = interval_days_array[config.ai_aggressiveness-1];
- if( info.game_date%intervalDays == firm_recno%intervalDays ) // do not call too often because when an AI action is queued, it will take a while to carry it out
- think_capture();
- //---------------------------------------//
- if( info.game_date%30 == firm_recno%30 )
- {
- ai_reset_defense_mode(); // reset defense mode if all soldiers are dead
- }
- }
- //----------- End of function FirmCamp::process_ai -----------//
- //--------- Begin of function FirmCamp::ai_reset_defense_mode ---------//
- void FirmCamp::ai_reset_defense_mode()
- {
- if(ai_status!=CAMP_IN_DEFENSE)
- return;
- //------------------------------------------------------------//
- // reset defense mode if all soldiers are dead
- //------------------------------------------------------------//
- DefenseUnit *defPtr = defense_array;
- Unit *unitPtr;
- int found=0;
- for(int i=0; i<=MAX_WORKER; i++, defPtr++)
- {
- if(!defPtr->unit_recno)
- continue; // empty slot
- if(unit_array.is_deleted(defPtr->unit_recno))
- continue;
- unitPtr = unit_array[defPtr->unit_recno];
- if(unitPtr->nation_recno==nation_recno && unitPtr->action_misc==ACTION_MISC_DEFENSE_CAMP_RECNO &&
- unitPtr->action_misc_para==firm_recno) // is a soldier of this camp
- found++;
- }
- if(!found)
- {
- set_employ_worker(1); // all soldiers have died, reset defense mode to employ new workers
- memset(defense_array, 0, sizeof(DefenseUnit)*(MAX_WORKER+1));
- }
- }
- //----------- End of function FirmCamp::ai_reset_defense_mode -----------//
- //--------- Begin of function FirmCamp::process_ai_capturing ---------//
- //
- // This function is called when the AI is in the process of
- // attacking and capturing the independent town this camp is
- // linked to.
- //
- void FirmCamp::process_ai_capturing()
- {
- err_when( patrol_unit_count <= 0 ); // this function shouldn't be called at all if patrol_unit_count==0
- err_when( patrol_unit_count>9 );
- if( !ai_capture_town_recno )
- return;
- if( think_capture_return() ) // if the capturing units should now return to their base.
- return;
- //--- there are still town defender out there, order idle units to attack them ---//
- Unit* unitPtr;
- Town* townPtr = town_array[ai_capture_town_recno];
- if( townPtr->town_defender_count > 0 )
- {
- for( int i=patrol_unit_count ; i>0 ; i-- )
- {
- unitPtr = unit_array[ patrol_unit_array[i-1] ];
- if( unitPtr->cur_action == SPRITE_IDLE )
- ai_attack_town_defender(unitPtr);
- }
- }
- //--- if the town is still not captured but all mobile town defenders are destroyed, attack the town again ---//
- if( townPtr->town_defender_count == 0 )
- {
- //----- have one of the units attack the town ----//
- short unitArray[1];
- err_when( patrol_unit_count<=0 );
- unitArray[0] = patrol_unit_array[ m.random(patrol_unit_count) ];
- err_when( unit_array.is_deleted(unitArray[0]) );
- if( townPtr->nation_recno )
- nation_array[nation_recno]->set_relation_should_attack( townPtr->nation_recno, 1, COMMAND_AI );
- // ##### patch begin Gilbert 5/8 ######//
- unit_array.attack(townPtr->loc_x1, townPtr->loc_y1, 0, unitArray, 1, COMMAND_AI, 0);
- // ##### patch end Gilbert 5/8 ######//
- }
- }
- //----------- End of function FirmCamp::process_ai_capturing -----------//
- //------ Begin of function FirmCamp::ai_attack_town_defender ------//
- //
- void FirmCamp::ai_attack_town_defender(Unit* attackerUnit)
- {
- int shouldAttackUnit=0;
- if( attackerUnit->cur_action == SPRITE_IDLE )
- shouldAttackUnit = 1;
- else if( attackerUnit->cur_action == SPRITE_ATTACK )
- {
- //--- if this unit is currently attacking the town, ask it to attack a defender unit ---//
- Town* townPtr = town_array[ai_capture_town_recno];
- if( attackerUnit->action_x_loc==townPtr->loc_x1 && attackerUnit->action_y_loc==townPtr->loc_y1 )
- shouldAttackUnit = 1;
- }
- if( !shouldAttackUnit )
- return;
- //---- if there are still town defenders out there ---//
- int unitCount = unit_array.size();
- int unitRecno = m.random(unitCount)+1; // scan randomly
- short unitArray[1];
- Unit* targetUnit;
- for( int i=0 ; i<unitCount ; i++ )
- {
- if( ++unitRecno > unitCount )
- unitRecno = 1;
- if( unit_array.is_deleted(unitRecno) )
- continue;
- targetUnit = unit_array[unitRecno];
- if( targetUnit->unit_mode == UNIT_MODE_DEFEND_TOWN &&
- targetUnit->unit_mode_para == ai_capture_town_recno )
- {
- unitArray[0] = attackerUnit->sprite_recno;
- if( targetUnit->nation_recno )
- nation_array[nation_recno]->set_relation_should_attack( targetUnit->nation_recno, 1, COMMAND_AI );
- // ##### patch begin Gilbert 5/8 ######//
- unit_array.attack( targetUnit->next_x_loc(), targetUnit->next_y_loc(),
- 0, unitArray, 1, COMMAND_AI, targetUnit->sprite_recno );
- // ##### patch end Gilbert 5/8 ######//
- break;
- }
- }
- }
- //-------- End of function FirmCamp::ai_attack_town_defender ------//
- //--------- Begin of function FirmCamp::think_recruit ---------//
- //
- // Think about recruiting an overseer and soliders to this base.
- //
- void FirmCamp::think_recruit()
- {
- if( patrol_unit_count ) // if there are units of this camp patrolling outside
- return;
- Nation* nationPtr = nation_array[nation_recno];
- ai_recruiting_soldier = 1; // the AI is currently trying to recruit soldiers
- //---- if there are currently units coming to this firm ----//
- if( coming_unit_count > 0 )
- {
- Unit* unitPtr;
- for( int i=0 ; i<coming_unit_count ; i++ )
- {
- if( unit_array.is_deleted( coming_unit_array[i] ) )
- continue;
- unitPtr = unit_array[ coming_unit_array[i] ];
- //--- check if any of them are still on their way to this firm ---//
- if( unitPtr->nation_recno == nation_recno &&
- unitPtr->action_mode == ACTION_ASSIGN_TO_FIRM )
- {
- //--- if so, do not do anything unit they are all done ---//
- return;
- }
- }
- coming_unit_count = 0;
- }
- //-- if this camp is empty, think about move a whole troop from a useless camp (should_ai_close()==1)
- if( !overseer_recno && worker_count==0 &&
- nationPtr->firm_should_close_array[FIRM_CAMP-1] > 0 )
- {
- FirmCamp *firmCamp, *bestCampPtr=NULL;
- int bestRating=0, curRating;
- //--- see if there are any useless camps around and pick the most suitable one ---//
- for( int i=nationPtr->ai_camp_count-1 ; i>=0 ; i-- )
- {
- firmCamp = (FirmCamp*) firm_array[ nationPtr->ai_camp_array[i] ];
- err_when( firmCamp->firm_id != FIRM_CAMP );
- if( firmCamp->region_id != region_id )
- continue;
- if( firmCamp->should_close_flag &&
- (firmCamp->overseer_recno || firmCamp->worker_count>0) )
- {
- curRating = 100 - m.points_distance( center_x, center_y,
- firmCamp->center_x, firmCamp->center_y );
- if( curRating > bestRating )
- {
- bestRating = curRating;
- bestCampPtr = firmCamp;
- }
- }
- }
- //--------- start the move now -------//
- if( bestCampPtr )
- {
- bestCampPtr->patrol();
- if( bestCampPtr->patrol_unit_count==0 ) // there could be chances that there are no some for mobilizing the units
- return;
- //--- set coming_unit_count for later checking ---//
- err_when( sizeof(coming_unit_array) != sizeof(patrol_unit_array) );
- memcpy( coming_unit_array, bestCampPtr->patrol_unit_array, sizeof(coming_unit_array) );
- coming_unit_count = bestCampPtr->patrol_unit_count;
- //---- order the unit to move to this camp now ---//
- unit_array.assign(loc_x1, loc_y1, 0, COMMAND_AI, bestCampPtr->patrol_unit_array, bestCampPtr->patrol_unit_count);
- //------ delete the camp as it no longer has any use ----//
-
- bestCampPtr->ai_del_firm();
- return;
- }
- }
- //------- get an overseer if there isn't any right now -----//
- if( !overseer_recno )
- nationPtr->add_action(loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP);
- //---- think about the no. of workers needed for this base ----//
- int combatDiff;
- if( overseer_recno == nationPtr->king_unit_recno ) // recruit as many soldiers as possible if the commander is the king
- {
- combatDiff = 1000;
- }
- else if( nationPtr->total_jobless_population > 20 + (100-nationPtr->pref_military_development) / 3 ) // 20 to 53
- {
- combatDiff = 1000; // recruit as many as possible
- }
- else
- {
- int combatLevelNeeded = ai_combat_level_needed();
- combatDiff = combatLevelNeeded - total_combat_level();
- }
- if( combatDiff > 0 )
- {
- ai_recruit(combatDiff);
- }
- else
- {
- if( overseer_recno )
- ai_recruiting_soldier = 0; // this firm has enough soldiers already
- }
- }
- //----------- End of function FirmCamp::think_recruit ----------//
- //--------- Begin of function FirmCamp::ai_recruit ---------//
- //
- // <int> recruitCombatLevel - the combat level needed to be added.
- //
- // return: <int> 1-succeeded, 0-failed.
- //
- int FirmCamp::ai_recruit(int recruitCombatLevel)
- {
- if( worker_count == MAX_WORKER || !overseer_recno )
- return 0;
- int recruitCount = max( 1, recruitCombatLevel / 20 );
- recruitCount = min( recruitCount, MAX_WORKER-worker_count );
- //--- first try to recruit soldiers directly from a linked village ---//
- int majorityRace = majority_race();
- int raceId;
- int loopCount=0;
- Town* townPtr;
- for( int i=0 ; i<linked_town_count ; i++ )
- {
- townPtr = town_array[ linked_town_array[i] ];
- if( townPtr->nation_recno != nation_recno || !townPtr->jobless_population )
- continue;
- //-- recruit majority race first, but will also consider other races --//
- raceId = max( 1, majorityRace );
- for( int j=0 ; j<MAX_RACE ; j++ )
- {
- if( ++raceId > MAX_RACE )
- raceId = 1;
- //--- if the loyalty is too low, reward before recruiting ---//
- if( townPtr->jobless_race_pop_array[raceId-1] > 0 &&
- townPtr->race_loyalty_array[raceId-1] < 40 )
- {
- if( townPtr->accumulated_reward_penalty > 30 ) // if the reward penalty is too high, do reward
- break;
- townPtr->reward(COMMAND_AI);
- }
- //---- recruit the soldiers we needed ----//
- while( townPtr->can_recruit(raceId) )
- {
- err_when( ++loopCount > 1000 );
- pull_town_people(townPtr->town_recno, COMMAND_AI, raceId, 1); // last 1-force pulling people from the town to the firm
- if( --recruitCount == 0 )
- return 1;
- }
- }
- }
- //------ next, try to recruit from remote villages -----//
- if( recruitCount > 0 )
- nation_array[nation_recno]->add_action(loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_WORKER, FIRM_CAMP, recruitCount);
- return 1;
- }
- //----------- End of function FirmCamp::ai_recruit ----------//
- //--------- Begin of function FirmCamp::ai_combat_level_needed ---------//
- //
- // Think about the no. of soldiers needed by this base.
- //
- int FirmCamp::ai_combat_level_needed()
- {
- Town* townPtr;
- int combatNeeded=0;
- Nation* nationPtr = nation_array[nation_recno];
- //------- scan for linked towns ---------//
- for( int i=0 ; i<linked_town_count ; i++ )
- {
- townPtr = town_array[ linked_town_array[i] ];
- //------- this is its own town -------//
- if( townPtr->nation_recno == nation_recno )
- {
- if( townPtr->should_ai_migrate() ) // no need for this if this town is going to migrate
- continue;
- combatNeeded += townPtr->population * 10; // 30 people need 300 combat levels
- if( townPtr->is_base_town )
- combatNeeded += townPtr->population * 10; // double the combat level need for base town
- }
- }
- //--- if the overseer is the king, increase its combat level needed ---//
- if( overseer_recno && unit_array[overseer_recno]->rank_id == RANK_KING )
- combatNeeded = max(400, combatNeeded);
- //---------------------------------------//
- return combatNeeded;
- }
- //----------- End of function FirmCamp::ai_combat_level_needed ----------//
- //--------- Begin of function FirmCamp::total_combat_level ---------//
- //
- // Total combat level of all soldiers and commander in the base.
- // The leadership of the general also applies to the final combat level.
- //
- // return: <int> the total combat level - it is the sum of hit points
- // of all the units in the camp.
- //
- int FirmCamp::total_combat_level()
- {
- int totalCombatLevel=0;
- Worker* workerPtr = worker_array;
- for( int i=0 ; i<worker_count ; i++, workerPtr++ )
- {
- totalCombatLevel += workerPtr->hit_points; // use it points instead of combat level because hit_points represent both combat level and hit points left
- err_when( totalCombatLevel < 0 );
- //---- the combat level of weapons are higher ------//
- UnitInfo* unitInfo = unit_res[workerPtr->unit_id];
- if( unitInfo->unit_class == UNIT_CLASS_WEAPON )
- totalCombatLevel += (unitInfo->weapon_power + workerPtr->extra_para - 1) * 30; // extra_para keeps the weapon version
- err_when( totalCombatLevel < 0 );
- }
- if( overseer_recno )
- {
- Unit* unitPtr = unit_array[overseer_recno];
- //--- the commander's leadership effects over the soldiers ---//
- totalCombatLevel += totalCombatLevel * unitPtr->skill.skill_level / 150; // divided by 150 instead of 100 because while the attacking ability of the unit is affected by the general, the hit points isn't, so we shouldn't do a direct multiplication.
- //------ the leader's own hit points ------//
- totalCombatLevel += (int) unitPtr->hit_points;
- err_when( totalCombatLevel < 0 );
- }
- return totalCombatLevel;
- }
- //----------- End of function FirmCamp::total_combat_level ----------//
- //--------- Begin of function FirmCamp::average_combat_level ---------//
- //
- int FirmCamp::average_combat_level()
- {
- int personCount = worker_count + (overseer_recno>0);
- if( personCount > 0 )
- return total_combat_level() / personCount;
- else
- return 0;
- }
- //----------- End of function FirmCamp::average_combat_level ----------//
- //--------- Begin of function FirmCamp::ai_should_close ---------//
- //
- // Whether this AI firm should be closed or not.
- //
- int FirmCamp::ai_should_close()
- {
- return linked_town_count==0 && linked_firm_count==0;
- }
- //----------- End of function FirmCamp::ai_should_close ----------//
- //--------- Begin of function FirmCamp::think_capture ---------//
- //
- // Think about capturing towns.
- //
- void FirmCamp::think_capture()
- {
- if( is_attack_camp ) // if this camp has been assigned to an attack mission already
- return;
- int targetTownRecno = think_capture_target_town();
- if( !targetTownRecno )
- return;
- //----- if the target town is a nation town -----//
- Town* targetTown = town_array[targetTownRecno];
- Nation* ownNation = nation_array[nation_recno];
- if( targetTown->nation_recno )
- {
- //--- if there are any defenses (camps and mobile units) on the target town, destroy them all first -----//
- if( ownNation->attack_enemy_town_defense(targetTown) != -1 ) // only proceed further when the result is -1, which means no defense on the target town, no attacking is needed.
- return;
- }
- //------ check if the town people will go out to defend -----//
- float thisResistance, resistanceDiff;
- int defenseCombatLevel=0;
- for( int i=0 ; i<MAX_RACE ; i++ )
- {
- if( targetTown->race_pop_array[i] < 5 ) // if the pop count is lower than 5, ingore it
- continue;
- if( targetTown->nation_recno )
- {
- thisResistance = targetTown->race_loyalty_array[i];
- resistanceDiff = thisResistance - MIN_NATION_DEFEND_LOYALTY;
- }
- else
- {
- thisResistance = targetTown->race_resistance_array[i][nation_recno-1];
- resistanceDiff = thisResistance - MIN_INDEPENDENT_DEFEND_LOYALTY;
- }
- if( resistanceDiff >= 0 )
- {
- float resistanceDecPerDefender = thisResistance/targetTown->race_pop_array[i]; // resistance decrease per new defender
- int defenderCount = int(resistanceDiff / resistanceDecPerDefender)+1; // no. of defenders will go out if you attack this town
- defenseCombatLevel += targetTown->town_combat_level * 2 * defenderCount; // *2 is defenseCombatLevel is actually the sum of hit points, not combat level
- }
- }
- //--- try using spies if there are defense forces and the nation likes to use spies ---//
- if( defenseCombatLevel > 0 ) // && ownNation->pref_spy >= 50 && m.random(3)==0 ) // 1/3 chance of using spies here, otherwise only use spies when we are not strong enough to take over the village by force
- {
- if( targetTown->nation_recno==0 ) // if the camp is trying to capture an independent town, the leadership and race id. of the overseer matters.
- {
- if( think_assign_better_overseer(targetTown) ) // a better general is being assigned to this firm, wait for it
- return;
- if( think_capture_use_spy(targetTown) )
- return;
- if( defenseCombatLevel > 100+ownNation->pref_military_courage &&
- resistanceDiff > (100-ownNation->pref_peacefulness)/5 ) // depending on the peacefulness, the nation won't attack if resistance > (0-20)
- {
- return;
- }
- }
- else
- {
- //--- don't attack if the target nation's military rating is higher than ours ---//
- if( nation_array[targetTown->nation_recno]->military_rank_rating()
- > ownNation->military_rank_rating() )
- {
- return;
- }
- }
- }
- //------ send out troops to capture the target town now ----//
- int rc;
- if( targetTown->nation_recno )
- rc = ai_capture_enemy_town(targetTown, defenseCombatLevel);
- else
- rc = ai_capture_independent_town(targetTown, defenseCombatLevel);
- //-- use the same approach to capture both enemy and independent towns --//
- if( rc )
- {
- ai_capture_town_recno = targetTownRecno;
- defense_flag = 0; // turn off the defense flag during capturing so the general is staying in the base to influence the town
- //--- as the current commander has been out to attack the town by ai_attack_target(), we need to assign him back to the camp for influencing the town and eventually capture it ---//
- if( !overseer_recno && targetTown->nation_recno && patrol_unit_count>0 )
- unit_array[ patrol_unit_array[0] ]->assign(loc_x1, loc_y1);
- }
- }
- //----------- End of function FirmCamp::think_capture -----------//
- //--------- Begin of function FirmCamp::think_capture_target_town ---------//
- //
- // Think about which town to capture.
- //
- // Return: <int> recno of the target town.
- //
- int FirmCamp::think_capture_target_town()
- {
- if( !linked_town_count || !overseer_recno )
- return 0;
- //--- if there are any units currently being assigned to this camp ---//
- if( nation_array[nation_recno]->is_action_exist( loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_WORKER, FIRM_CAMP ) )
- return 0;
- //-- decide which town to attack (only when the camp is linked to more than one town ---//
- int curResistance, curTargetResistance, resistanceDec;
- int i, minResistance=100, bestTownRecno=0;
- Town* townPtr;
- int prefPeacefulness = nation_array[nation_recno]->pref_peacefulness;
- Nation* ownNation = nation_array[nation_recno];
- int overseerRaceId = unit_array[overseer_recno]->race_id;
- for( i=0 ; i<linked_town_count ; i++ )
- {
- townPtr = town_array[ linked_town_array[i] ];
- if( townPtr->nation_recno == nation_recno )
- continue;
- //------- if it's an independent town -------//
- if( !townPtr->nation_recno ) // only capture independent town
- {
- curResistance = townPtr->average_resistance(nation_recno);
- curTargetResistance = townPtr->average_target_resistance(nation_recno);
- resistanceDec = curResistance - curTargetResistance;
- //------- if the resistance is decreasing ---------//
- if( resistanceDec > 0 &&
- curResistance > 25-25*ownNation->pref_peacefulness/100 && // for nation that has a high peacefulness preference they will wait for the loyalty to fall and try not to attack the town unless necessary
- townPtr->race_pop_array[overseerRaceId-1] >= 5 ) // if it's less than 5, don't count it, as that it will be easy to attack
- {
- continue; // let it decrease until it can no longer decrease
- }
- }
- else //-------- if it's a nation town ---------//
- {
- NationRelation* nationRelation = ownNation->get_relation(townPtr->nation_recno);
- if( nationRelation->status != NATION_HOSTILE )
- continue;
- curResistance = townPtr->average_loyalty();
- }
- //--------------------------------------//
- if( curResistance < minResistance )
- {
- minResistance = curResistance;
- bestTownRecno = townPtr->town_recno;
- }
- }
- return bestTownRecno;
- }
- //--------- End of function FirmCamp::think_capture_target_town --------//
- //--------- Begin of function FirmCamp::ai_capture_independent_town -------//
- //
- // Try to capture the given independent town.
- //
- int FirmCamp::ai_capture_independent_town(Town* targetTown, int defenseCombatLevel)
- {
- //---- see if the force is strong enough to attack the town ----//
- Nation* nationPtr = nation_array[nation_recno];
- int curCombatLevel = total_combat_level(); // total combat level
- int combatDiff = defenseCombatLevel * (150+nationPtr->pref_force_projection/2) / 100
- - curCombatLevel; // try to recruit soldiers based on the force projection perference
- if( combatDiff > 0 )
- {
- if( ai_recruit(combatDiff) ) // try to recruit new soldiers to increase the combat ability of the troop
- return 0;
- }
- combatDiff = defenseCombatLevel * (200-nationPtr->pref_military_courage/2) / 100
- - curCombatLevel;
- //---------- attack the target town now ----------//
- if( nation_array[nation_recno]->ai_attack_target(targetTown->loc_x1, targetTown->loc_y1, defenseCombatLevel, 0, 0, 0, firm_recno) )
- return 1;
- return 0;
- }
- //--------- End of function FirmCamp::ai_capture_independent_town --------//
- //--------- Begin of function FirmCamp::think_capture_return ---------//
- //
- // Think about if the capturing units should now return to their base.
- //
- int FirmCamp::think_capture_return()
- {
- //----- if the target town is destroyed ------//
- int returnCamp=0;
- if( town_array.is_deleted(ai_capture_town_recno) )
- {
- returnCamp = 1;
- }
- else //---- check whether the town has been captured ----//
- {
- Town* townPtr = town_array[ai_capture_town_recno];
- if( townPtr->nation_recno == nation_recno ) // the town has been captured
- returnCamp = 1;
- }
- //-------- if should return to the camp now ---------//
- if( returnCamp )
- {
- Unit* unitPtr;
- for( int i=0; i<patrol_unit_count ; i++ )
- {
- unitPtr = unit_array[ patrol_unit_array[i] ];
- if( unitPtr->is_visible() )
- unitPtr->assign(loc_x1, loc_y1);
- }
- ai_capture_town_recno = 0; // turn it on again after the capturing plan is finished
- defense_flag = 1;
- return 1;
- }
- return 0;
- }
- //----------- End of function FirmCamp::think_capture_return -----------//
- //--------- Begin of function FirmCamp::think_assign_better_overseer -------//
- //
- int FirmCamp::think_assign_better_overseer(Town* targetTown)
- {
- //----- check if there is already a queued action -----//
- Nation* ownNation = nation_array[nation_recno];
- if( ownNation->is_action_exist( loc_x1, loc_y1, -1, -1,
- ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP ) )
- {
- return 1; // there is a queued action being processed already
- }
- //------ get the two most populated races of the town ----//
- int mostRaceId1, mostRaceId2;
- targetTown->get_most_populated_race(mostRaceId1, mostRaceId2);
- //-- if the resistance of the majority race has already dropped to its lowest possible --//
- if( targetTown->race_resistance_array[mostRaceId1-1][nation_recno-1] <=
- (float) (targetTown->race_target_resistance_array[mostRaceId1-1][nation_recno-1]+1) )
- {
- if( targetTown->race_resistance_array[mostRaceId1-1][nation_recno-1] > 30 )
- {
- if( think_assign_better_overseer2(targetTown->town_recno, mostRaceId1) )
- return 1;
- }
- }
- //-- if the resistance of the 2nd majority race has already dropped to its lowest possible --//
- if( targetTown->race_resistance_array[mostRaceId2-1][nation_recno-1] <=
- (float) (targetTown->race_target_resistance_array[mostRaceId2-1][nation_recno-1]+1) )
- {
- if( targetTown->race_resistance_array[mostRaceId2-1][nation_recno-1] > 30 )
- {
- if( think_assign_better_overseer2(targetTown->town_recno, mostRaceId2) )
- return 1;
- }
- }
- return 0;
- }
- //--------- End of function FirmCamp::think_assign_better_overseer --------//
- //--------- Begin of function FirmCamp::think_assign_better_overseer2 -------//
- //
- int FirmCamp::think_assign_better_overseer2(int targetTownRecno, int raceId)
- {
- int reduceResistance;
- Nation* ownNation = nation_array[nation_recno];
- int bestUnitRecno = ownNation->find_best_capturer(targetTownRecno, raceId, reduceResistance);
- if( !bestUnitRecno || bestUnitRecno==overseer_recno ) // if we already got the best one here
- return 0;
- //---- only assign new overseer if the new one's leadership is significantly higher than the current one ----//
- if( overseer_recno &&
- unit_array[bestUnitRecno]->skill.skill_level < unit_array[overseer_recno]->skill.skill_level + 15 )
- {
- return 0;
- }
- //------ check what the best unit is -------//
- if( !ownNation->mobilize_capturer(bestUnitRecno) )
- return 0;
- //---------- add the action to the queue now ----------//
- int actionRecno = ownNation->add_action( loc_x1, loc_y1, -1, -1,
- ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP, 1, bestUnitRecno );
- if( actionRecno )
- ownNation->process_action(actionRecno);
- return 1;
- }
- //--------- End of function FirmCamp::think_assign_better_overseer2 --------//
- //--------- Begin of function FirmCamp::ai_capture_enemy_town -------//
- //
- // When capturing an enemy town, the commander should stay in the
- // command base to influence the village and reinforcement should be
- // sent instead of using the troop in the base for attacking the enemies.
- //
- int FirmCamp::ai_capture_enemy_town(Town* targetTown, int defenseCombatLevel)
- {
- int useAllCamp;
- Nation* ownNation = nation_array[nation_recno];
- Nation* targetNation = nation_array[targetTown->nation_recno];
- int ourMilitary = ownNation->military_rank_rating();
- int enemyMilitary = targetNation->military_rank_rating();
- //--- use all camps to attack if we have money and we are stronger than the enemy ---//
- if( ourMilitary - enemyMilitary > 30 && ownNation->ai_should_spend(ownNation->pref_military_courage/2) )
- useAllCamp = 1;
- //---- use all camps to attack the enemy if the enemy is a human player
- else if( config.ai_aggressiveness >= OPTION_MEDIUM &&
- !targetNation->is_ai() && ourMilitary > enemyMilitary )
- {
- if( config.ai_aggressiveness >= OPTION_HIGH ||
- ownNation->pref_peacefulness < 50 )
- {
- useAllCamp = 1;
- }
- }
- return nation_array[nation_recno]->ai_attack_target(targetTown->loc_x1, targetTown->loc_y1,
- defenseCombatLevel, 0, 0, 0, firm_recno, useAllCamp );
- }
- //--------- End of function FirmCamp::ai_capture_enemy_town --------//
- //--------- Begin of function FirmCamp::think_capture_use_spy ---------//
- //
- // Think about using spies for capturing the target town.
- //
- int FirmCamp::think_capture_use_spy(Town* targetTown)
- {
- Nation* ownNation = nation_array[nation_recno];
- //------ get the two most populated races of the town ----//
- int mostRaceId1, mostRaceId2;
- targetTown->get_most_populated_race(mostRaceId1, mostRaceId2);
- //-- get the current number of our spies in this town and see if we need more --//
- int spyCount;
- int curSpyLevel = spy_array.total_spy_skill_level( SPY_TOWN, targetTown->town_recno, nation_recno, spyCount );
- //--------------------------------------------//
- int rc=0;
- if( think_capture_use_spy2(targetTown, mostRaceId1, curSpyLevel ) )
- rc = 1;
- if( mostRaceId2 )
- {
- if( think_capture_use_spy2(targetTown, mostRaceId2, curSpyLevel ) )
- rc = 1;
- }
- return rc;
- }
- //----------- End of function FirmCamp::think_capture_use_spy -----------//
- //--------- Begin of function FirmCamp::think_capture_use_spy2 ---------//
- //
- // Think about using spies for capturing the target town.
- //
- int FirmCamp::think_capture_use_spy2(Town* targetTown, int raceId, int curSpyLevel)
- {
- Nation* ownNation = nation_array[nation_recno];
- int curResistance, targetResistance;
- if( targetTown->nation_recno )
- {
- curResistance = (int) targetTown->race_loyalty_array[raceId-1];
- targetResistance = targetTown->race_target_loyalty_array[raceId-1];
- }
- else
- {
- curResistance = (int) targetTown->race_resistance_array[raceId-1][nation_recno-1];
- targetResistance = targetTown->race_target_resistance_array[raceId-1][nation_recno-1];
- }
- int minResistance = min(curResistance, targetResistance);
- //----- if the resistance is low enough, don't have to use spies -----//
- if( targetTown->nation_recno )
- {
- if( minResistance < MIN_NATION_DEFEND_LOYALTY )
- return 0;
- }
- else
- {
- if( minResistance < MIN_INDEPENDENT_DEFEND_LOYALTY )
- return 0;
- }
- //----- if the needed spy level > current spy level, assign more spies ----//
- int neededSpyLevel = minResistance * (50+ownNation->pref_spy) / 50;
- if( neededSpyLevel > curSpyLevel )
- return ownNation->ai_assign_spy_to_town(targetTown->town_recno, raceId);
- return 0;
- }
- //----------- End of function FirmCamp::think_capture_use_spy2 -----------//
- //--------- Begin of function FirmCamp::ai_update_link_status ---------//
- //
- // Updating link status of this firm with towns.
- //
- // It's a overloaded function of Firm::ai_update_link_status().
- //
- void FirmCamp::ai_update_link_status()
- {
- Nation* ownNation = nation_array[nation_recno];
- //------ always enable links to all towns -----//
- for( int i=0 ; i<linked_town_count ; i++ )
- {
- Town* townPtr = town_array[linked_town_array[i]];
- //---- don't try to capture other nation's towns unless the AI is at war or tense with the nation ----//
- if( townPtr->nation_recno &&
- ownNation->get_relation_status(townPtr->nation_recno) <= NATION_TENSE ) // hostile or tense
- {
- continue;
- }
- toggle_town_link( i+1, 1, COMMAND_AI );
- //------------------------------------------------------------------//
- // Here we only update this camp's link to the town.
- // The town's link to this firm is updated in Town::update_target_loyalty().
- //------------------------------------------------------------------//
- }
- }
- //----------- End of function FirmCamp::ai_update_link_status ----------//
- //------- Begin of function FirmCamp::ai_has_excess_worker -------//
- //
- // Return whether this firm has any excessive soldiers or not.
- //
- int FirmCamp::ai_has_excess_worker()
- {
- if( linked_town_count==0 )
- return 1;
- if( ai_capture_town_recno ) // no if the camp is trying to capture an independent town
- return 0;
- if( is_attack_camp ) // no if the camp is trying to capture an independent town
- return 0;
- if( should_close_flag )
- return 1;
- return 0;
- // return total_combat_level() > ai_combat_level_needed()+100;
- }
- //--------- End of function FirmCamp::ai_has_excess_worker -------//
- //------- Begin of function FirmCamp::think_use_cash_to_capture -------//
- //
- // Think about using money to decrease the resistance of the
- // independent villagers.
- //
- int FirmCamp::think_use_cash_to_capture()
- {
- if( !nation_array[nation_recno]->should_use_cash_to_capture() )
- return 0;
- //-------------------------------------//
- Town* townPtr;
- for( int i=0 ; i<linked_town_count ; i++ )
- {
- townPtr = town_array[ linked_town_array[i] ];
- if( townPtr->nation_recno == nation_recno )
- continue;
- if( townPtr->accumulated_enemy_grant_penalty > 0 )
- continue;
- if( townPtr->can_grant_to_non_own_town(nation_recno) )
- townPtr->grant_to_non_own_town(nation_recno, COMMAND_AI);
- }
- return 1;
- }
- //--------- End of function FirmCamp::think_use_cash_to_capture -------//
- //------- Begin of function FirmCamp::think_linked_town_change_nation ------//
- //
- // This function is called by Town::set_nation() when a town linked
- // to this firm has changed nation.
- //
- // <int> linkedTownRecno - the recno of the town that has changed nation.
- // <int> oldNationRecno - the old nation recno of the town
- // <int> newNationRecno - the new nation recno of the town
- //
- void FirmCamp::think_linked_town_change_nation(int linkedTownRecno, int oldNationRecno, int newNationRecno)
- {
- //-----------------------------------------------//
- //
- // If we are trying to capture an independent town and our
- // enemies have managed to capture it first.
- //
- //-----------------------------------------------//
- Nation* ownNation = nation_array[nation_recno];
- if( oldNationRecno==0 && newNationRecno>0 && newNationRecno != nation_recno )
- {
- Town* townPtr = town_array[linkedTownRecno];
- //--- if the town does not have any protection, then don't remove this camp ---//
- if( townPtr->protection_available()==0 )
- return;
- should_close_flag = 1;
- ownNation->firm_should_close_array[firm_id-1]++;
- }
- }
- //-------- End of function FirmCamp::think_linked_town_change_nation ------//
- //------- Begin of function FirmCamp::think_attack_nearby_enemy -------//
- //
- // Think about attacking enemies near this cmap.
- //
- int FirmCamp::think_attack_nearby_enemy()
- {
- //------------------------------------------//
- Nation* nationPtr = nation_array[nation_recno];
- int scanRange = 6 + nationPtr->pref_military_courage/20; // 6 to 11
- int xLoc1 = loc_x1 - scanRange;
- int yLoc1 = loc_y1 - scanRange;
- int xLoc2 = loc_x2 + scanRange;
- int yLoc2 = loc_y2 + scanRange;
- xLoc1 = max( xLoc1, 0 );
- yLoc1 = max( yLoc1, 0 );
- xLoc2 = min( xLoc2, MAX_WORLD_X_LOC-1 );
- yLoc2 = min( yLoc2, MAX_WORLD_Y_LOC-1 );
- //------------------------------------------//
- int enemyCombatLevel=0; // the higher the rating, the easier we can attack the target town.
- int xLoc, yLoc;
- int enemyXLoc= -1, enemyYLoc;
- Unit* unitPtr;
- Location* locPtr;
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- locPtr = world.get_loc(xLoc1, yLoc);
- for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
- {
- //--- if there is an enemy unit here ---//
- if( locPtr->has_unit(UNIT_LAND) )
- {
- unitPtr = unit_array[ locPtr->unit_recno(UNIT_LAND) ];
- if( !unitPtr->nation_recno )
- continue;
- //--- if the unit is idle and he is our enemy ---//
- if( unitPtr->cur_action == SPRITE_ATTACK &&
- nationPtr->get_relation_status(unitPtr->nation_recno) == NATION_HOSTILE )
- {
- err_when( unitPtr->nation_recno == nation_recno );
- enemyCombatLevel += (int) unitPtr->hit_points;
- if( enemyXLoc == -1 || m.random(5)==0 )
- {
- enemyXLoc = xLoc;
- enemyYLoc = yLoc;
- }
- }
- }
- }
- }
- if( enemyCombatLevel==0 )
- return 0;
- err_when( enemyXLoc < 0 );
- //--------- attack the target now -----------//
- if( worker_count > 0 )
- {
- patrol_all_soldier();
- if( patrol_unit_count > 0 )
- {
- // ###### patch begin Gilbert 5/8 ########//
- unit_array.attack(enemyXLoc, enemyYLoc, 0, patrol_unit_array, patrol_unit_count, COMMAND_AI,
- world.get_loc(enemyXLoc, enemyYLoc)->unit_recno(UNIT_LAND));
- // ###### patch end Gilbert 5/8 ########//
- return 1;
- }
- }
- return 0;
- }
- //-------- End of function FirmCamp::think_attack_nearby_enemy -------//
- //------- Begin of function FirmCamp::think_change_town_link -------//
- //
- // Think about changing links to foreign towns.
- //
- void FirmCamp::think_change_town_link()
- {
- Nation* ownNation = nation_array[nation_recno];
- for( int i=linked_town_count-1 ; i>=0 ; i-- )
- {
- Town* townPtr = town_array[ linked_town_array[i] ];
- //--- only change links to foreign towns, links to own towns are always on ---//
- if( townPtr->nation_recno == nation_recno )
- continue;
- //---- only enable links to non-friendly towns ----//
- int enableFlag = townPtr->nation_recno==0 ||
- ownNation->get_relation(townPtr->nation_recno)->status == NATION_HOSTILE;
- toggle_town_link( i+1, enableFlag, COMMAND_AI );
- }
- }
- //--------- End of function FirmCamp::think_change_town_link -------//
- //------- Begin of function FirmCamp::think_assign_better_commander -------//
- //
- // Assign a better commander to this camp.
- //
- int FirmCamp::think_assign_better_commander()
- {
- //----- if there is already an overseer being assigned to the camp ---//
- Nation* ownNation = nation_array[nation_recno];
- int actionRecno = ownNation->is_action_exist(loc_x1, loc_y1, -1, -1,
- ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP);
- //--- if there is already one existing ---//
- if( actionRecno )
- {
- //--- if the action still is already being processed, don't bother with it ---//
- if( ownNation->get_action(actionRecno)->processing_instance_count > 0 )
- return 0;
- //--- however, if the action hasn't been processed, we still try to use the approach here ---//
- }
- //-------------------------------------------------//
- Firm* firmPtr;
- Worker* workerPtr;
- int bestRaceId = best_commander_race();
- int bestFirmRecno=0, bestWorkerId;
- int bestLeadership=0;
- if( overseer_recno )
- {
- bestLeadership = cur_commander_leadership(bestRaceId)
- + 10 + ownNation->pref_loyalty_concern/10; // nations that have higher loyalty concern will not switch commander too frequently
- }
- //--- locate for a soldier who has a higher leadership ---//
- for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- )
- {
- firmPtr = firm_array[ ownNation->ai_camp_array[i] ];
- if( firmPtr->region_id != region_id )
- continue;
- workerPtr = firmPtr->worker_array;
- for( int j=1 ; j<=firmPtr->worker_count ; j++, workerPtr++ )
- {
- if( !workerPtr->race_id )
- continue;
- int workerLeadership = workerPtr->skill_level;
- if( workerPtr->race_id != bestRaceId )
- workerLeadership /= 2;
- if( workerLeadership > bestLeadership )
- {
- bestLeadership = workerLeadership;
- bestFirmRecno = firmPtr->firm_recno;
- bestWorkerId = j;
- }
- }
- }
- if( bestFirmRecno == 0 )
- return 0;
- //-------- assign the overseer now -------//
- int unitRecno = firm_array[bestFirmRecno]->mobilize_worker(bestWorkerId, COMMAND_AI);
- if( !unitRecno )
- return 0;
- Unit* unitPtr = unit_array[unitRecno];
- unitPtr->set_rank(RANK_GENERAL);
- //---- if there is already an existing but unprocessed one, delete it first ---//
- if( actionRecno )
- ownNation->del_action(actionRecno);
- return ownNation->add_action(loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP, 1, unitRecno);
- }
- //-------- End of function FirmCamp::think_assign_better_commander ---------//
- //------- Begin of function FirmCamp::cur_commander_leadership -------//
- //
- // [int] bestRaceId - if this is given, it will be used, otherwise
- // it will use best_commander_race().
- //
- // Return the commander leadership
- //
- int FirmCamp::cur_commander_leadership(int bestRaceId)
- {
- int commanderLeadership=0;
- //--- get the current leadership of the commander ----//
- if( overseer_recno )
- {
- if( !bestRaceId )
- bestRaceId = best_commander_race();
- Unit* unitCommander = unit_array[overseer_recno];
- if( unitCommander->race_id == bestRaceId )
- commanderLeadership = unitCommander->skill.skill_level;
- else
- commanderLeadership = unitCommander->skill.skill_level / 2; // divided by 2 if the race doesn't match
- }
- return commanderLeadership;
- }
- //-------- End of function FirmCamp::cur_commander_leadership ---------//
- //------- Begin of function FirmCamp::new_commander_leadership -------//
- //
- // <int> newRaceId - the race id. of the would-be commander.
- // <int> newSkillLevel - the skill level of the would-be commander.
- //
- // Return the commander leadership if the unit is assigned to this camp.
- //
- int FirmCamp::new_commander_leadership(int newRaceId, int newSkillLevel)
- {
- int commanderLeadership=0;
- int bestRaceId = best_commander_race();
- //--- get the current leadership of the commander ----//
- if( overseer_recno )
- {
- if( newRaceId == bestRaceId )
- commanderLeadership = newSkillLevel;
- else
- commanderLeadership = newSkillLevel / 2; // divided by 2 if the race doesn't match
- }
- return commanderLeadership;
- }
- //-------- End of function FirmCamp::new_commander_leadership ---------//
- //------- Begin of function FirmCamp::best_commander_race -------//
- //
- // Return what race the commander should be for this camp.
- //
- int FirmCamp::best_commander_race()
- {
- //---------------------------------------------//
- //
- // If this camp is the commanding camp of a town,
- // then return the majority race of the town.
- //
- // A camp is the commanding camp of a town when
- // it is the closest camp to the town.
- //
- //---------------------------------------------//
- for( int i=linked_town_count-1 ; i>=0 ; i-- )
- {
- Town* townPtr = town_array[ linked_town_array[i] ];
- if( townPtr->closest_own_camp() == firm_recno )
- return townPtr->majority_race();
- }
- //----- check if this camp is trying to capture an independent town ---//
- int targetTownRecno = think_capture_target_town();
- if( targetTownRecno && town_array[targetTownRecno]->nation_recno==0 )
- return town_array[targetTownRecno]->majority_race();
- //----- Otherwise return the majority race of this camp -----//
- return majority_race();
- }
- //-------- End of function FirmCamp::best_commander_race ---------//
|