Пример #1
0
//--------- 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;
}
Пример #2
0
//--------- 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;
}