Example #1
0
//------- Begin of function FirmHarbor::think_build_firm -----------//
//
void FirmHarbor::think_build_firm()
{
	Nation* ownNation = nation_array[nation_recno];

	if( ownNation->cash < 2000 )		// don't build if the cash is too low
		return;

	if( ownNation->true_profit_365days() < (50-ownNation->pref_use_marine)*20 )		//	-1000 to +1000
		return;

	//----- think about building markets ------//

	if( ownNation->pref_trading_tendency >= 60 )
	{
		if( ai_build_firm(FIRM_MARKET) )
			return;
	}

	//----- think about building camps ------//

	if( ownNation->pref_military_development/2 +
		 (linked_firm_count + ownNation->ai_ship_count + ship_count) * 10 +
		 ownNation->total_jobless_population*2 > 150 )
	{
		ai_build_firm(FIRM_CAMP);
	}
}
Example #2
0
//------- Begin of function FirmMarket::think_build_export_market -----------//
//
// Think about export goods of this market to other markets.
//
int FirmMarket::think_build_export_market(int townRecno)
{
	Town* 		townPtr = town_array[townRecno];
	Firm* 		firmPtr;
	Nation* 		nationPtr = nation_array[nation_recno];

	//---- see if we already have a market linked to this town ----//

	for( int i=0 ; i<townPtr->linked_firm_count ; i++ )
	{
		firmPtr = firm_array[ townPtr->linked_firm_array[i] ];

		if( firmPtr->firm_id != FIRM_MARKET || firmPtr->firm_recno==firm_recno )
			continue;

		//--- if we already have a market there, no need to build a new market ----//

		if( firmPtr->nation_recno == nation_recno )
			return 0;
	}

	//--- if there is no market place linked to this town, we can set up one ourselves ---//

	short buildXLoc, buildYLoc;

	if( !nationPtr->find_best_firm_loc(FIRM_MARKET, townPtr->loc_x1, townPtr->loc_y1, buildXLoc, buildYLoc) )
	{
		townPtr->no_neighbor_space = 1;
		return 0;
	}

	nationPtr->add_action(buildXLoc, buildYLoc, townPtr->loc_x1, townPtr->loc_y1, ACTION_AI_BUILD_FIRM, FIRM_MARKET);
	return 1;
}
Example #3
0
//-------- Begin of function Info::set_rank_data --------//
//
// <int> onlyHasContact - if this is 1, then only nations
//								  that have contact with the viewing
//								  nation is counted. Otherwise all nations
//								  are counted.
//
void Info::set_rank_data(int onlyHasContact)
{
	Nation* viewingNation = NULL; 
	Nation* nationPtr;
	int 	  rankPos=0;

	if( nation_array.player_recno && !nation_array.is_deleted(info.viewing_nation_recno) )
		viewingNation = nation_array[info.viewing_nation_recno];

	memset( nation_rank_data_array, 0, sizeof(nation_rank_data_array) );

	for( int i=1 ; i<=nation_array.size() ; i++ )
	{
		if( nation_array.is_deleted(i) )
			continue;

		if( onlyHasContact )
		{
			if( viewingNation && !viewingNation->get_relation(i)->has_contact )
				continue;
		}

		nationPtr = nation_array[i];

		nation_rank_data_array[0][i-1] = nationPtr->population_rating;

		nation_rank_data_array[1][i-1] = nationPtr->military_rating;

		nation_rank_data_array[2][i-1] = nationPtr->economic_rating;

		nation_rank_data_array[3][i-1] = (int) nationPtr->reputation;

		nation_rank_data_array[4][i-1] = (int) nationPtr->kill_monster_score;
	}
}
Example #4
0
//-------- Begin of static function nation_filter --------//
//
// This function has dual purpose :
//
// 1. when <int> recNo is not given :
//    - return the total no. of nations of this nation
//
// 2. when <int> recNo is given :
//    - return the nation recno in nation_array of the given recno.
//
int Info::nation_filter(int recNo)
{
	int    	i, nationCount=0;
//	Nation*  viewingNation = nation_array[info.viewing_nation_recno];

	Nation*  viewingNation = NULL;
	
	if( nation_array.player_recno )
		viewingNation = nation_array[info.viewing_nation_recno];

	for( i=1 ; i<=nation_array.size() ; i++ )
	{
		if( nation_array.is_deleted(i) )
			continue;

		if( i==info.viewing_nation_recno ||
			 !viewingNation ||
			 viewingNation->get_relation(i)->has_contact )
		{
			nationCount++;
		}

		if( recNo && nationCount==recNo )
			return i;
	}

	err_when( recNo );   // the recNo is not found, it is out of range

	return nationCount;
}
Example #5
0
//--------- Begin of function Unit::ai_build_camp --------//
//
// Order this unit to build a camp in its region.
//
int Unit::ai_build_camp()
{
	//--- to prevent building more than one camp at the same time ---//

	int     curRegionId = region_id();
	Nation* ownNation = nation_array[nation_recno];

	if( ownNation->is_action_exist( ACTION_AI_BUILD_FIRM, FIRM_CAMP, curRegionId ) )
		return 0;

	//------- locate a place for the camp --------//

	FirmInfo* firmInfo = firm_res[FIRM_CAMP];
	int 		 xLoc=0, yLoc=0;
	char 	 	 teraMask = UnitRes::mobile_type_to_mask(UNIT_LAND);

	if( world.locate_space_random(xLoc, yLoc, MAX_WORLD_X_LOC-1,
		 MAX_WORLD_Y_LOC-1, firmInfo->loc_width+2, firmInfo->loc_height+2,   // leave at least one location space around the building
		 MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC, curRegionId, 1, teraMask) )
	{
		return ownNation->add_action( xLoc, yLoc, -1, -1,
					ACTION_AI_BUILD_FIRM, FIRM_CAMP, 1, sprite_recno );
	}

	return 0;
}
Example #6
0
//------- Begin of function Town::think_build_firm --------//
//
// Think about building a specific type of firm next to this town.
//
// <int> firmId  - id. of the firm to be built.
// <int> maxFirm - max. no. of firm of this type to be built next to this town.
//
int Town::think_build_firm(int firmId, int maxFirm)
{
	Nation* nationPtr = nation_array[nation_recno];

	//--- check whether the AI can build a new firm next this firm ---//

	if( !nationPtr->can_ai_build(firmId) )
		return 0;

	//-- only build one market place next to this town, check if there is any existing one --//

	Firm* firmPtr;
	int 	firmCount=0;

	for(int i=0; i<linked_firm_count; i++)
	{
		err_when(!linked_firm_array[i] || firm_array.is_deleted(linked_firm_array[i]));

		firmPtr = firm_array[linked_firm_array[i]];

		//---- if there is one firm of this type near the town already ----//

		if( firmPtr->firm_id == firmId &&
			 firmPtr->nation_recno == nation_recno )
		{
			if( ++firmCount >= maxFirm )
				return 0;
		}
	}

	//------ queue building a new firm -------//

	return ai_build_neighbor_firm(firmId);
}
Example #7
0
//------- Begin of function Town::think_reward --------//
//
// Think about granting the villagers.
//
void Town::think_reward()
{
	if( !has_linked_own_camp )
		return;

	if( accumulated_reward_penalty > 0 )
		return;

	//---- if accumulated_reward_penalty>0, don't grant unless the villagers are near the rebel level ----//

	Nation* ownNation = nation_array[nation_recno];
	int averageLoyalty = average_loyalty();

	if( averageLoyalty < REBEL_LOYALTY + 5 + ownNation->pref_loyalty_concern/10 )		// 35 to 45
	{
		int importanceRating;

		if( averageLoyalty < REBEL_LOYALTY+5 )
			importanceRating = 40+population;
		else
			importanceRating = population;

		if( ownNation->ai_should_spend(importanceRating) )
			reward( COMMAND_AI );
	}
}
Example #8
0
//-------- Begin of function Town::think_spying_town_assign_to --------//
//
// Think about planting spies into independent towns and enemy towns.
//
int Town::think_spying_town_assign_to(int raceId)
{
	Nation* ownNation = nation_array[nation_recno];

	int targetTownRecno = ownNation->think_assign_spy_target_town(race_id, region_id);

	if( !targetTownRecno )
		return 0;

	//------- assign the spy now -------//

	int unitRecno = recruit(SKILL_SPYING, raceId, COMMAND_AI);

	if( !unitRecno )
		return 0;

	Town* targetTown = town_array[targetTownRecno];

	int actionRecno = ownNation->add_action( targetTown->loc_x1, targetTown->loc_y1,
							-1, -1, ACTION_AI_ASSIGN_SPY, targetTown->nation_recno, 1, unitRecno );

	if( !actionRecno )
		return 0;

	train_unit_action_id = ownNation->get_action(actionRecno)->action_id;

	return 1;
}
Example #9
0
//------- Begin of function FirmCamp::pay_weapon_expense -------//
//
void FirmCamp::pay_weapon_expense()
{
	Worker* workerPtr = worker_array;
	Nation* nationPtr = nation_array[nation_recno];

	for( int i=1 ; i<=worker_count ; i++, workerPtr++ )
	{
		if( workerPtr->unit_id &&
			 unit_res[workerPtr->unit_id]->unit_class == UNIT_CLASS_WEAPON )
		{
			if( nationPtr->cash > 0 )
			{
				nationPtr->add_expense( EXPENSE_WEAPON, (float) unit_res[workerPtr->unit_id]->year_cost / 365, 1 );
			}
			else     // decrease hit points if the nation cannot pay the unit
			{
				if( workerPtr->hit_points > 0 )
					workerPtr->hit_points--;

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

				err_when( workerPtr->hit_points < 0 );
			}
		}
	}
}
Example #10
0
//--------- Begin of function Firm::ai_update_link_status ---------//
//
// Updating link status of this firm with towns. 
//
void Firm::ai_update_link_status()
{
	err_when( firm_id == FIRM_CAMP );		// FirmCamp has its own ai_update_link_status(), this version shouldn't be called.

	if( !worker_array )		// if this firm does not need any workers. 
		return;

	if( is_worker_full() )	// if this firm already has all the workers it needs. 
		return;

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

	Nation* ownNation = nation_array[nation_recno];
	int	  i, rc;

	for( i=0 ; i<linked_town_count ; i++ )
	{
		Town* townPtr = town_array[linked_town_array[i]];

		//--- enable link to hire people from the town ---//

		rc = townPtr->nation_recno==0 ||		// either it's an independent town or it's friendly or allied to our nation
			  ownNation->get_relation_status(townPtr->nation_recno) >= NATION_FRIENDLY;

		toggle_town_link( i+1, rc, COMMAND_AI );
	}
}
Example #11
0
//----- Begin of function FirmWar::should_build_new_weapon ------//
//
int FirmWar::should_build_new_weapon()
{
	//----- first see if we have enough money to build & support the weapon ----//

	Nation* nationPtr = nation_array[nation_recno];

	if( nationPtr->true_profit_365days() < 0 )		// don't build new weapons if we are currently losing money
		return 0;

	if( nationPtr->expense_365days(EXPENSE_WEAPON) >
		 nationPtr->income_365days() * 30 + nationPtr->pref_use_weapon/2 )		// if weapon expenses are larger than 30% to 80% of the total income, don't build new weapons
	{
		return 0;
	}

	//----- see if there is any space on existing camps -----//

	Firm* firmPtr;

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

		if( firmPtr->region_id != region_id )
			continue;

		if( firmPtr->worker_count < MAX_WORKER )		// there is space in this firm
			return 1;
	}

	return 0;
}
Example #12
0
File: of_war.cpp Project: 7k2/7k2
//--------- Begin of function FirmWar::process_queue ---------//
//
void FirmWar::process_queue()
{
    if( build_queue_count==0 )
        return;

    // ######## begin Gilbert 30/12 #######//
    // --- cancel if technology lost -----//

    // do not cancel build in progress because tech may be recovered
    // cancel when it is going to build

    if( nation_recno )
    {
        // ---- delete queue until the first unit in the queue can build ----//

        while( build_queue_count > 0
                && unit_res[build_queue_array[0]]->get_nation_tech_level(nation_recno) == 0 )
        {
            misc.del_array_rec( build_queue_array, build_queue_count, sizeof(build_queue_array[0]), 1 );
            build_queue_count--;
        }
    }

    if( build_queue_count==0)
        return;
    // ######## end Gilbert 30/12 #######//



    //--- first check if the nation has enough money to build the weapon ---//

    Nation* nationPtr = nation_array[nation_recno];
    build_unit_id = build_queue_array[0];

    if( nationPtr->cash < unit_res[build_unit_id]->build_cost )
    {
        build_unit_id = 0;
        return;
    }

    nationPtr->add_expense( EXPENSE_WEAPON, unit_res[build_unit_id]->build_cost, 1);

    err_when( build_queue_count > MAX_BUILD_QUEUE );

    misc.del_array_rec( build_queue_array, build_queue_count, sizeof(build_queue_array[0]), 1 );

    build_queue_count--;

    //------- set building parameters -------//

    last_process_build_frame_no = sys.frame_count;
    build_progress_days = (float) 0;

    if( firm_array.selected_recno == firm_recno )
    {
        // disable_refresh = 1;
        // info.disp();
        // disable_refresh = 0;
    }
}
Example #13
0
//----- Begin of function Nation::consider_alliance_rating -----//
//
// Return a rating from 0 to 100 for whether this nation should ally
// with the given nation.
//
int Nation::consider_alliance_rating(int nationRecno)
{
	Nation* nationPtr = nation_array[nationRecno];

	//---- the current relation affect the alliance tendency ---//

	NationRelation* nationRelation = get_relation(nationRecno);

	int allianceRating = nationRelation->ai_relation_level-20;

	//--- if the nation has a bad record of starting wars with us before, decrease the rating ---//

	allianceRating -= nationRelation->started_war_on_us_count * 20;

	//------ add the trade rating -------//

	int tradeRating = trade_rating(nationRecno) +				// existing trade amount
							ai_trade_with_rating(nationRecno)/2;	// possible trade

	allianceRating += tradeRating;

	//---- if the nation's power is larger than us, it's a plus ----//

	int powerRating = nationPtr->military_rank_rating() - military_rank_rating();		// if the nation's power is larger than ours, it's good to form treaty with them

	if( powerRating > 0 )
		allianceRating += powerRating;

	return allianceRating;
}
Example #14
0
//-------- Begin of static function put_expense_rec --------//
//
static void put_expense_rec(int recNo, int x, int y, int refreshFlag)
{
	//----- define expense descriptions -------//

	static const char* expense_des_array[EXPENSE_TYPE_COUNT] =
	{
		"General Costs",
		"Spy Costs",
		"Other Mobile Human Unit Costs",
		"Caravan Costs",
		"Weapons Costs",
		"Ship Costs",
		"Buildings Costs",
		"Training Units",
		"Hiring Units",
		"Honoring Units",
		"Foreign Worker Salaries",
		"Grants to Your Villagers",
		"Grants to Other Villagers",
		"Imports",
		"Aid/Tribute to Other Kingdoms",
		"Bribes",
	};

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

	x+=3;
	y+=3;

	Nation* nationPtr = nation_array[info.viewing_nation_recno];

	font_san.put( x    , y, expense_des_array[recNo-1] );
	font_san.put( x+370, y, misc.format( (int) nationPtr->expense_365days(recNo-1), 2 ) );
}
Example #15
0
//------- Begin of function FirmBase::think_adjust_workforce -------//
//
// Think about adjusting the workforce by increasing or decreasing
// needed_worker_count.
//
int FirmBase::think_adjust_workforce()
{
	Nation* nationPtr = nation_array[nation_recno];

	//---- if we have enough food -----//

	if( nationPtr->ai_has_enough_food() )
	{
		if( needed_worker_count < MAX_WORKER )
		{
			set_needed_worker_count( needed_worker_count+1, COMMAND_AI );
			return 1;
		}
	}

	//---- if we are running out of food -----//

	else
	{
		if( needed_worker_count > MAX_WORKER/2 )
		{
			set_needed_worker_count( needed_worker_count-1, COMMAND_AI );
			return 1;
		}
	}

	return 0;
}
Example #16
0
File: ofirm.cpp Project: 112212/7k2
//---------- Begin of function Firm::process_repair --------//
//
void Firm::process_repair()
{
	if( repair_flag && hit_points < max_hit_points()
		&& info.game_date > last_attack_date+1	)			// can only do construction when the firm is not under attack //
		
	{
		if( nation_recno )
		{
			Nation* nationPtr = nation_array[nation_recno];

			float repairCost = (float) firm_res[firm_id]->setup_cost
									 * REPAIR_POINTS_PER_DAY / max_hit_points();

			float repairLiveCost = (float) firm_res[firm_id]->setup_live_points_cost
										  * REPAIR_POINTS_PER_DAY / max_hit_points();

			if( nationPtr->cash < repairCost || nationPtr->live_points < repairLiveCost )
				return;

			nationPtr->add_expense( EXPENSE_CONSTRUCTION, repairCost, 1 );
			nationPtr->change_live_points( -repairLiveCost );
		}

		hit_points += REPAIR_POINTS_PER_DAY;

		if( hit_points >= max_hit_points() )
		{
			hit_points = (float) max_hit_points();
			set_repair_flag( 0, COMMAND_AUTO );
		}
	}
}
Example #17
0
//-------- Begin of static function put_income_rec --------//
//
static void put_income_rec(int recNo, int x, int y, int refreshFlag)
{
	//----- define income descriptions ------//

	static const char* income_des_array[INCOME_TYPE_COUNT] =
	{
		"Sale of Goods",
		"Exports",
		"Taxes",
		"Recovered Treasure",
		"Worker Income",
		"Sale of Buildings",
		"Aid/Tribute from Other Kingdoms",
		"Cheating",
	};

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

	x+=3;
	y+=3;

	Nation* nationPtr = nation_array[info.viewing_nation_recno];

	font_san.put( x    , y, income_des_array[recNo-1] );
	font_san.put( x+370, y, misc.format( (int) nationPtr->income_365days(recNo-1), 2 ) );
}
Example #18
0
File: ofirm.cpp Project: 112212/7k2
//---------- Begin of function Firm::pay_expense --------//
//
void Firm::pay_expense()
{
	if( !nation_recno )
		return;

	Nation* nationPtr = nation_array[nation_recno];

	//-------- fixed expenses ---------//

	float dayExpense = (float) year_expense() / 365;

	if( nationPtr->cash >= dayExpense )
	{
		nationPtr->add_expense( EXPENSE_FIRM, dayExpense, 1 );
	}
	else
	{
		if( hit_points > 0 )
			hit_points--;

		if( hit_points < 0 )
			hit_points = (float) 0;

		//--- when the hit points drop to zero and the firm is destroyed ---//

		if( hit_points==0 && nation_recno == nation_array.player_recno )
			news_array.firm_worn_out(firm_recno);
	}
}
Example #19
0
File: ofirm.cpp Project: 112212/7k2
void Firm::sell_firm(char remoteAction)
{
	if( !remoteAction && remote.is_enable() )
	{
		// packet structure : <firm recno>
		short *shortPtr = (short *)remote.new_send_queue_msg(MSG_FIRM_SELL, sizeof(short));
		*shortPtr = firm_recno;
		return;
	}
	//------- sell at 50% of the original cost -------//

	Nation* nationPtr = nation_array[nation_recno];

	float sellIncome = (float) firm_res[firm_id]->setup_cost / 2 * (int) hit_points / (int) max_hit_points();
	float sellLiveIncome = (float) firm_res[firm_id]->setup_live_points_cost / 2 * (int) hit_points / (int) max_hit_points();

	nationPtr->add_income(INCOME_SELL_FIRM, sellIncome);

	if( nationPtr->is_monster() )
		nationPtr->change_live_points( sellLiveIncome );

	se_res.sound(center_x, center_y, 1, 'F', firm_id, "SELL" );

   firm_array.del_firm(firm_recno);
}
Example #20
0
//----- Begin of function FirmMarket::update_trade_link -----//
//
// Update the status of links to harbors and towns based
// on the current trade treaty status. 
//
void FirmMarket::update_trade_link()
{
	Nation* ownNation = nation_array[nation_recno];
	int tradeTreaty;

	//------ update links to towns -----//

	Town* townPtr;

	for( int i=0 ; i<linked_town_count ; i++ )
	{
		 townPtr = town_array[linked_town_array[i]];

		 if( !townPtr->nation_recno )
			 continue;

		 if( townPtr->nation_recno )
		 {
			 tradeTreaty = ownNation->get_relation(townPtr->nation_recno)->trade_treaty
								|| townPtr->nation_recno==nation_recno;
		 }
		 else		// if this is an independent town, it buys goods from the market if its resistance towards the nation is < 30
		 {
			 tradeTreaty = townPtr->resistance(nation_recno) <= INDEPENDENT_LINK_RESISTANCE;
		 }

		 if( linked_town_enable_array[i] != (tradeTreaty ? LINK_EE : LINK_DD) )
			 toggle_town_link( i+1, tradeTreaty, COMMAND_AUTO, 1 );					// 1-toggle both side
	}
}
Example #21
0
//------- Begin of function TalkRes::reply_talk_msg --------//
//
// If the nation which receives this message decides to accept
// the offer of this message, this function is called.
//
// <int>  talkMsgRecno - the recno of the TalkMsg
// <char> replyType	  - reply type, either REPLY_ACCEPT or REPLY_REJECT
// <char> remoteAction - remote action type
//
void TalkRes::reply_talk_msg(int talkMsgRecno, char replyType, char remoteAction)
{
	//-------- send multiplayer -----------//

	if( !remoteAction && remote.is_enable() )
	{
		// packet structure : <talkRecno:int> <reply type:char> <padding:char>
		char* charPtr = remote.new_send_queue_msg( MSG_REPLY_TALK_MSG, sizeof(int)+2*sizeof(char) );
		*(int *)charPtr = talkMsgRecno;
		charPtr[sizeof(int)] = replyType;
		charPtr[sizeof(int)+sizeof(char)] = 0;
		return;
	}

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

	err_when( is_talk_msg_deleted(talkMsgRecno) );

	TalkMsg* talkMsgPtr = get_talk_msg(talkMsgRecno);
	Nation*  fromNation = nation_array[talkMsgPtr->from_nation_recno];

	err_when( talkMsgPtr->reply_type == REPLY_NOT_NEEDED );
	err_when( replyType != REPLY_ACCEPT && replyType != REPLY_REJECT );

	talkMsgPtr->reply_type = replyType;
	talkMsgPtr->reply_date = info.game_date;

	switch( fromNation->nation_type )
	{
		case NATION_OWN:
			news_array.diplomacy( talkMsgRecno );
			// ###### begin Gilbert 9/10 ########//
			// sound effect
			se_ctrl.immediate_sound("GONG");
			// ###### end Gilbert 9/10 ########//
			break;

		case NATION_AI:
			fromNation->ai_notify_reply( talkMsgRecno );		// notify the AI nation about this reply.
			break;

		case NATION_REMOTE:
			break;
	}

	//---- set the replying nation's never accept date so that the replying nation will not make an offer soon after it rejects the offer

	nation_array[talkMsgPtr->to_nation_recno]->get_relation(talkMsgPtr->from_nation_recno)
		->set_never_accept_until_date(talkMsgPtr->talk_id, 30);

	//------- if the offer is accepted -------//

	if( talkMsgPtr->reply_type == REPLY_ACCEPT )
		talkMsgPtr->process_accepted_reply();

	//--- if the player has replyed the message, remove it from the news display ---//

	if( talkMsgPtr->to_nation_recno == nation_array.player_recno )
		news_array.remove(NEWS_DIPLOMACY, talkMsgRecno);
}
Example #22
0
//------- Begin of function GameFile::write_game_header -------//
//
// Write saved game header info to the saved game file.
//
// Return : <int> 1 - file written successfully
//                0 - not successful
//
int GameFile::write_game_header(File* filePtr)
{
	class_size = sizeof(GameFile);

	Nation* playerNation = ~nation_array;

	strncpy( player_name, playerNation->king_name(), NationArray::HUMAN_NAME_LEN );
	player_name[NationArray::HUMAN_NAME_LEN] = '\0';

	race_id 		 = playerNation->race_id;
	nation_color = playerNation->nation_color;
	terrain_set  = config.terrain_set;

	game_date = info.game_date;

#ifndef NO_WINDOWS  // FIXME
	//----- set the file date ------//

	SYSTEMTIME sysTime;
	GetSystemTime(&sysTime);
	SystemTimeToFileTime(&sysTime, &file_date);
#endif

	//------- write GameFile to the saved game file -------//

   return filePtr->file_write( this, sizeof(GameFile) );     // write the whole object to the saved game file
}
Example #23
0
int Unit::think_normal_monster_action()
{
	if( home_camp_firm_recno )
		return 0;

	//--- if the entire nation does not have any lairs ----//

	Nation* nationPtr = nation_array[nation_recno];

	if( nationPtr->is_monster() &&
		 ( nationPtr->ai_camp_count==0 ||

		//---- If there are more units than the existing lairs can hold ---//

			nationPtr->total_camp_unit_space(0) <= nationPtr->total_unit_count ) )
	{
		return ai_build_firm();
	}

	//---- try to assign units to existing lairs -----//

	if( leader_unit_recno &&
		 unit_array[leader_unit_recno]->is_visible() )		// if the unit is led by a commander, let the commander makes the decision. If the leader has been assigned to a firm, don't consider it as a leader anymore
	{
		return 0;
	}

	return think_assign_soldier_to_camp();
}
Example #24
0
//------- Begin of function Firm::ai_recruit_worker -----------//
//
int Firm::ai_recruit_worker()
{
	if( worker_count == MAX_WORKER )
		return 0;

	Nation* nationPtr = nation_array[nation_recno];
	Town*   townPtr;

	for( int i=0; i<linked_town_count ; i++ )
	{
		if( linked_town_enable_array[i] != LINK_EE )
			continue;

		townPtr = town_array[ linked_town_array[i] ];

		//-- only recruit workers from towns of other nations if we don't have labor ourselves

		if( townPtr->nation_recno != nation_recno &&
			 nationPtr->total_jobless_population > MAX_WORKER )
		{
			continue;
		}

		if( townPtr->jobless_population > 0 )
			return 0;		// don't order units to move into it as they will be recruited from the town automatically
	}

	//---- order workers to move into the firm ----//

	nationPtr->add_action(loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_WORKER, firm_id, MAX_WORKER-worker_count);

	return 1;
}
Example #25
0
//----- Begin of function Nation::consider_give_tribute -----//
//
// talkMsg->talk_para1 - amount of the tribute.
//
int Nation::consider_give_tribute(TalkMsg* talkMsg)
{
	//-------- don't give tribute too frequently -------//

	NationRelation* nationRelation = get_relation(talkMsg->from_nation_recno);

	if( info.game_date < nationRelation->never_accept_until_date_array[TALK_GIVE_TRIBUTE-1] )
		return 0;

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

	int relationStatus = get_relation_status(talkMsg->from_nation_recno);
	Nation* fromNation = nation_array[talkMsg->from_nation_recno];

	if( true_profit_365days() < 0 )		// don't give tribute if we are losing money
		return 0;

	int reserveYears = 1 + 3 * pref_cash_reserve / 100;			// 1 to 4 years

	if( cash-talkMsg->talk_para1 < fixed_expense_365days() * reserveYears )
		return 0;

	int militaryDiff = fromNation->military_rank_rating() - military_rank_rating();

	if( militaryDiff > 10+pref_military_courage/2 )
	{
		nationRelation->set_never_accept_until_date(TALK_GIVE_TRIBUTE, 180);
		return 1;
	}

	return 0;
}
Example #26
0
//-------- Begin of static function put_income_rec --------//
//
static void put_income_rec(int recNo, int x, int y)
{
	//----- define income descriptions ------//

//	static char* income_des_array[INCOME_TYPE_COUNT] =		// see TextResReports::str_income_desc
//	{
//		"Sale of Goods",
//		"Exports",
//		"Taxes",
//		"Recovered Treasure",
//		"Sale of Buildings",
//		"Aid/Tribute from Other Kingdoms",
//		"Conversion",
//		"Cheating",
//	};

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

	x+=3;
	y+=2;

	Nation* nationPtr = nation_array[info.viewing_nation_recno];

//	char* str;
//	if( nationPtr->is_monster() && recNo==6 )
//		str = "Aid/Tribute from Other Kingdoms/Slave Towns";
//	else
//		str = income_des_array[recNo-1];

	font_bld.put( x    , y, text_reports.str_income_desc(recNo-1, nationPtr->is_monster()) );
	font_bld.put( x+370, y, m.format( (int) nationPtr->income_365days(recNo-1), 2 ) );
}
Example #27
0
//----- Begin of function Nation::ai_surrender_to_rating -----//
//
// return a rating on how much the nation will tend to surrender
// to the specific nation.
//
int Nation::ai_surrender_to_rating(int nationRecno)
{
	Nation* 			 nationPtr = nation_array[nationRecno];
	NationRelation* nationRelation = get_relation(nationRecno);

	//--- higher tendency to surrender to a powerful nation ---//

	int curRating = nationPtr->overall_rank_rating() - overall_rank_rating();

	curRating += (nationRelation->ai_relation_level-40);

	curRating += (int) nationRelation->good_relation_duration_rating*3;

	curRating += (int) nationPtr->reputation/2;

	//------ shouldn't surrender to an enemy --------//

	if( nationRelation->status == NATION_HOSTILE )
		curRating -= 100;

	//--- if the race of the kings are the same, the chance is higher ---//

	if( race_res.is_same_race( nationPtr->race_id, race_id ) )
		curRating += 20;

	return curRating;
}
Example #28
0
//--------- Begin of static function disp_debug_info ---------//
//
static void disp_debug_info()
{
	vga_util.d3_panel_down( REPORT_DET_X1, REPORT_DET_Y1, REPORT_DET_X2, REPORT_DET_Y2 );

	//----------- display info ------------//

	int	  nationRecno  = info.nation_filter(browse_nation.recno());
	Nation* nationPtr    = nation_array[nationRecno];

	int x1=REPORT_DET_X1+6, x2=REPORT_DET_X1+160;
	int y=REPORT_DET_Y1+6;

	int refreshFlag = INFO_REPAINT;

	//------------ display AI info ----------//

	font_bld.put_field( x1, y    , "Food    ", x2, nationPtr->food_str() );
	font_bld.put_field( x1, y+=16, "Treasure", x2, nationPtr->cash_str() );
	font_bld.put_field( x1, y+=16, "Life points", x2, (int) nationPtr->live_points, 1 );
	font_bld.put_field( x1, y+=16, "ai_capture_enemy_town_recno", x2, nationPtr->ai_capture_enemy_town_recno, 1 );
	font_bld.put_field( x1, y+=16, "Surplus supply rating", x2, nationPtr->surplus_supply_rating() );
	y+=48;

	//--------- display AI preference ----------//

	x2 += 60;

	font_bld.put_field( x1, y+=16, "Unit Chase Distance"     , x2, nationPtr->pref_unit_chase_distance     , 1 );
	font_bld.put_field( x1, y+=16, "Military Development"	   , x2, nationPtr->pref_military_development	 , 1 );
	font_bld.put_field( x1, y+=16, "Economic Development"	   , x2, nationPtr->pref_economic_development	 , 1 );
	font_bld.put_field( x1, y+=16, "Increase Pop by Capture" , x2, nationPtr->pref_inc_pop_by_capture      , 1 );
	font_bld.put_field( x1, y+=16, "Increase Pop by Growth"  , x2, nationPtr->pref_inc_pop_by_growth   	 , 1 );
	font_bld.put_field( x1, y+=16, "Peacefulness" 		      , x2, nationPtr->pref_peacefulness        	 , 1 );
	font_bld.put_field( x1, y+=16, "Military Courage"    	   , x2, nationPtr->pref_military_courage    	 , 1 );
	font_bld.put_field( x1, y+=16, "Territorial Cohesiveness", x2, nationPtr->pref_territorial_cohesiveness, 1 );
	font_bld.put_field( x1, y+=16, "Trading Tendency"        , x2, nationPtr->pref_trading_tendency        , 1 );

	x1 += (REPORT_DET_X2-REPORT_DET_X1)/2;
	x2 += (REPORT_DET_X2-REPORT_DET_X1)/2;

	y=REPORT_DET_Y1+6;

	font_bld.put_field( x1, y    , "Allying Tendency"        , x2, nationPtr->pref_allying_tendency        , 1 );
	font_bld.put_field( x1, y+=16, "Honesty"                 , x2, nationPtr->pref_honesty                 , 1 );
	font_bld.put_field( x1, y+=16, "Town Defense"         	, x2, nationPtr->pref_town_defense			    , 1 );
	font_bld.put_field( x1, y+=16, "Citizen Loyalty Concern" , x2, nationPtr->pref_loyalty_concern  		 , 1 );
	font_bld.put_field( x1, y+=16, "Forgiveness"             , x2, nationPtr->pref_forgiveness      		 , 1 );
	font_bld.put_field( x1, y+=16, "Collect Tax Tendency"    , x2, nationPtr->pref_collect_tax      		 , 1 );
	font_bld.put_field( x1, y+=16, "Build Inn Tendency"      , x2, nationPtr->pref_hire_unit       		    , 1 );
	font_bld.put_field( x1, y+=16, "Use Weapon Tendency"     , x2, nationPtr->pref_use_weapon       		 , 1 );
	font_bld.put_field( x1, y+=16, "Keep Generals Tendency"  , x2, nationPtr->pref_keep_general            , 1 );
	font_bld.put_field( x1, y+=16, "Keep Skilled Units Tendency", x2, nationPtr->pref_keep_skilled_unit    , 1 );
	font_bld.put_field( x1, y+=16, "Attack Monster"          , x2, nationPtr->pref_attack_monster          , 1 );
	font_bld.put_field( x1, y+=16, "Use Spies"               , x2, nationPtr->pref_spy                     , 1 );
	font_bld.put_field( x1, y+=16, "Use Counter Spies"       , x2, nationPtr->pref_counter_spy             , 1 );
	font_bld.put_field( x1, y+=16, "Food Reserve"            , x2, nationPtr->pref_food_reserve            , 1 );
	font_bld.put_field( x1, y+=16, "Cash Reserve"            , x2, nationPtr->pref_cash_reserve            , 1 );
	font_bld.put_field( x1, y+=16, "Use Marine"              , x2, nationPtr->pref_use_marine              , 1 );
}
Example #29
0
//------------- Begin of function Unit::defense_follow_target --------------//
// decide whether to follow the target
//
// return 0 if aborting attack the current target and go back to military camp
// return 1 otherwise
//
int Unit::defense_follow_target()
{
	#define PROB_HOSTILE_RETURN	10
	#define PROB_FRIENDLY_RETURN	20
	#define PROB_NEUTRAL_RETURN	30
	
	if(unit_array.is_deleted(action_para))
		return 1;

	if(cur_action==SPRITE_ATTACK)
		return 1;

	Unit *targetPtr = unit_array[action_para];
	Location *locPtr = world.get_loc(action_x_loc, action_y_loc);
	if(!locPtr->has_unit(targetPtr->mobile_type))
		return 1; // the target may be dead or invisible
	
	int returnFactor, abortAction = 0;
	
	//-----------------------------------------------------------------//
	// calculate the chance to go back to military camp in following the
	// target
	//-----------------------------------------------------------------//
	if(locPtr->power_nation_recno==nation_recno)
		return 1; // target within our nation
	else if(!locPtr->power_nation_recno) // is neutral
		returnFactor = PROB_NEUTRAL_RETURN;
	else
	{
		Nation *locNationPtr = nation_array[locPtr->power_nation_recno];
		if(locNationPtr->get_relation_status(nation_recno)==NATION_HOSTILE)
			returnFactor = PROB_HOSTILE_RETURN;
		else
			returnFactor = PROB_FRIENDLY_RETURN;
	}

	if(!abortAction)
	{
		SpriteInfo *targetSpriteInfo = targetPtr->sprite_info;

		//-----------------------------------------------------------------//
		// if the target moves faster than this unit, it is more likely for
		// this unit to go back to military camp.
		//-----------------------------------------------------------------//
		//-**** should also consider the combat level and hit_points of both unit ****-//
		if(targetSpriteInfo->speed > sprite_info->speed)
			returnFactor -= 5;

		if(misc.random(returnFactor)==0) // return to camp if true
			abortAction++;
		else
			return 1;
	}

	err_when(!abortAction);
	err_when(action_mode==ACTION_ASSIGN_TO_FIRM); // if so, process_auto_defense_back_camp() cannot process successfully
	process_auto_defense_back_camp();	
	return 0; // cancel attack
}
Example #30
0
// ------- begin of function TalkRes::create_incident --------//
//
// create incident : send declare war message
//
void TalkRes::create_incident( int nation1, int nation2 )
{
	Nation *toNation = nation_array[nation1];

	//-- if we are currently allied or friendly with the nation, we need to terminate the friendly/alliance treaty first --//

	TalkMsg talkMsg;

	if( toNation->get_relation_status(nation2) == RELATION_ALLIANCE )
	{
		memset(&talkMsg, 0, sizeof(TalkMsg));
		talkMsg.to_nation_recno   = (char) nation1;
		talkMsg.from_nation_recno = (char) nation2;
		talkMsg.from_nation_invisible = 1;
		talkMsg.talk_id  			  = TALK_END_ALLIANCE_TREATY;
		send_talk_msg( &talkMsg, COMMAND_AUTO );

		memset(&talkMsg, 0, sizeof(TalkMsg));
		talkMsg.to_nation_recno   = (char) nation2;
		talkMsg.from_nation_recno = (char) nation1;
		talkMsg.from_nation_invisible = 1;
		talkMsg.talk_id  			  = TALK_END_ALLIANCE_TREATY;
		send_talk_msg( &talkMsg, COMMAND_AUTO, 1 );		// force sending the message and bypass can_send_msg()
	}

	else if( toNation->get_relation_status(nation2) == RELATION_FRIENDLY )
	{
		memset(&talkMsg, 0, sizeof(TalkMsg));
		talkMsg.to_nation_recno   = (char) nation1;
		talkMsg.from_nation_recno = (char) nation2;
		talkMsg.from_nation_invisible = 1;
		talkMsg.talk_id  			  = TALK_END_FRIENDLY_TREATY;
		send_talk_msg( &talkMsg, COMMAND_AUTO );

		memset(&talkMsg, 0, sizeof(TalkMsg));
		talkMsg.to_nation_recno   = (char) nation2;
		talkMsg.from_nation_recno = (char) nation1;
		talkMsg.from_nation_invisible = 1;
		talkMsg.talk_id  			  = TALK_END_FRIENDLY_TREATY;
		send_talk_msg( &talkMsg, COMMAND_AUTO, 1 );
	}

	//--- send a declare war message to the target kingdom ---//

	memset(&talkMsg, 0, sizeof(TalkMsg));
	talkMsg.to_nation_recno   = (char) nation1;
	talkMsg.from_nation_recno = (char) nation2;
	talkMsg.from_nation_invisible = 1;
	talkMsg.talk_id  			  = TALK_DECLARE_WAR;
	send_talk_msg( &talkMsg, COMMAND_AUTO );

	memset(&talkMsg, 0, sizeof(TalkMsg));
	talkMsg.to_nation_recno   = (char) nation2;
	talkMsg.from_nation_recno = (char) nation1;
	talkMsg.from_nation_invisible = 1;
	talkMsg.talk_id  			  = TALK_DECLARE_WAR;
	send_talk_msg( &talkMsg, COMMAND_AUTO, 1 );
}