コード例 #1
0
ファイル: impasse.c プロジェクト: dtbinh/automatic-car
void		impasse(t_lidar *lidar)
{
  int		i;
  int		count;
  static int	stop = 0;

  i = 3;
  count = 0;
  while (i <= 34)
    {
      if (lidar->speed > 0.2)
	{
	  if (i >= 14 && i <= 18)
	    {
	      if (my_getnbr(lidar->nbrs[i]) < 1050)
		count++;
	    }
	  else
	    if (my_getnbr(lidar->nbrs[i]) < 1150)
	      count++;
	}
      i++;
    }
  stop_move(lidar, count, &stop);
}
コード例 #2
0
ファイル: oun_act.cpp プロジェクト: mecirt/7k2
//--------- Begin of function Unit::completed_order ---------//
//
// The current order is completed.
//
void Unit::completed_order()
{
	stop_move();		// a UnitB function

	//----- if the order is initiated by an AI --//

	if( cur_order.ai_action_id && nation_recno )
		nation_array[nation_recno]->action_finished(cur_order.ai_action_id, sprite_recno);

	cur_order.set(UNIT_STOP);
}
コード例 #3
0
ファイル: oun_act.cpp プロジェクト: mecirt/7k2
//--------- Begin of function Unit::pop_order ---------//
//
// Note: the stack only has space for one Order object.
//
void Unit::pop_order()
{
	stop_move();	// stop the current action first

	err_when( has_pushed_order() == 0 );		// cannot push when the only one stack space is used

	cur_order = pushed_order;

	pushed_order.set(-1);

	set_original_target(-1, -1);		// clear the original target
}
コード例 #4
0
ファイル: ounitb.cpp プロジェクト: mecirt/7k2
void UnitB::process_wait()
{
	err_when(cur_action != SPRITE_WAIT);

	//move if the next tile is ready
	int stepMagn = move_step_magn();
	if(can_move((cur_x+stepMagn*move_x_pixel_array[final_dir])/LOCATE_WIDTH, (cur_y+stepMagn*move_y_pixel_array[final_dir])/LOCATE_WIDTH))
	{
		wait_state = 0;
		cur_action = SPRITE_MOVE;
		return;
	}
	else //find a new path if the thing occupying the next tile no longer move
	{
/*		int occUnitNum;
		Unit* occStuff;
		occUnitNum = checking_who_occupy_my_next_tile((cur_x+stepMagn*move_x_pixel_array[final_dir])/LOCATE_WIDTH, (cur_y+stepMagn*move_y_pixel_array[final_dir])/LOCATE_WIDTH);

		//##### begin trevor 21/1 #####//

		enum{ SEARCH_NEW_PATH_PROBABILITY = 10 };

		if( (!occUnitNum || (occUnitNum && (occStuff=unit_array[occUnitNum])
			 && (occStuff->cur_action != SPRITE_MOVE
			 && occStuff->cur_action != SPRITE_WAIT)))
			 || (SEARCH_NEW_PATH_PROBABILITY > m.random(100) && sprite_speed() <= occStuff->sprite_speed() && !is_in_formation()) )
		{
			wait_state = 0;
			move_to(move_to_loc_x, move_to_loc_y);
		//	retry_state++;
			return;
		}

		//##### end trevor 21/1 #####//*/
	}
	//find a new path if wait too long	
	// ####### begin Gilbert 28/4 ########//
	if(wait_state++ > (retry_state <= MAX_UNIT_WAIT_STATE ? retry_state+MAX_UNIT_WAIT_STATE_FIRST : MAX_UNIT_WAIT_STATE) )
	{
		wait_state = 0;

		int backupRetryState = retry_state;
		move_to(move_to_loc_x, move_to_loc_y);
		retry_state = backupRetryState + 1;		// restore and increase
	}
	// ####### end Gilbert 28/4 ########//
	//if retrying too many times, stop move
	if(retry_state > MAX_RETRY_STATE) 
	{
		stop_move();
		retry_state = 0;
	}
}
コード例 #5
0
ファイル: ounitb.cpp プロジェクト: mecirt/7k2
//---------- Begin of function UnitB::process_blocked -----//
// 
// retry move to destination if the unit is blocked
//
void UnitB::process_blocked()
{
	if(number_of_times_being_blocked++ > MAX_UNIT_BLOCKED_TIME  || 
		(next_x_loc() == move_to_loc_x && next_y_loc() == move_to_loc_y) || 
		((abs(move_to_loc_x - next_x_loc()) <= obj_loc_width()) && 
		 (abs(move_to_loc_y - next_y_loc()) <= obj_loc_height()) && 
		 !can_move(move_to_loc_x, move_to_loc_y) &&
		 !checking_who_occupy_the_place_i_want_to_go(move_to_loc_x, move_to_loc_y)))
	{
		set_no_longer_blocked();
		stop_move();
	}
	else
		move_to(move_to_loc_x, move_to_loc_y);
}
コード例 #6
0
ファイル: oun_act.cpp プロジェクト: mecirt/7k2
//--------- Begin of function Unit::stop_order ---------//
//
// Stop the current order without completion.
//
void Unit::stop_order()
{
	stop_move();	// a UnitB function

	//----- if the order is initiated by an AI --//

	if( cur_order.ai_action_id && nation_recno )
		nation_array[nation_recno]->action_failure(cur_order.ai_action_id, sprite_recno);

	cur_order.set(UNIT_STOP);

	clear_pushed_order();			// clear pushed orders if there are any

	set_original_target(-1, -1);	// clear the original target

	force_move_flag = false;
}
コード例 #7
0
ファイル: oun_act.cpp プロジェクト: mecirt/7k2
//--------- Begin of function Unit::push_order ---------//
//
// Note: the stack only has space for one Order object.
//
void Unit::push_order()
{
	err_when( has_pushed_order() > 0 );		// cannot push when the only one stack space is used

	pushed_order = cur_order;

	// ##### begin Gilbert 31/5 ########//
	// if the unit is stopped, store current location, used when resuming the action
	if( pushed_order.mode == UNIT_STOP )
	{
		pushed_order.set(UNIT_STOP, -2, next_x_loc(), next_y_loc() );
		// para = -2; to identify resume move, see execute_attack
	}
	// ##### end Gilbert 31/5 ########/

	cur_order.set(UNIT_STOP);

	stop_move();
}
コード例 #8
0
ファイル: oun_act.cpp プロジェクト: mecirt/7k2
//--------- Begin of function Unit::stop_cur_order ---------//
//
// Stop the current order without completion.
//
void Unit::stop_cur_order()
{
	stop_move();

	cur_order.set(UNIT_STOP);
}
コード例 #9
0
ファイル: ounitb.cpp プロジェクト: mecirt/7k2
//--------- Begin of function UnitB::move_to ---------//
//
// Move a unit to a specified location
//
// <int>  destXLoc - the x-coordinate of the destination
// <int>  destYLoc - the y-coordinate of the destination
// <bool> raiseDest - default is true, if not want to raise destination, false
// 
void UnitB::move_to(int destXLoc, int destYLoc, bool raiseDest)
{
	// ###### begin Gilbert 22/3 #######//
	// other people may ask this unit to move away while it is dead

	if( hit_points <= 0 || cur_action == SPRITE_DIE )
		return;
	// ###### end Gilbert 22/3 #######//

//	err_when(destXLoc < 0 || destXLoc >= MAX_WORLD_X_LOC || destYLoc < 0 || destYLoc >= MAX_WORLD_Y_LOC);
	destXLoc = min(destXLoc, MAX_WORLD_X_LOC-1);
	destXLoc = max(destXLoc, 0);
	destYLoc = min(destYLoc, MAX_WORLD_Y_LOC-1);
	destYLoc = max(destYLoc, 0);

	stop_move();

	//--- save the destination for later possible retries in searching when it is blocked ----//

	move_to_loc_x = destXLoc;
	move_to_loc_y = destYLoc;

	if((destXLoc == next_x_loc()) && (destYLoc == next_y_loc()))
		return;

	//------- search the path ---------//

//#ifdef DEBUG
//	unsigned long pathFinderStartTime = m.get_time();
//#endif
	path_finder.set_attribute(loc_width, loc_height, mobile_type, 0);

	// ###### begin Gilbert 31/5 #######//
	err_when( cur_order.mode == UNIT_ATTACK && !cast_to_Unit() );
	int stopAtRange = cur_order.mode == UNIT_ATTACK ? cast_to_Unit()->attack_range()-1 : 0;
	// subtract one attack_range so close attack can search near the target
	// and range attack search a little closer
	// ###### end Gilbert 31/5 #######//

	//----- code for handle nation power option -----//

	bool handlePowerNationFlag = false;

	path_finder.set_handle_power_nation(0);

	if( nation_recno )
	{
		Nation *nationPtr = nation_array[nation_recno];

		int srcLocPowerNation  = world.get_loc(next_x_loc(), next_y_loc())->power_nation_recno;
		int destLocPowerNation = world.get_loc(destXLoc, destYLoc)->power_nation_recno;

		//--- only if unit stands on a passable location and the destination is passable, we handle power nation ---//

		if( (!srcLocPowerNation  || nationPtr->get_relation_passable(srcLocPowerNation)) &&
			 (!destLocPowerNation || nationPtr->get_relation_passable(destLocPowerNation)) )
		{
			path_finder.set_handle_power_nation(1, nationPtr->relation_passable_array );
			handlePowerNationFlag = true;
		}
	}

	//--------- find the path now ---------//

	int rangeX1, rangeY1, rangeX2, rangeY2;

	get_object_range(destXLoc, destYLoc, rangeX1, rangeY1, rangeX2, rangeY2);

	// ######## begin Gilbert 31/5 ##########//
	path_finder.find_path(next_x_loc(), next_y_loc(), destXLoc, destYLoc,
								 rangeX1, rangeY1, rangeX2, rangeY2, 1, raiseDest,
								 0, stopAtRange );
	// ######## end Gilbert 31/5 ##########//

	if( path_finder.is_path_found() )
	{
		set_no_longer_blocked();

		seek_path_fail_count=0;		// reset the failure counter
	}
	else	//---- path searching failed ----//
	{
		if(!is_blocked())
			set_not_seriously_blocked();

		//--- if the path search failed, increase the failure counter ---//

//		if( seek_path_fail_count < 100 )		// prevent numeric overflow
//			seek_path_fail_count++;
	}

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

	int pathNodeCount;
	int totalSteps;			// total number of steps to walk through the whole path.

	if( cur_path )
		mem_del( cur_path );

	cur_path = path_finder.retrieve(pathNodeCount, totalSteps);  // retrieves the path

	// ###### begin Gilbert 11/5 #########//
	if( cur_path )
	{
		cur_path_result_id = pathNodeCount;		// start with the last node
		steps_remaining = totalSteps;
	}
	else
	{
		cur_path_result_id = 0;
		steps_remaining = 0;
	}
	// ###### end Gilbert 11/5 #########//

//#ifdef DEBUG
//	// ######## begin Gilbert 27/4 #######//
//	pathFinderStartTime = m.get_time() - pathFinderStartTime;
//	pathfind_profile_time += pathFinderStartTime;
//	pathfind_count++;
//	if( pathFinderStartTime > longest_pathfind_profile_time )
//	{
//		longest_pathfind_profile_time = pathFinderStartTime;
//		longest_pathfind_unit_recno = sprite_recno;
//	}
//	// ######## begin Gilbert 27/4 #######//
//#endif

	if(!cur_path)
	{
		if(handlePowerNationFlag)
		{
			// ##### begin Gilber 27/4 ########//
//#ifdef DEBUG
			// unsigned long pathFinderStartTime = m.get_time();
			// pathFinderStartTime = m.get_time();
//#endif
			// ##### end Gilber 27/4 ########//
			// ###### begin Gilbert 12/5 ########//
			// path_finder.set_attribute(loc_width, loc_height, mobile_type, PFIND_IGNORE_UNIT );
			// ###### end Gilbert 12/5 ########//
			path_finder.set_handle_power_nation(0);
			handlePowerNationFlag = false;

			// ######## begin Gilbert 31/5 ##########//
			path_finder.find_path(next_x_loc(), next_y_loc(), destXLoc, destYLoc,
								 rangeX1, rangeY1, rangeX2, rangeY2, 1, raiseDest,
								 0, stopAtRange );
			// ######## end Gilbert 31/5 ##########//

			if( path_finder.is_path_found() )
			{
				set_no_longer_blocked();

				seek_path_fail_count=0;		// reset the failure counter
			}
			else	//---- path searching failed ----//
			{
				if(!is_blocked())
					set_not_seriously_blocked();
			}
			if( cur_path )
				mem_del( cur_path );

			cur_path = path_finder.retrieve(pathNodeCount, totalSteps);  // retrieves the path

			// ###### begin Gilbert 11/5 #########//
			if( cur_path )
			{
				cur_path_result_id = pathNodeCount;		// start with the last node
				steps_remaining = totalSteps;
			}
			else
			{
				cur_path_result_id = 0;
				steps_remaining = 0;
			}
			// ###### end Gilbert 11/5 #########//
//#ifdef DEBUG
//			// ######## begin Gilbert 27/4 #######//
//			pathFinderStartTime = m.get_time() - pathFinderStartTime;
//			pathfind_profile_time += pathFinderStartTime;
//			pathfind_count++;
//			if( pathFinderStartTime > longest_pathfind_profile_time )
//			{
//				longest_pathfind_profile_time = pathFinderStartTime;
//				longest_pathfind_unit_recno = sprite_recno;
//			}
//			// ######## begin Gilbert 27/4 #######//
//#endif
			if(!cur_path)
			{
				if(!handle_blocking())
					set_no_longer_blocked();	
				if(seek_path_fail_count <= 100*SEEK_PATH_FAIL_INCREMENT)
					seek_path_fail_count+=SEEK_PATH_FAIL_INCREMENT;		// 10 is the single increment unit. It will be reduce by 1 each time in Unit::attack()
			}
		}
		else
		{
			if(!handle_blocking())
				set_no_longer_blocked();
			if(seek_path_fail_count <= 100*SEEK_PATH_FAIL_INCREMENT)
				seek_path_fail_count+=SEEK_PATH_FAIL_INCREMENT;
		}
	}

	//--------- start the first move ---------//

	if( cur_path && cur_action != SPRITE_MOVE )			// if it is previously moving, don't call next_move() as it has still yet to finish its remaining pixel move to snap to grids
	{
		cur_action = SPRITE_MOVE;
		cur_frame = 1;
		retry_state = 0;
	}
	else
	{
		// ###### begin Gilbert 15/5 #########//
		if( cur_x == next_x && cur_y == next_y )
		{
			wait_count = 0;
			set_wait(); 
		}
		// ###### end Gilbert 15/5 #########//
	}
}
コード例 #10
0
ファイル: ounitb.cpp プロジェクト: mecirt/7k2
//--------- Begin of function UnitB::set_next --------//
//
//	set the next coordinates to move to
//
// <int> newNextX, newNextY	- next coordinate to move to
// <int> para						- used to count the result_path_dist
// <int> ignoreBlockCheck		- whether ignore blocking check or not
//
int UnitB::set_next(int newNextX, int newNextY, int para, int ignoreBlockCheck)
{
	static char callingCount=0;

	int curNextXLoc = next_x_loc();
	int curNextYLoc = next_y_loc();
	int newNextXLoc = newNextX >> ZOOM_X_SHIFT_COUNT;
	int newNextYLoc = newNextY >> ZOOM_Y_SHIFT_COUNT;
	//------begin Juliet 14/10-----//
	int tempEndX = newNextXLoc+obj_loc_width()-1;
	int tempEndY = newNextYLoc+obj_loc_height()-1;
	//------end Juliet 14/10-------//
	short w, h, x, y;

	callingCount++;          // this function is being called, prevent recursive calling

	if(curNextXLoc!=newNextXLoc || curNextYLoc!=newNextYLoc)
	{
		if(!is_dir_correct())
		{
			set_turn();
			return 1;
		}
	}

	//----------- blocking check ---------//

	if( !ignoreBlockCheck )
	{
		int isBlocked=0;

		for(h=0, y=newNextYLoc; h<loc_height && !isBlocked ; h++, y++)
		{
			for(w=0, x=newNextXLoc; w<loc_width; w++, x++)
			{
				Location* locPtr = world.get_loc(x,y);

				if( locPtr->can_move(mobile_type) )
					continue;

				//--- this location is occupied by the unit itself ---//

				if( locPtr->unit_recno(mobile_type) == sprite_recno )
					continue;

				isBlocked = 1;
				break;
			}
		}

		if( isBlocked )
		{
			//----- if we have already reach the destination -----//

			
			int rangeX1, rangeY1, rangeX2, rangeY2;

			get_object_range(move_to_loc_x, move_to_loc_y, rangeX1, rangeY1, rangeX2, rangeY2);

			if( m.is_touch( rangeX1, rangeY1, rangeX2, rangeY2,
								 newNextXLoc, newNextYLoc, newNextXLoc+loc_width-1, newNextYLoc+loc_height-1 ) )
			{
				stop_move();
			}
			else //------- otherwise wait ---------//
			{
				set_wait();
			}
			
			callingCount--;
			return 0;
		}
	}

	//--------- set the sprite_recno in new locations -----------//

	for(h=0, y=curNextYLoc; h<loc_height; h++, y++)
	{
		for(w=0, x=curNextXLoc; w<loc_width; w++, x++)
			world.get_loc(x,y)->remove_unit(mobile_type);
	}

	for(h=0, y=newNextYLoc; h<loc_height; h++, y++)
	{
		for(w=0, x=newNextXLoc; w<loc_width; w++, x++)
			world.get_loc(x,y)->set_unit(sprite_recno,mobile_type);
	}

	//----- set the new next coordinate ------//

	next_x = newNextX;
	next_y = newNextY;

	callingCount--;

	if( steps_remaining > 0 )		// steps_remaining can be decreased to negative as set_next() is called when stopping a unit, which is an addition to the steps it is supposed to move 
		steps_remaining--;

	// --------- explore map ---------//

	if( cast_to_Unit() )
		cast_to_Unit()->explore_on_move(curNextXLoc, curNextYLoc, newNextXLoc, newNextYLoc );

	return 1;
}
コード例 #11
0
ファイル: ounitb.cpp プロジェクト: mecirt/7k2
//------------Begin of function Unit::handle_blocking-------------//
//
//This function function handles blocking situation
// return type <bool> - return true if handle successfully
//						return false if handle unsuccessfully
bool UnitB::handle_blocking()
{
	
	//---------Defining and initializing local variables-----------//
	int occupyingUnitRecordNumber;
	Unit* theOccupyingObject=NULL;
	int occLocX, occLocY;
	int theMoveToPlaceX, theMoveToPlaceY;
	bool handleSuccessfully=false;
	int is, js;
	//--------------------------------------------------------------//
	
	//setting the unit himself as not occupying the tile, otherwise it will found out that
	//he himself occupying the tile
		
	int lX = next_x_loc();
	int lY = next_y_loc();

	for(is = 0; is<obj_loc_width(); is++)
		for(js=0; js<obj_loc_height(); js++)
			world.get_loc(lX+is, lY+js)->remove_unit(mobile_type);
	
	//some local variables for use
	int checkingLocX=lX;
	int checkingLocY=lY;
	int directionX=0, directionY=0;
	int directionAngle;
	int destX = move_to_loc_x;
	int destY = move_to_loc_y;

	//would like to check first the direction of the destination, it makes more sense
	int diffX = destX-lX;
	int diffY = destY-lY;

	int stepSizeX=0, stepSizeY=0;
	
	if(diffX >= 0)
	{
		if(diffY<=0)
		{
			if(diffY >= -diffX)
			{
				checkingLocX++;
				directionX=1;
			}
			else
			{
				checkingLocY--;
				directionY=-1;
			}
		}
		else
		{
			if(diffY <= diffX)
			{
				checkingLocX++;
				directionX=1;
			}
			else
			{
				checkingLocY++;
				directionY =1;
			}
		}
	}
	else
	{
		if(diffY<=0)
		{
			if(diffY <= diffX)
			{
				checkingLocX--;
				directionX = -1;
			}
			else
			{
				checkingLocY--;
				directionY = -1;
			}
		}
		else
		{
			if(diffY <= -diffX)
			{
				checkingLocX--;
				directionX = -1;
			}
			else
			{
				checkingLocY++;
				directionY = 1;
			}
		}
	}
	
	if(!diffX && !diffY)
	{
		lX = next_x_loc();
		lY = next_y_loc();
		for(is = 0; is< obj_loc_width(); is++)
			for(js=0; js<obj_loc_height(); js++)
				world.get_loc(lX+is, lY+js)->set_unit(sprite_recno, mobile_type);
		
		return false;
	}

	directionAngle = m.angle_lookup(directionX, directionY);

	int firstTimeAngle = directionAngle;
	
	//loop over all the directiion of the blocked unit

	while(!handleSuccessfully && directionAngle < (firstTimeAngle+360))
	{
		occupyingUnitRecordNumber = checking_who_occupy_the_place_i_want_to_go(checkingLocX, checkingLocY);

		if(occupyingUnitRecordNumber)
			theOccupyingObject = unit_array[occupyingUnitRecordNumber];
		else
			theOccupyingObject = NULL;

		//do it only when it is of the same nationality and is a unit and is not a troop
		//let the blocking unit to move to the direction of the blocked unit want to go to

		if(theOccupyingObject && theOccupyingObject->nation_recno == nation_recno)
		{
			stepSizeX = obj_loc_width();
			stepSizeY = obj_loc_height();
			occLocX = theOccupyingObject->next_x_loc();
			occLocY = theOccupyingObject->next_y_loc();

			stepSizeX *= directionX;
			stepSizeY *= directionY;

			theMoveToPlaceX = occLocX+stepSizeX;
			theMoveToPlaceY = occLocY+stepSizeY;
			
			Location* locPtr = world.get_loc(theMoveToPlaceX, theMoveToPlaceY);
					
			//if the blocking unit successfully walk away, the blocked unit can then try to find a new path to the destination
			if( theOccupyingObject->can_move(theMoveToPlaceX, theMoveToPlaceY) || 
				theOccupyingObject->checking_who_occupy_the_place_i_want_to_go(theMoveToPlaceX, theMoveToPlaceY))
			{
				theOccupyingObject->move_to(theMoveToPlaceX, theMoveToPlaceY, false);
				if(theOccupyingObject->cur_action == SPRITE_MOVE || theOccupyingObject->cur_action == SPRITE_WAIT)
				{
					stop_move(); 
					set_first_time_blocked();
					handleSuccessfully = true;
				}
			}
		}
		
		directionAngle+=45;
		m.xy_lookup(directionAngle, directionX, directionY);
		checkingLocX = lX+directionX;
		checkingLocY = lY+directionY;
	}
	
	//set back the unit to occupy the tile after handling blocking.
	lX = next_x_loc();
	lY = next_y_loc();
	for(is = 0; is< obj_loc_width(); is++)
		for(js=0; js<obj_loc_height(); js++)
			world.get_loc(lX+is, lY+js)->set_unit(sprite_recno, mobile_type);

	return handleSuccessfully;
}