Beispiel #1
0
//--------- Begin of function sort_soldier_id_function ---------//
//
static int sort_soldier_id_function( const void *va, const void *vb )
{
	Soldier *a = &cur_firm_ptr->soldier_array[*((short*)va) - 1];
	Soldier *b = &cur_firm_ptr->soldier_array[*((short*)vb) - 1];

	int rc = a->is_under_training() - b->is_under_training();

	if( rc == 0 )
		return int( b->skill_level() - a->skill_level() );
	else
		return rc;
}
Beispiel #2
0
//--------- Begin of function sort_soldier_function ---------//
//
static int sort_soldier_function( const void *va, const void *vb )
{
	Soldier *a = (Soldier *)va;
	Soldier *b = (Soldier *)vb;

	int rc = a->is_under_training() - b->is_under_training();

	if( rc == 0 )
		return int( b->skill_level() - a->skill_level() );
	else
		return rc;
}
Beispiel #3
0
//---------- Begin of function FirmCamp::pay_expense --------//
//
// pay_expense() is called by Firm::next_day()
//
void FirmCamp::pay_expense()
{
	if( !nation_recno )
		return;

	Firm::pay_expense();

	//-------- pay expenses to human units and weapons --------//

	Soldier* soldierPtr = soldier_array;
	Nation* nationPtr = nation_array[nation_recno];

	for( int i=1 ; i<=soldier_count ; i++, soldierPtr++ )
	{
		if( soldierPtr->is_under_training() )
			continue;

		// #### begin Gilbert 24/3 #####//
		// int unitClass = unit_res[soldierPtr->unit_id]->unit_class;

		//------ if the unit is a weapon -------//

		// if( unitClass == UNIT_CLASS_WEAPON )
		// one has life reduce hp when no food
		// one has no life, reduce hp when no money
		if( !unit_res[soldierPtr->unit_id]->class_info.life )
		// #### end Gilbert 24/3 #####//
		{
			if( nationPtr->cash > 0 )
			{
				nationPtr->add_expense( EXPENSE_WEAPON,
					(float) unit_res[soldierPtr->unit_id]->year_cost / 365, 1 );
			}
			else
			{
				//-- if it's a weapon, decrease hit points if the nation cannot pay the unit --//

				if( soldierPtr->hit_points > 0 )
					soldierPtr->hit_points--;

				if( soldierPtr->hit_points == 0 )
					kill_soldier(i);		// if its hit points is zero, delete it

				err_when( soldierPtr->hit_points < 0 );
			}
		}
	}
}
Beispiel #4
0
//------- Begin of function FirmCamp::basic_train -------//
//
// Training a villager into a soldier.
//
void FirmCamp::basic_train()
{
	if( game.game_mode == GAME_TUTORIAL && 
		nation_recno != nation_array.player_recno)
		return;
	
	for( int i = 1; i <= soldier_count; ++i )
	{
		Soldier *soldierPtr = soldier_array + i - 1;

		// ###### begin Gilbert 19/11 #######//
		if( soldierPtr->is_under_training() )
		{
			int basicCombatLevel = BASIC_COMBAT_TRAIN;
			// ###### patch begin Gilbert 16/2 ######//
			// if( nation_recno && soldierPtr->race_id == RACE_ROMAN 
			//	&& god_res[GOD_ROMAN]->nation_prayer_count(nation_recno) > 0 )
			if( nation_recno && god_res[GOD_ROMAN]->nation_prayer_count(nation_recno) > 0 )
			{
				basicCombatLevel += BASIC_COMBAT_TRAIN / 2;		// roman can train to combat level 30
			}
			// ###### patch end Gilbert 16/2 ######//

			int totalBuildDays = unit_res[soldierPtr->unit_id]->build_days;
			soldierPtr->skill.inc_combat_level( ((float) basicCombatLevel + 0.125f)/ totalBuildDays );
			soldierPtr->skill.inc_skill_level( ((float) BASIC_SKILL_TRAIN + 0.125f) / totalBuildDays );
			// add a little more to avoid truncation error

			soldierPtr->hit_points = soldierPtr->max_hit_points();

			if( soldierPtr->hit_points > soldierPtr->max_hit_points() )
				soldierPtr->hit_points = soldierPtr->max_hit_points();

			--soldierPtr->remain_build_days;
			err_when( soldierPtr->remain_build_days < 0 );

		// ###### end Gilbert 19/11 #######//

			break;		// only train one unit at a time.
		}
	}
}
Beispiel #5
0
//------- Begin of function FirmCamp::advanced_train -------//
//
// Increase the leadership and ocmbat level of the general and the soldiers.
//
void FirmCamp::advanced_train()
{
	if( game.game_mode == GAME_TUTORIAL && 
		nation_recno != nation_array.player_recno)
		return;
	
	if( !overseer_recno )
		return;

	Unit* overseerUnit = unit_array[overseer_recno];

	int overseerSkill = (int) overseerUnit->skill_level();
								// + overseerUnit->item.ability( ITEM_ABILITY_SKILL_LEVEL );
								// skill_level() already contain enhancement
	int incValue;

	//------- increase the commander's leadership ---------//

	if( soldier_count > 0
		 && (int) overseerUnit->skill_level() < MAX_SKILL_TRAIN ) // do not use overseerSkill
	{
		//-- the more soldiers this commander has, the higher the leadership will increase ---//

		incValue = 5 * soldier_count
					  * (int) overseerUnit->hit_points / overseerUnit->max_hit_points()
					  * (100+overseerUnit->skill.skill_potential*2) / 100;

		// AI_CHEAT

		if( is_ai && config.ai_aggressiveness > OPTION_MODERATE )
			incValue += incValue * (config.ai_aggressiveness-OPTION_MODERATE) / 3;		// 33% faster if aggressivness is high, 66% faster if aggressiveness is very high

		overseerUnit->skill.inc_skill_level( (float)incValue/100 );
	}

	//------- increase the commander's combat level ---------//

	if( overseerUnit->combat_level() < MAX_COMBAT_TRAIN )
	{
		incValue = 10 * (int) overseerUnit->hit_points / overseerUnit->max_hit_points()
					  * (100+overseerUnit->skill.skill_potential*2) / 100;

		// ------ effect of god ----------//

		// ##### patch begin Gilbert 16/2 ######//
//		if( overseerUnit->race_id == RACE_CELTIC && nation_recno 
//			&& god_res[GOD_CELTIC]->nation_prayer_count(nation_recno) > 0 )
		if( nation_recno && god_res[GOD_CELTIC]->nation_prayer_count(nation_recno) > 0 )
		{
			if( overseerUnit->race_id == RACE_CELTIC )
				incValue += incValue / 2;		// 50% skill increase in fort
			else
				incValue += incValue / 5;		// 20% skill increase in fort
		}
		// ##### patch end Gilbert 16/2 ######//

		if( is_ai && config.ai_aggressiveness > OPTION_MODERATE )
			incValue += incValue * (config.ai_aggressiveness-OPTION_MODERATE) / 5;		// 20% faster if aggressivness is high, 40% faster if aggressiveness is very high

		overseerUnit->skill.inc_combat_level( (float)incValue/100 );
	}

	//------- increase the solider's combat level -------//

	for( int i=0 ; i<soldier_count ; i++ )
	{
		Soldier* soldierPtr = soldier_array + i;

		#ifdef DEBUG

		err_when( !soldierPtr->name_id );

		err_when( soldierPtr->is_monster() &&
					 monster_res.name_used_array[soldierPtr->name_id-1] < 1 );

		#endif

		if( soldierPtr->is_under_training() )		// skip unit under initial training
			continue;

		//------- increase soldier skill -----------//

		if( soldierPtr->combat_level() < overseerSkill
			&& soldierPtr->combat_level() < MAX_COMBAT_TRAIN )
		{
			incValue = max(20, overseerSkill - (int)soldierPtr->combat_level())
						  * soldierPtr->hit_points / soldierPtr->max_hit_points()
						  * (100+soldierPtr->skill.skill_potential*2+overseerUnit->item.ability(ITEM_ABILITY_TRAIN)) / 100;

			// ------ effect of god ----------//

			// ###### patch begin Gilbert 16/2 ######//
			//if( soldierPtr->race_id == RACE_CELTIC && nation_recno 
			//	&& god_res[GOD_CELTIC]->nation_prayer_count(nation_recno) > 0 )
			if( nation_recno 
				&& god_res[GOD_CELTIC]->nation_prayer_count(nation_recno) > 0 )
			{
				if( soldierPtr->race_id == RACE_CELTIC )
					incValue += incValue / 2;		// 50% skill increase in fort
				else
					incValue += incValue / 5;		// 20% skill increase in fort
			}
			// ###### patch end Gilbert 16/2 ######//

			// ###### patch begin Gilbert 23/12 #########//
			// penalty of egyptain
			if( soldierPtr->race_id == RACE_EGYPTIAN && nation_recno
				&& god_res[GOD_EGYPTIAN]->nation_prayer_count(nation_recno) > 0 )
			{
				incValue = incValue * (MAX_WORKER*2) / (MAX_WORKER*2+god_res[GOD_EGYPTIAN]->nation_prayer_count(nation_recno));
			}
			// ###### patch end Gilbert 23/12 #########//

			if( is_ai && config.ai_aggressiveness > OPTION_MODERATE )
				incValue += incValue * (config.ai_aggressiveness-OPTION_MODERATE) / 5;		// 20% faster if aggressivness is high, 40% faster if aggressiveness is very high

			soldierPtr->skill.inc_combat_level( (float)incValue/100 );
		}

		//-- if the soldier has leadership potential, he learns leadership --//

		if( soldierPtr->skill.skill_potential > 0
			 && soldierPtr->skill_level() < MAX_SKILL_TRAIN )
		{
			incValue = (int) max(50, overseerSkill-soldierPtr->skill_level())
						  * soldierPtr->hit_points / soldierPtr->max_hit_points()
						  * soldierPtr->skill.skill_potential*2 / 100;

			if( is_ai && config.ai_aggressiveness > OPTION_MODERATE )
				incValue += incValue * (config.ai_aggressiveness-OPTION_MODERATE) / 5;		// 20% faster if aggressivness is high, 40% faster if aggressiveness is very high

			soldierPtr->skill.inc_skill_level( (float)incValue/100 );
		}
	}
}
Beispiel #6
0
int Unit::think_assign_soldier_to_camp()
{
	//---- think about assign the unit to a camp/fort that needs soldiers ----//

	Nation* ownNation = nation_array[nation_recno];
	FirmCamp *firmCamp, *bestFirm=NULL;
	int  regionId = world.get_region_id( next_x_loc(), next_y_loc() );
	int  skillLevel = skill_level();
	int  curRating, bestRating=0;
	int  curXLoc = next_x_loc(), curYLoc = next_y_loc();

	for( int i=0 ; i<ownNation->ai_camp_count ; i++ )
	{
		firmCamp = firm_array[ownNation->ai_camp_array[i]]->cast_to_FirmCamp();

		if( firmCamp->nation_recno != nation_recno )
			continue;

		if( firmCamp->region_id != regionId || firmCamp->under_construction )
			continue;

		if( !firmCamp->can_accept_assign(sprite_recno) )
			continue;

		curRating = 0;

		//----- if the camp is already full of soldier ------//

		if( firmCamp->is_soldier_full() )
		{
			//---- get the lowest skill soldier of the firm -----//

			Soldier* soldierPtr = firmCamp->soldier_array;
			int	   minSkill=100;

			for( int j=0 ; j<firmCamp->soldier_count ; j++, soldierPtr++ )
			{
				if( soldierPtr->is_under_training() )
					continue;

				if( soldierPtr->skill_level() < minSkill )
					minSkill = soldierPtr->skill_level();
			}

			//------------------------------//

			if( firmCamp->majority_race() == race_id )
			{
				if( skill_level() < minSkill+10 )
					continue;
			}
			else //-- for different race, only assign if the skill is significantly higher than the existing ones --//
			{
				if( skill_level() < minSkill+30 )
					continue;
			}
		}
		else
		{
			curRating += 300;		// if the firm is not full, rating + 300
		}

		//-------- calculate the rating ---------//

		curRating += world.distance_rating( curXLoc, curYLoc, firmCamp->center_x, firmCamp->center_y );

		if( firmCamp->majority_race() == race_id )
			curRating += 70;

		curRating += (MAX_SOLDIER - firmCamp->soldier_count) * 10;

		//-------------------------------------//

		if( curRating > bestRating )
		{
			bestRating = curRating;
			bestFirm   = firmCamp;
		}
	}

	if( bestFirm )
	{
		assign(bestFirm->loc_x1, bestFirm->loc_y1);
		return 1;
	}
	else
		return 0;
}
Beispiel #7
0
//--------- Begin of function FirmCamp::disp_camp_info ---------//
//
void FirmCamp::disp_camp_info(int dispY1, int refreshFlag)
{
	if( is_own() )
	{
		int x1 = INFO_X1 +13;
		int y1 = INFO_Y1 +235;
		int x2 = INFO_X1 +13;
		int y2 = INFO_Y1 +281;
		if( refreshFlag==INFO_REPAINT )
		{
			// ##### begin Gilbert 31/12 #######//
			// button_patrol.create( INFO_X1+13, INFO_Y1+235, 'A', "PATROL" );
			// button_reward.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+235, 'A', "REWARDCB" );
			// button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+235, 'A', defense_flag ? "DEFENSE1" : "DEFENSE0" );

			if (!is_monster())
				button_patrol.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, 'A', "PATROL" );
			else
				button_patrol.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, 'A', "F_PATROL" );

			if (!is_monster())
				button_reward.create( INFO_X1+13, INFO_Y1+235, 'A', "REWARD" );				
			else
				button_reward.create( INFO_X1+13, INFO_Y1+235, 'A', "F_REWARD" );				
							
			if (!is_monster())
				button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+281, 'A', defense_flag ? "DEFENSE1" : "DEFENSE0" );
			else
				button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+281, 'A', defense_flag ? "F_DEFEN1" : "F_DEFEN0" );
				
			if (!is_monster())
				button_promote.create( INFO_X1+13+2*BUTTON_DISTANCE , INFO_Y1+235, 'A', "PROMOTE" );
			else
				button_promote.create( INFO_X1+13+2*BUTTON_DISTANCE , INFO_Y1+235, 'A', "F_PROMOT" );
			// ##### end Gilbert 31/12 #######//
		}
		if( overseer_recno )
		{
			button_patrol.enable_flag = 1;
		}
		else
		{
			for( int i = 0; i < soldier_count && soldier_array[i].is_under_training(); ++i );
			button_patrol.enable_flag = i < soldier_count;
		}
		
		String str;
		switch(patrol_state)
		{
			case PATROL_ALL:
			//	str = "Sortie All";
				str = "";
				break;
			case PATROL_NO_GENERAL:
				str = "Sortie No Leader";
				break;
			case PATROL_NO_INJURED_SOILDER:
				str = "Sortie No Injured";
				break;
			default:
				break;
		}

		button_patrol.paint();
	//	vga.active_buf->bar_alpha( button_patrol.x1, button_patrol.y1+15, button_patrol.x1+BUTTON_ACTION_WIDTH-1, button_patrol.y1+BUTTON_ACTION_HEIGHT-16, 1, 0 );
		font_whbl.center_put_paragraph( button_patrol.x1, button_patrol.y1, button_patrol.x1+BUTTON_ACTION_WIDTH-1, button_patrol.y1+BUTTON_ACTION_HEIGHT-1, str );

		// ###### begin Gilbert 15/4 ########//
		if( nation_array[nation_recno]->cash >= REWARD_COST &&
			 ( (overseer_recno && unit_array[overseer_recno]->rank_id != RANK_KING && unit_res[unit_array[overseer_recno]->unit_id]->class_info.has_loyalty)
			  || (selected_soldier_id && selected_soldier_id <= soldier_count && unit_res[soldier_array[selected_soldier_id-1].unit_id]->class_info.has_loyalty)) )
			button_reward.enable_flag = 1;			// call paint
		// ###### end Gilbert 15/4 ########//
		else
			button_reward.enable_flag = 0;		// call paint
		button_reward.paint();

		if (!is_monster())
			button_defense.update_bitmap( defense_flag ? "DEFENSE1" : "DEFENSE0" );		// call paint
		else
			button_defense.update_bitmap( defense_flag ? "F_DEFEN1" : "F_DEFEN0" );

		if( (button_promote.visible_flag = !overseer_recno) )
		{
			button_promote.enable_flag = 0;
			if( selected_soldier_id > 0 && selected_soldier_id <= soldier_count )
			{
				Soldier *soldierPtr = soldier_array + selected_soldier_id - 1;
				// ##### begin Gilbert 24/3 ######//
				err_when( soldierPtr->unit_id == UNIT_WAGON );

				if( soldierPtr->race_id != 0
					&& soldierPtr->rank_id == RANK_SOLDIER 
					&& !soldierPtr->is_under_training()
					&& soldierPtr->skill_level() > 0 )
				// ##### end Gilbert 24/3 ######//
				{
					button_promote.enable_flag = 1;
				}
			}

			button_promote.paint();
		}
	}
	disp_spy_button( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, refreshFlag);
}
Beispiel #8
0
//--------- Begin of function Nation::recruit_in_firm_soldier --------//
//
// Get soldiers currently in camps or forts for assigning them to another
// camp or fort.
//
// <Firm*> destFirmPtr  - the firm which the workers are recruited for.
//
// [int] preferedRaceId - the prefered race id.
//								  (if not given, the majority race of the destination
//								   firm will be used.)
//
// return: <int> recno of the unit recruited.
//
int Nation::recruit_in_firm_soldier(Firm* destFirmPtr, int preferedRaceId)
{
	err_when( destFirmPtr->cast_to_FirmCamp() == NULL );	// it must either be a Camp or a Fort 

	if( !preferedRaceId )
	{
		preferedRaceId = destFirmPtr->majority_race();

		if( !preferedRaceId )
			return 0;
	}

	//--- scan existing firms to see if any of them have excess workers ---//

	FirmCamp*	firmCamp, *bestFirmCamp=NULL;
	int			bestRating=0, curRating;
	int			bestFirmSoldierId=0;

	int i;
	for( i=0 ; i<ai_camp_count ; i++ )
	{
		firmCamp = firm_array[ai_camp_array[i]]->cast_to_FirmCamp();

		err_when( !firmCamp );

		if( firmCamp->firm_recno == destFirmPtr->firm_recno )
			continue;

		if( firmCamp->region_id != destFirmPtr->region_id )
			continue;

		int excessCombatLevel = firmCamp->total_combat_level() - firmCamp->ai_combat_level_needed();

		curRating = excessCombatLevel/3 +
						world.distance_rating( firmCamp->center_x, firmCamp->center_y,
						destFirmPtr->center_x, destFirmPtr->center_y );

		for( int j=0 ; j<firmCamp->soldier_count ; j++ )
		{
			if( firmCamp->soldier_array[j].is_under_training() )
				continue;

			if( firmCamp->soldier_array[j].race_id == preferedRaceId )
				curRating += 50;
		}

		if( curRating > bestRating )
		{
			bestRating = curRating;
			bestFirmCamp = firmCamp;
		}
	}

	if( !bestFirmCamp )
		return 0;

	//------ mobilize a worker form the selected firm ----//

	int bestSoldierId=0;
		 bestRating = 0;

	Soldier* soldierPtr = bestFirmCamp->soldier_array;

	for( i=0 ; i<bestFirmCamp->soldier_count ; i++, soldierPtr++ )
	{
		if( soldierPtr->is_under_training() )
			continue;

		if( soldierPtr->race_id == preferedRaceId ) 	// same race
			curRating = 50;
		else if( soldierPtr->race_id == 0 )		// weapon
			curRating = 20;
		else             				// different race
			curRating = 10;

		if( curRating > bestRating )
		{
			bestRating 	  = curRating;
			bestSoldierId = i+1;
		}
	}

	if( !bestSoldierId )
		return NULL;

	return bestFirmCamp->mobilize_soldier( bestSoldierId, COMMAND_AI );
}