Example #1
0
//------- Begin of function Town::setup_link ---------//
//
void Town::setup_link()
{
	//-----------------------------------------------------------------------------//
	// check the connected firms location and structure if ai_link_checked is true
	//-----------------------------------------------------------------------------//

	if(ai_town)
		ai_link_checked = 0;

	//----- build town-to-firm link relationship -------//

	int   firmRecno;
	Firm* firmPtr;
	FirmInfo* firmInfo;

	linked_firm_count = 0;

	for( firmRecno=firm_array.size() ; firmRecno>0 ; firmRecno-- )
	{
		if( firm_array.is_deleted(firmRecno) )
			continue;

		firmPtr  = firm_array[firmRecno];
		firmInfo = firm_res[firmPtr->firm_id];

		if( !firmInfo->is_linkable_to_town )
			continue;

		//----- only linkable if the firm and the town belong to the same nation or the firm can influence a foreign town, i.e. Camp, Fort and Fryhtan Lair,

		if( nation_recno==0 )
		{
			//--- independent towns can linked to work firms and markets ---//

			if( !firmPtr->cast_to_FirmWork() && !firmPtr->cast_to_FirmMarket()
				 && !firmPtr->cast_to_FirmCamp() )
			{
				continue;
			}
		}
		else
		{
			//--- nation towns can only linked to own firms or camps -------//

			if( firmPtr->nation_recno != nation_recno && !firmPtr->cast_to_FirmCamp() )
				continue;
		}

		//---------- check if the firm is close enough to this firm -------//

		if( m.points_distance( firmPtr->center_x, firmPtr->center_y, center_x, center_y )
			 > world.effective_distance(firmPtr->firm_id, 0) )
		{
			continue;
		}

		//------ check if both are on the same terrain type ------//

		if( (world.get_loc(firmPtr->loc_x1, firmPtr->loc_y1)->is_plateau()==1)
			 != (world.get_loc(loc_x1, loc_y1)->is_plateau()==1) )
		{
			continue;
		}

		//----- if the firm requires same race -------//

		if( !firm_res.is_linkable_to_town(firmPtr->firm_id, firmPtr->race_id, race_id) )
			continue;

		//------- determine default link flag -------//

		int defaultLinkStatus = LINK_EE;

		if( nation_recno==0 )		// if this is an independent town
		{
			if( firmPtr->nation_recno==0 || resistance(firmPtr->nation_recno) > INDEPENDENT_LINK_RESISTANCE )
				defaultLinkStatus = LINK_DD;
		}

		//-------- add the link now -------//

		if( linked_firm_count < MAX_LINKED_FIRM_TOWN )
		{
			err_when( linked_firm_count>0 && linked_firm_array[linked_firm_count-1] == firmRecno );		// BUGHERE - check double linking error

			linked_firm_array[linked_firm_count] = firmRecno;
			linked_firm_enable_array[linked_firm_count] = defaultLinkStatus;

			linked_firm_count++;
		}
		else
		{
			err_here();
		}

		if( firmPtr->linked_town_count < MAX_LINKED_TOWN_TOWN )
		{
			firmPtr->linked_town_array[firmPtr->linked_town_count] = town_recno;
			firmPtr->linked_town_enable_array[firmPtr->linked_town_count] = defaultLinkStatus;

			firmPtr->linked_town_count++;

			if(firmPtr->is_ai)
				firmPtr->ai_link_checked = 0;
		}
		else
		{
			err_here();
		}
	}

	//----- build town-to-town link relationship -------//

	linked_town_count = 0;

	int   townRecno;
	Town* townPtr;

	for( townRecno=town_array.size() ; townRecno>0 ; townRecno-- )
	{
		if( town_array.is_deleted(townRecno) || townRecno==town_recno )
			continue;

		townPtr = town_array[townRecno];

		//----- if the firm requires same race -------//

		if( race_id != townPtr->race_id )
			continue;

		//------ check if the town is close enough to this firm -------//

		if( m.points_distance( townPtr->center_x, townPtr->center_y,
			 center_x, center_y ) > world.effective_distance(0, 0) )
		{
			continue;
		}

		//------ check if both are on the same terrain type ------//

		if( (world.get_loc(townPtr->loc_x1, townPtr->loc_y1)->is_plateau()==1)
			 != (world.get_loc(loc_x1, loc_y1)->is_plateau()==1) )
		{
			continue;
		}

		//-------- link this town -------//

		if( linked_town_count < MAX_LINKED_TOWN_TOWN )
		{
			linked_town_array[linked_town_count] = townRecno;
			linked_town_enable_array[linked_town_count] = LINK_EE;

			linked_town_count++;
		}
		else
		{
			err_here();
		}

		//-------- link the other town  -------//

		if( townPtr->linked_town_count < MAX_LINKED_TOWN_TOWN )
		{
			townPtr->linked_town_array[townPtr->linked_town_count] = town_recno;
			townPtr->linked_town_enable_array[townPtr->linked_town_count] = LINK_EE;

			townPtr->linked_town_count++;

			if(townPtr->ai_town)
				townPtr->ai_link_checked = 0;
		}
		else
		{
			err_here();
		}
	}
}
Example #2
0
File: ospya.cpp Project: mecirt/7k2
//-------- Begin of function SpyArray::catch_spy ------//
//
// <int> spyPlace - either SPY_TOWN or SPY_FIRM
// <int> spyPlacePara - town_recno or firm_recno
//
int SpyArray::catch_spy(int spyPlace, int spyPlacePara)
{
	int nationRecno, totalPop;

	if( spyPlace == SPY_TOWN )
	{
		Town* townPtr = town_array[spyPlacePara];

		nationRecno = townPtr->nation_recno;
		totalPop    = townPtr->population;
	}
	else if( spyPlace == SPY_FIRM )
	{
		Firm* firmPtr = firm_array[spyPlacePara];

		nationRecno = firmPtr->nation_recno;
		if( firmPtr->cast_to_FirmCamp() )
		{
			FirmCamp *firmCamp = firmPtr->cast_to_FirmCamp();
			totalPop    = firmCamp->soldier_count + (firmCamp->overseer_recno>0);
		}
		else if( firmPtr->cast_to_FirmWork() )
		{
			FirmWork *firmWork = firmPtr->cast_to_FirmWork();
			totalPop    = firmWork->worker_count;
		}
		else if( firmPtr->cast_to_FirmTrain() )
		{
			totalPop = firmPtr->cast_to_FirmTrain()->trainee_count;
			return 0;		// don't catch spy
		}
		else if( firmPtr->cast_to_FirmInn() )
		{
			totalPop = firmPtr->cast_to_FirmInn()->inn_unit_count;
			return 0;		// don't catch spy
		}
		else if( firmPtr->cast_to_FirmMarket() )
		{
			totalPop = 0;
			return 0;
		}
		else if( firmPtr->cast_to_FirmMonsterTrain() )
		{
			totalPop = firmPtr->cast_to_FirmMonsterTrain()->trainee_count;
			return 0;		// don't catch spy
		}
		else if( firmPtr->cast_to_FirmMonsterAlchemy() )
		{
			totalPop = 0;
			return 0;
		}
		else if( firmPtr->cast_to_FirmLishorr() )
		{
			totalPop = 0;
			return 0;
		}
		else if( firmPtr->cast_to_FirmMonsterFortress() )
		{
			FirmMonsterFortress *firmMonsterFortress = firmPtr->cast_to_FirmMonsterFortress();
			totalPop = firmMonsterFortress->archer_count + firmMonsterFortress->extra_builder_count;
		}
		else if( firmPtr->cast_to_FirmAnimal() )
		{
			totalPop = 0;
			return 0;
		}
		else if( firmPtr->cast_to_FirmIncubator() )
		{
			totalPop = 0;
			return 0;
		}
		else if( firmPtr->cast_to_FirmMagic() )
		{
			totalPop = 0;
			return 0;
		}
		else if( firmPtr->cast_to_FirmOffensive() )
		{
			totalPop = 0;
			return 0;
		}
		else if( firmPtr->cast_to_FirmOffensive2() )
		{
			totalPop = 0;
			return 0;
		}
		else
		{
			err_here();
			totalPop = 0;
		}
	}
	else
		err_here();

	//--- calculate the total of anti-spy skill in this town ----//

	int enemySpyCount=0, counterSpySkill=0;
	Spy* spyPtr;

	int techLevel = 0;
	if( nationRecno )
		techLevel = tech_res[TECH_COUNTER_SPY]->get_nation_tech_level(nationRecno);

	int i;
	for( i=size() ; i>0 ; i-- )
	{
		if( is_deleted(i) )
			continue;

		spyPtr = spy_array[i];

		if( spyPtr->spy_place == spyPlace &&
			 spyPtr->spy_place_para == spyPlacePara )
		{
			if( spyPtr->true_nation_recno == nationRecno )
				counterSpySkill += spyPtr->spy_skill + spyPtr->spy_skill * techLevel / 2;
			else
				enemySpyCount++;
		}
	}

	//----- if all citizens are enemy spies ----//

	if( enemySpyCount == totalPop )
		return 0;

	err_when( enemySpyCount > totalPop );

	//-------- try to catch enemy spies now ------//

	for( i=spy_array.size() ; i>0 ; i-- )
	{
		if( spy_array.is_deleted(i) )
			continue;

		spyPtr = spy_array[i];

		if( spyPtr->action_mode == SPY_IDLE )		// it is very hard to get caught in sleep mode
			continue;

		if( spyPtr->spy_place == spyPlace &&
			 spyPtr->spy_place_para == spyPlacePara &&
			 spyPtr->true_nation_recno != nationRecno )	// doesn't get caught in sleep mode
		{
			int escapeChance = 100 + spyPtr->spy_skill - counterSpySkill;

			escapeChance = max( spyPtr->spy_skill/10, escapeChance );

			if( m.random(escapeChance) == 0 )
			{
				spyPtr->get_killed(); 		// only catch one spy per calling
				return 1;
			}
		}
	}

	return 0;
}