//--------- Begin of function Nation::ai_assign_spy --------// // // Try to locate an existing spy for use. // // <int> targetXLoc, targetYLoc - the target location // [int] spyRaceId - if specified, only spies of this race // will be located. (default:0) // [int] mobileOnly - get mobile spies only. (default:0) // int Nation::ai_assign_spy(int targetXLoc, int targetYLoc, int spyRaceId, int mobileOnly) { int unitRecno=0; //---- try to find an existing spy ----// Spy* spyPtr = ai_find_spy( targetXLoc, targetYLoc, spyRaceId, mobileOnly ); if( spyPtr ) unitRecno = spyPtr->mobilize_spy(); //--- if not successful, then try to hire one ---// if( !unitRecno ) unitRecno = hire_unit(SKILL_SPYING, spyRaceId, targetXLoc, targetYLoc); //--- if cannot hire one, try to train one ----// int trainTownRecno=0; if( !unitRecno ) unitRecno = train_unit(SKILL_SPYING, spyRaceId, targetXLoc, targetYLoc, trainTownRecno); if( !unitRecno ) return 0; //------ get the spy object of the unit ------// Unit* unitPtr = unit_array[unitRecno]; err_when( !unitPtr->spy_recno ); spyPtr = spy_array[unitPtr->spy_recno]; //------- get the nation of the assign destination -----// Location* locPtr = world.get_loc(targetXLoc, targetYLoc); int cloakedNationRecno; if( locPtr->is_firm() ) { Firm* firmPtr = firm_array[locPtr->firm_recno()]; err_when( firmPtr->nation_recno==0 ); // cannot assign to a monster firm cloakedNationRecno = firmPtr->nation_recno; } else if( locPtr->is_town() ) { Town* townPtr = town_array[locPtr->town_recno()]; cloakedNationRecno = townPtr->nation_recno; } else { return 0; // the original firm or town has been destroyed or sold } //------- Add the assign spy action --------// int actionRecno = add_action( targetXLoc, targetYLoc, -1, -1, ACTION_AI_ASSIGN_SPY, cloakedNationRecno, 1, unitRecno ); if( !actionRecno ) return 0; //------ if the unit is under training ------// if( trainTownRecno ) town_array[trainTownRecno]->train_unit_action_id = get_action(actionRecno)->action_id; return 1; }
//--------- Begin of function Nation::ai_find_unit --------// // // <int> isCivilian - whether the unit is a civilian unit // <int> raceId - the race the selected unit should have // (0 for any races) // <short> destX, destY - location the unit move to // <char&> resultFlag - describle how to find the skilled unit // 0 - for unable to train unit, // 1 - for existing skilled unit // 2 - for unit hired from inn // 3 - for training unit in town (training is required) // // [int] actionId - the action id. of the action which // the unit should do after it has finished training. // // return the unit pointer pointed to the skilled unit // Unit* Nation::ai_find_unit(int isCivilian, int raceId, short destX, short destY, char& resultFlag, int actionId) { //----- try to find an existing unit with the required skill -----// Unit *wantedUnit = NULL; Unit *unitPtr; Firm *firmPtr; short curDist, minDist=0x1000; int destRegionId = world.get_region_id(destX, destY); for(int i=unit_array.size(); i>0; i--) { if(unit_array.is_deleted(i)) continue; unitPtr = unit_array[i]; if( unitPtr->nation_recno!=nation_recno || !unitPtr->race_id ) continue; if( raceId ) { if( unitPtr->race_id != raceId ) continue; } else { if( !unitPtr->is_human() ) continue; } //---- if this unit is on a mission ----// if( unitPtr->home_camp_firm_recno ) continue; if( unitPtr->region_id() != destRegionId ) continue; if( unitPtr->is_civilian() != isCivilian ) continue; if( unitPtr->unit_mode ) // it can be a camp defender. continue; //----- if this is a mobile unit ------// if( unitPtr->is_visible() ) { if( !unitPtr->is_all_stop() ) continue; if( unitPtr->cur_action!=SPRITE_ATTACK && !unitPtr->cur_order.ai_action_id ) { curDist = m.points_distance(unitPtr->next_x_loc(), unitPtr->next_y_loc(), destX, destY); if(curDist < minDist) { wantedUnit = unitPtr; minDist = curDist; } } } //------- if this is an overseer ------// else if( unitPtr->unit_mode==UNIT_MODE_OVERSEE ) { firmPtr = firm_array[unitPtr->unit_mode_para]; if( firmPtr->region_id != destRegionId ) continue; if( firmPtr->cast_to_FirmCamp() ) { //--- if this military camp is going to be closed, use this overseer ---// if( firmPtr->should_close_flag ) { firmPtr->cast_to_FirmCamp()->mobilize_overseer(); wantedUnit = unitPtr; // pick this overseer break; } } } } //---------------------------------------------------// if(wantedUnit) { resultFlag = 1; err_when( wantedUnit->is_civilian() != isCivilian ); } else { //--- if no existing skilled unit found, try to hire one from inns ---// int unitRecno=0; if( !isCivilian ) // if the wanted unit is a military, we can try to hire it from the inn { unitRecno = hire_unit(raceId, isCivilian, false, destX, destY); // this function will try going with hiring units that are better than training your own ones. false-don't hire a spy, just hire a normal military unit if( unitRecno ) { resultFlag = 2; err_when( unit_array[unitRecno]->is_civilian() != isCivilian ); } } if( !unitRecno && isCivilian ) { int recruitTownRecno; unitRecno = recruit_peasant(raceId, destX, destY, recruitTownRecno); if( unitRecno ) { err_when( unit_array[unitRecno]->is_civilian() != isCivilian ); resultFlag = 3; } else resultFlag = 0; } if( unitRecno ) wantedUnit = unit_array[unitRecno]; } return wantedUnit; }