Пример #1
0
//-------- Begin of function Nation::ai_sea_travel -------//
//
// action_x_loc, action_y_loc - location of the destination
//
// group_unit_array - array of units that will do the sea travel
// instance_count - no. of units in the array
//
// action_para  - the action of units after they have arrived the region,
//					   it is one of the following:
//
// SEA_ACTION_SETTLE		 	  - settle into a town
//	SEA_ACTION_BUILD_CAMP 	  - build and assign to a firm
//	SEA_ACTION_ASSIGN_TO_FIRM - assign to a firm
//	SEA_ACTION_MOVE			  - just move to the destination
//								 	    (this include moving to the location of a battle field.)
//
//---------------------------------------------//
//
// Procedures:
// * 1. Locate a ship, build one if cannot locate any.
// * 2. Assign the units to the ship.
//   3. Move the ship to the destination region.
//   4. Units disembark on the coast.
//   5. Units move to the destination.
//
// This function deal with the 1st and 2nd procedures,
// when they are finished, action ACTION_AI_SEA_TRAVEL2
// will be added.
//
//---------------------------------------------//
//
int Nation::ai_sea_travel(ActionNode* actionNode)
{
	err_when( actionNode->instance_count < 1 ||
				 actionNode->instance_count > ActionNode::MAX_ACTION_GROUP_UNIT );

	Unit* unitPtr = unit_array[actionNode->group_unit_array[0]];

	err_when( unitPtr->nation_recno != nation_recno );
	err_when( !unitPtr->is_visible() );

	//---- figure out the sea region id which the ship should appear ----//

	int unitRegionId = world.get_region_id(unitPtr->next_x_loc(), unitPtr->next_y_loc());
	int destRegionId = world.get_region_id(actionNode->action_x_loc, actionNode->action_y_loc);

	int seaRegionId = region_array.get_sea_path_region_id(unitRegionId, destRegionId);

	//------- 1. try to locate a ship --------//

	int shipUnitRecno = ai_find_transport_ship(seaRegionId, unitPtr->next_x_loc(), unitPtr->next_y_loc());

	if( !shipUnitRecno )
		return -1;					// must return -1 instead of 0 as the action must be executed immediately otherwise the units will be assigned with other action and the unit list may no longer be valid

	//---- if this ship is in the harbor, sail it out ----//

	UnitMarine* unitMarine = (UnitMarine*) unit_array[shipUnitRecno];

	if( unitMarine->unit_mode == UNIT_MODE_IN_HARBOR )
	{
		FirmHarbor*	firmHarbor = (FirmHarbor*) firm_array[unitMarine->unit_mode_para];

		firmHarbor->sail_ship(unitMarine->sprite_recno, COMMAND_AI);
	}

	if( !unitMarine->is_visible() )		// no space in the sea for placing the ship 
		return -1;

	//------ 2. Assign the units to the ship -------//

	unitMarine->ai_action_id = actionNode->action_id;

	err_when( unit_res[unitMarine->unit_id]->unit_class != UNIT_CLASS_SHIP );

	// ##### patch begin Gilbert 5/8 #######//
	unit_array.assign_to_ship(unitMarine->next_x_loc(), unitMarine->next_y_loc(), 0, actionNode->group_unit_array, actionNode->instance_count, COMMAND_AI, unitMarine->sprite_recno );
	// ##### patch end Gilbert 5/8 #######//

	for( int i=0 ; i<actionNode->instance_count ; i++ )
		unit_array[ actionNode->group_unit_array[i] ]->ai_action_id = actionNode->action_id;

	actionNode->instance_count++;		// +1 for the ship

	actionNode->processing_instance_count = actionNode->instance_count-1;		// -1 because when we return 1, it will be increased by 1 automatically
	actionNode->action_para2 = 0;		// reset it, it is set in Nation::action_finished()

	return 1;
}
Пример #2
0
//------ Begin of function Nation::ai_sea_attack_target ------//
//
// <int> targetXLoc, targetYLoc - the location of the target.
//
int Nation::ai_sea_attack_target(int targetXLoc, int targetYLoc)
{
	UnitMarine* unitMarine;
	int 		   targetRegionId = world.get_region_id(targetXLoc, targetYLoc);
	int			rc = 0;

	for( int i=0 ; i<ai_ship_count ; i++ )
	{
		unitMarine = (UnitMarine*) unit_array[ ai_ship_array[i] ];

		if( unitMarine->attack_count==0 )
			continue;

		if( !unitMarine->is_ai_all_stop() )
			continue;

		//----- if the ship is in the harbor now -----//

		if( unitMarine->unit_mode == UNIT_MODE_IN_HARBOR )
		{
			FirmHarbor*	firmHarbor = (FirmHarbor*) firm_array[unitMarine->unit_mode_para];

			if( firmHarbor->sea_region_id != targetRegionId )
				continue;

			firmHarbor->sail_ship(unitMarine->sprite_recno, COMMAND_AI);
		}

		if( !unitMarine->is_visible() )		// no space in the sea for placing the ship
			continue;

		if( unitMarine->region_id() != targetRegionId )
			continue;

		//------ order the ship to attack the target ------//

		unitMarine->attack_unit( targetXLoc, targetYLoc );
		rc = 1;
	}

	return rc;
}
Пример #3
0
//-------- Begin of function Nation::ai_find_transport_ship -------//
//
// Locate a ship for transporting units.
//
// <int> seaRegionId			 - region id. of the sea which the ship should appear in.
// <int> unitXLoc, unitYLoc - the location of the units to be picked up,
//									   try to select a harbor close to this location.
// [int] findBest           - whether need to find the best ship or just return
//									   one if there is one found. (default: 1)
//
// return: <int> the recno of the ship located.
//
int Nation::ai_find_transport_ship(int seaRegionId, int unitXLoc, int unitYLoc, int findBest)
{
	//------- locate a suitable ship --------//

	UnitMarine* unitMarine;
	int			curRating, bestRating=0, bestUnitRecno=0;

	for( int i=0 ; i<ai_ship_count ; i++ )
	{
		unitMarine = (UnitMarine*) unit_array[ ai_ship_array[i] ];

		err_when( unit_res[unitMarine->unit_id]->unit_class != UNIT_CLASS_SHIP );

		if( unitMarine->unit_count > 0 ||										// if there are already units in the ship
			 unit_res[unitMarine->unit_id]->carry_unit_capacity==0 )		// if the ship does not carry units
		{
			continue;
		}

		//------- if this ship is in the harbor ---------//

		if( unitMarine->unit_mode == UNIT_MODE_IN_HARBOR )
		{
			FirmHarbor* firmHarbor = (FirmHarbor*) firm_array[unitMarine->unit_mode_para];

			err_when( firmHarbor->firm_id != FIRM_HARBOR );

			if( firmHarbor->sea_region_id != seaRegionId )
				continue;
		}

		//--------- if this ship is on the sea ----------//

		else
		{
			if( !unitMarine->is_ai_all_stop() )
				continue;

			if( unitMarine->region_id() != seaRegionId )
				continue;

			err_when( !unitMarine->is_visible() );

			if( !unitMarine->is_visible() )
				continue;
		}

		//--------- check if the sea region is matched ---------//

		if( !findBest )		// return immediately when a suitable one is found
			return unitMarine->sprite_recno;

		curRating = world.distance_rating( unitXLoc, unitYLoc,
						unitMarine->next_x_loc(), unitMarine->next_y_loc() );

		curRating += (int)unitMarine->hit_points/10				// damage
						 + (int)unitMarine->max_hit_points/10;	// ship class

		if( curRating > bestRating )
		{
			bestRating 	  = curRating;
			bestUnitRecno = unitMarine->sprite_recno;
		}
	}

	return bestUnitRecno;
}