コード例 #1
0
ファイル: OSPREOFF.cpp プロジェクト: sraboy/7kaa
//------------------- static function --------------------//
int SeekPathReuse::can_walk_s2(int xLoc, int yLoc)
{
    if(xLoc>=MAX_WORLD_X_LOC-1 || yLoc>=MAX_WORLD_Y_LOC-1)
        return 0;

    if(can_walk(xLoc, yLoc) && can_walk(xLoc+1,yLoc) && can_walk(xLoc,yLoc+1) && can_walk(xLoc+1,yLoc+1))
        return 1;
    else
        return 0;
}
コード例 #2
0
ファイル: Babar.cpp プロジェクト: joetde/SuperBadbar
state_player Babar::get_state() const
{
    if (m_crouch_time && can_walk() )
        return CROUCH_WALKING;
    if (m_crouch_time)
        return CROUCH;
    if (m_jump || m_double_jump || m_ready_double_jump) // m_ready_double_jump indique qu'on est entre saut et doublesaut
        return JUMP;
    if (can_walk() )
        return WALK;
    return STATIC;
}
コード例 #3
0
ファイル: tux.cpp プロジェクト: HybridDog/supertux
void
Tux::try_continue_walking(float dt_sec)
{
  if (!m_moving)
    return;

  // Let tux walk
  m_offset += TUXSPEED * dt_sec;

  // Do nothing if we have not yet reached the next tile
  if (m_offset <= 32)
    return;

  m_offset -= 32;

  auto sprite_change = m_worldmap->at_sprite_change(m_tile_pos);
  change_sprite(sprite_change);

  // if this is a special_tile with passive_message, display it
  auto special_tile = m_worldmap->at_special_tile();
  if (special_tile)
  {
    // direction and the apply_action_ are opposites, since they "see"
    // directions in a different way
    if ((m_direction == Direction::NORTH && special_tile->get_apply_action_south()) ||
        (m_direction == Direction::SOUTH && special_tile->get_apply_action_north()) ||
        (m_direction == Direction::WEST && special_tile->get_apply_action_east()) ||
        (m_direction == Direction::EAST && special_tile->get_apply_action_west()))
    {
      process_special_tile(special_tile);
    }
  }

  // check if we are at a Teleporter
  auto teleporter = m_worldmap->at_teleporter(m_tile_pos);

  // stop if we reached a level, a WORLDMAP_STOP tile, a teleporter or a special tile without a passive_message
  if ((m_worldmap->at_level()) ||
      (m_worldmap->tile_data_at(m_tile_pos) & Tile::WORLDMAP_STOP) ||
      (special_tile && !special_tile->is_passive_message() && special_tile->get_script().empty()) ||
      (teleporter) ||
      m_ghost_mode)
  {
    if (special_tile && !special_tile->get_map_message().empty() && !special_tile->is_passive_message()) {
      m_worldmap->set_passive_message({}, 0.0f);
    }
    stop();
    return;
  }

  // if user wants to change direction, try changing, else guess the direction in which to walk next
  const int tile_data = m_worldmap->tile_data_at(m_tile_pos);
  if ((m_direction != m_input_direction) && can_walk(tile_data, m_input_direction)) {
    m_direction = m_input_direction;
    m_back_direction = reverse_dir(m_direction);
  } else {
    Direction dir = Direction::NONE;
    if (tile_data & Tile::WORLDMAP_NORTH && m_back_direction != Direction::NORTH)
      dir = Direction::NORTH;
    else if (tile_data & Tile::WORLDMAP_SOUTH && m_back_direction != Direction::SOUTH)
      dir = Direction::SOUTH;
    else if (tile_data & Tile::WORLDMAP_EAST && m_back_direction != Direction::EAST)
      dir = Direction::EAST;
    else if (tile_data & Tile::WORLDMAP_WEST && m_back_direction != Direction::WEST)
      dir = Direction::WEST;

    if (dir == Direction::NONE) {
      // Should never be reached if tiledata is good
      log_warning << "Could not determine where to walk next" << std::endl;
      stop();
      return;
    }

    m_direction = dir;
    m_input_direction = m_direction;
    m_back_direction = reverse_dir(m_direction);
  }

  // Walk automatically to the next tile
  if (m_direction == Direction::NONE)
    return;

  Vector next_tile;
  if (!m_ghost_mode && !m_worldmap->path_ok(m_direction, m_tile_pos, &next_tile)) {
    log_debug << "Tilemap data is buggy" << std::endl;
    stop();
    return;
  }

  auto next_sprite = m_worldmap->at_sprite_change(next_tile);
  if (next_sprite != nullptr && next_sprite->m_change_on_touch) {
    change_sprite(next_sprite);
  }
  //SpriteChange* last_sprite = m_worldmap->at_sprite_change(tile_pos);
  if (sprite_change != nullptr && next_sprite != nullptr) {
    log_debug << "Old: " << m_tile_pos << " New: " << next_tile << std::endl;
    sprite_change->set_stay_action();
  }

  m_tile_pos = next_tile;
}
コード例 #4
0
ファイル: OSPREUSE.cpp プロジェクト: AMDmi3/7kaa
//-------- Begin of function SeekPathReuse::get_result ---------//
// return the final result node path
//ResultNode* SeekPathReuse::get_result(int& resultNodeCount)
//
ResultNode* SeekPathReuse::get_result(int& resultNodeCount, short& pathDist)
{
	if(reuse_path_status == REUSE_PATH_FIRST_SEEK)
	{
		resultNodeCount = num_of_result_node;
 		reuse_path_dist = count_path_dist(path_reuse_result_node_ptr, num_of_result_node);
 		pathDist = reuse_path_dist;
		return path_reuse_result_node_ptr;
	}
	else
	{
		err_when(reuse_path_status!=REUSE_PATH_SEARCH && reuse_path_status!=REUSE_PATH_INCOMPLETE_SEARCH);

		if(path_reuse_result_node_ptr!=NULL && num_of_result_node>0)
		{
			sys_yield(); // update cursor position
			if(num_of_result_node<2)
			{
				mem_del(path_reuse_result_node_ptr);
				path_reuse_result_node_ptr = NULL;
				num_of_result_node = 0;
			}

			sys_yield(); // update cursor position

			resultNodeCount = num_of_result_node;
 			reuse_path_dist = count_path_dist(path_reuse_result_node_ptr, num_of_result_node);
 			pathDist = reuse_path_dist;
		}
		else
		{
			num_of_result_node = 0;
			if(path_reuse_result_node_ptr!=NULL)
			{
				mem_del(path_reuse_result_node_ptr);
				path_reuse_result_node_ptr = NULL;
			}

			err_when(num_of_result_node!=0 || path_reuse_result_node_ptr!=NULL);
		}

		//******************* debug **********************//
		#ifdef DEBUG
			err_when(mobile_type!=UNIT_LAND && pathDist%2);
			if(!path_reuse_result_node_ptr && num_of_result_node>0)
			{
				//---------------------------------------------------------//
				// final checking, error free for the result_path
				//---------------------------------------------------------//
				ResultNode*	debugResultPtr = path_reuse_result_node_ptr;
				ResultNode*	debugStartNode = path_reuse_result_node_ptr;
				ResultNode*	debugEndNode = debugStartNode + 1;
				int			debugCount = num_of_result_node;
				int			dvX, dvY;	// vector direction
				int			dXLoc, dYLoc;

				err_when(mobile_type!=UNIT_LAND && (debugStartNode->node_x%2 || debugStartNode->node_y%2));
				for(int d=1; d<debugCount; d++)
				{
					//------- check x, y vector magnitude ---------//
					debugStartNode = path_reuse_result_node_ptr + d-1;
					debugEndNode = debugStartNode + d;
					err_when(mobile_type!=UNIT_LAND && (debugEndNode->node_x%2 || debugEndNode->node_y%2));
					dvX = debugEndNode->node_x - debugStartNode->node_x;
					dvY = debugEndNode->node_y - debugStartNode->node_y;

					err_when(dvX!=0 && dvY!=0 && abs(dvX)!=abs(dvY));
					if(dvX)	dvX /= abs(dvX);
					if(dvY)	dvY /= abs(dvY);
					dXLoc = debugStartNode->node_x;
					dYLoc = debugStartNode->node_y;
					
					//-------- check accessible ---------//
					while(dXLoc!=debugEndNode->node_x || dYLoc!=debugEndNode->node_y)
					{
						dXLoc += dvX;
						dYLoc += dvY;
						err_when(unit_size==1 && !can_walk(dXLoc, dYLoc));
						err_when(unit_size==2 && !can_walk_s2(dXLoc, dYLoc));
					}
				}
			}
		#endif
		//******************* debug **********************//

		return path_reuse_result_node_ptr;
	}
}
コード例 #5
0
ファイル: OSPREOFF.cpp プロジェクト: sraboy/7kaa
//-------- Begin of function SeekPathReuse::get_next_nonblocked_offset_loc ---------//
// find the next nonblocked offset location if the inputed location is blocked
// return 1 if found, 0 for none
//
int SeekPathReuse::get_next_nonblocked_offset_loc(int& nextXLoc, int&nextYLoc)
{
    int found = 0;
    int unitDestX, unitDestY;

    /*#ifdef DEBUG
    	int debugLoopCount = 0;
    #endif

    while(!found)
    {
    	err_when(++debugLoopCount>10000);
    	if(!get_next_offset_loc(nextXLoc, nextYLoc))
    		break; // all nodes visited

    	unitDestX = nextXLoc+x_offset;
    	unitDestY = nextYLoc+y_offset;

    	err_when(unit_size!=1);
    	if(unitDestX>=0 && unitDestX<MAX_WORLD_X_LOC && unitDestY>=0 && unitDestY<MAX_WORLD_Y_LOC &&
    		can_walk(unitDestX, unitDestY))
    		found = 1;
    }

    return found;*/
    while(!found)
    {
        if(nextXLoc != cur_leader_node_ptr->node_x || nextYLoc != cur_leader_node_ptr->node_y)
        {
            nextXLoc += leader_vec_x;
            nextYLoc += leader_vec_y;

            unitDestX = nextXLoc+x_offset;
            unitDestY = nextYLoc+y_offset;

            err_when(unit_size!=1);
            if(unitDestX>=0 && unitDestX<MAX_WORLD_X_LOC && unitDestY>=0 && unitDestY<MAX_WORLD_Y_LOC &&
                    can_walk(unitDestX, unitDestY))
                found = 1;
        }
        else
        {
            if(cur_leader_node_num < reuse_leader_path_node_num)
            {
                cur_leader_node_num++;
                cur_leader_node_ptr++;
                leader_vec_x = cur_leader_node_ptr->node_x - nextXLoc;
                leader_vec_y = cur_leader_node_ptr->node_y - nextYLoc;
                if(leader_vec_x!=0)
                {
                    leader_vec_x /= abs(leader_vec_x);
                    nextXLoc += leader_vec_x;
                }
                if(leader_vec_y!=0)
                {
                    leader_vec_y /= abs(leader_vec_y);
                    nextYLoc += leader_vec_y;
                }

                unitDestX = nextXLoc+x_offset;
                unitDestY = nextYLoc+y_offset;

                err_when(unit_size!=1);
                if(unitDestX>=0 && unitDestX<MAX_WORLD_X_LOC && unitDestY>=0 && unitDestY<MAX_WORLD_Y_LOC &&
                        can_walk(unitDestX, unitDestY))
                    found = 1;
            }
            else
                break;	// or return 0;
        }

        sys_yield(); // update cursor position
    }

    return found;
}
コード例 #6
0
ファイル: OSPREOFF.cpp プロジェクト: sraboy/7kaa
//-------- Begin of function SeekPathReuse::use_offset_method ---------//
void SeekPathReuse::use_offset_method(int xLoc, int yLoc)
{
    //----------------------------------------------------------------------//
    // checking for incomplete searching
    //----------------------------------------------------------------------//
    if(is_node_avail_empty())
    {
        incomplete_search++;
        reuse_path_status = REUSE_PATH_INCOMPLETE_SEARCH;
        return;
    }

    //-----------------------------------------------------//
    int leaderNodeXLoc = xLoc; // hold the currently referred leader node
    int leaderNodeYLoc = yLoc;

    leader_vec_x = cur_leader_node_ptr->node_x - leaderNodeXLoc;
    leader_vec_y = cur_leader_node_ptr->node_y - leaderNodeYLoc;
    if(leader_vec_x!=0)
        leader_vec_x /= abs(leader_vec_x);
    if(leader_vec_y!=0)
        leader_vec_y /= abs(leader_vec_y);

    ResultNode *partOfResultNodePtr, *curNodePtr;
    int partOfResultNodeNum, restNode;

    partOfResultNodePtr = NULL;
    partOfResultNodeNum = 0;

    //-----------------------------------------------------//
    int unitNodeXLoc, unitNodeYLoc;
    int preNonblockedXLoc, preNonblockedYLoc;
    int nextNonblockedLeaderXLoc, nextNonblockedLeaderYLoc;
    int preLeaderVecX, preLeaderVecY;
    int virDestX, virDestY;
    int pathSeekResult, canReach;

    //-----------------------------------------------------//
    // start walking along the leader path
    //-----------------------------------------------------//
#ifdef DEBUG
    int debugPreLeaderNodeXLoc, debugPreLeaderNodeYLoc;
    while(debugPreLeaderNodeXLoc=leaderNodeXLoc, debugPreLeaderNodeYLoc=leaderNodeYLoc,
            get_next_offset_loc(leaderNodeXLoc, leaderNodeYLoc)) // get next location in the leader path
#else
    while(get_next_offset_loc(leaderNodeXLoc, leaderNodeYLoc)) // get next location in the leader path
#endif
    {
        err_when(leaderNodeXLoc<0 || leaderNodeXLoc>=MAX_WORLD_X_LOC);
        err_when(leaderNodeYLoc<0 || leaderNodeYLoc>=MAX_WORLD_Y_LOC);

        err_when(partOfResultNodePtr!=NULL);
        sys_yield(); // update cursor position

        unitNodeXLoc = leaderNodeXLoc+x_offset;	// calculate the corresponding location in the offset path.
        unitNodeYLoc = leaderNodeYLoc+y_offset;

        if(unitNodeXLoc>=0 && unitNodeXLoc<MAX_WORLD_X_LOC && unitNodeYLoc>=0 && unitNodeYLoc<MAX_WORLD_Y_LOC &&
                ((move_scale==1 && can_walk(unitNodeXLoc, unitNodeYLoc)) ||
                 (move_scale==2 && can_walk(unitNodeXLoc, unitNodeYLoc) &&
                  can_walk(unitNodeXLoc-leader_vec_x, unitNodeYLoc-leader_vec_y)) ))
        {
            //----------------------------------------------------------------------------//
            // offset node exists, so add it to the result path
            //----------------------------------------------------------------------------//
            add_result(unitNodeXLoc, unitNodeYLoc); // add result if location can be reached
            if(unitNodeXLoc==vir_dest_x && unitNodeYLoc==vir_dest_y)
                break;
        }
        else
        {
            //----------------------------------------------------------------------------//
            // get the next non-blocked location calculated by offset
            //----------------------------------------------------------------------------//
            nextNonblockedLeaderXLoc = leaderNodeXLoc; // used as reference
            nextNonblockedLeaderYLoc = leaderNodeYLoc;
            preLeaderVecX = leader_vec_x;
            preLeaderVecY = leader_vec_y;

            //========================================================================//
            //========================================================================//
            if(get_next_nonblocked_offset_loc(nextNonblockedLeaderXLoc, nextNonblockedLeaderYLoc))	// get the next nonblocked location for joining
            {
                if(is_node_avail_empty())
                {
                    incomplete_search++;
                    reuse_path_status = REUSE_PATH_INCOMPLETE_SEARCH;
                    return;
                }

                //--- seek from the current location to the next non-blocked location ---//
                err_when(num_of_result_node<1);
                preNonblockedXLoc = (cur_result_node_ptr-1)->node_x;
                preNonblockedYLoc = (cur_result_node_ptr-1)->node_y;
                //bound_check_x((preNonblockedXLoc = unitNodeXLoc-preLeaderVecX*move_scale));
                //bound_check_y((preNonblockedYLoc = unitNodeYLoc-preLeaderVecY*move_scale));
                err_when(preNonblockedXLoc<0 || preNonblockedXLoc>=MAX_WORLD_X_LOC);
                err_when(preNonblockedYLoc<0 || preNonblockedYLoc>=MAX_WORLD_Y_LOC);

                //-------- find a path to the next non-blocked location ----------//
                bound_check_x((virDestX = nextNonblockedLeaderXLoc+x_offset));
                bound_check_y((virDestY = nextNonblockedLeaderYLoc+y_offset));
                err_when(partOfResultNodePtr!=NULL);

                err_when(unit_size!=1);
                pathSeekResult = seek_path.seek(preNonblockedXLoc, preNonblockedYLoc, virDestX, virDestY,
                                                cur_group_id, mobile_type, SEARCH_MODE_IN_A_GROUP);
                partOfResultNodePtr = seek_path.get_result(partOfResultNodeNum, reuse_path_dist);

                //--------------------------------------------------------------------------//
                // go to destination directly if cannot reach the next nonblocked lcoation
                //--------------------------------------------------------------------------//
                if(partOfResultNodePtr==NULL || partOfResultNodeNum==0)
                    canReach = 0;
                else
                {
#ifdef DEBUG
                    int ddX = abs((cur_result_node_ptr-1)->node_x-partOfResultNodePtr[0].node_x);
                    int ddY = abs((cur_result_node_ptr-1)->node_y-partOfResultNodePtr[0].node_y);
                    err_when(ddX && ddY && ddX!=ddY);
#endif

                    ResultNode *curNode = partOfResultNodePtr + partOfResultNodeNum-1;
                    if(curNode->node_x==virDestX && curNode->node_y==virDestY)
                        canReach = 1;
                    else
                    {
                        canReach = 0;
                        mem_del(partOfResultNodePtr);
                        partOfResultNodePtr = NULL;
                    }
                }

                if(canReach==0)	//	 unable to reach the location specified
                {
                    if(is_node_avail_empty())
                    {
                        incomplete_search++;
                        reuse_path_status = REUSE_PATH_INCOMPLETE_SEARCH;
                        return;
                    }

                    bound_check_x((virDestX = dest_x));
                    bound_check_y((virDestY = dest_y));
                    err_when(partOfResultNodePtr!=NULL);

                    err_when(unit_size!=1);
                    int pathSeekResult= seek_path.seek(preNonblockedXLoc, preNonblockedYLoc, virDestX, virDestY, cur_group_id, mobile_type, SEARCH_MODE_IN_A_GROUP);
                    partOfResultNodePtr = seek_path.get_result(partOfResultNodeNum, reuse_path_dist);

#ifdef DEBUG
                    if(partOfResultNodePtr!=NULL)
                    {
                        int ddX = abs((cur_result_node_ptr-1)->node_x-partOfResultNodePtr[0].node_x);
                        int ddY = abs((cur_result_node_ptr-1)->node_y-partOfResultNodePtr[0].node_y);
                        err_when(ddX && ddY && ddX!=ddY);
                    }
#endif
                }

                //---------------------- connect the two paths ----------------------//
                if(partOfResultNodePtr!=NULL)
                {
                    restNode = partOfResultNodeNum;
                    curNodePtr = partOfResultNodePtr;

                    err_when(preNonblockedXLoc!=partOfResultNodePtr->node_x || preNonblockedYLoc!=partOfResultNodePtr->node_y);

                    restNode--;
                    curNodePtr++;
                    while(restNode)
                    {
                        add_result(curNodePtr->node_x, curNodePtr->node_y);
                        curNodePtr++;
                        restNode--;
                    }

                    debug_reuse_check_path(); //-************** debug checking

                    mem_del(partOfResultNodePtr);
                    partOfResultNodePtr = NULL;
                }

                err_when(partOfResultNodePtr!=NULL);

                if(canReach)
                {
                    leaderNodeXLoc = nextNonblockedLeaderXLoc;
                    leaderNodeYLoc = nextNonblockedLeaderYLoc;
                }
                else
                {
                    //------------------------------------------------//
                    // incomplete search
                    //------------------------------------------------//
                    if(is_node_avail_empty())
                    {
                        incomplete_search++;
                        reuse_path_status = REUSE_PATH_INCOMPLETE_SEARCH;
                        return;
                    }
                    break;
                }

                if(pathSeekResult!=PATH_FOUND && pathSeekResult!=PATH_REUSE_FOUND)
                    break;
            }
            //========================================================================//
            //========================================================================//
            else	// no next non-blocked offset location, searching directly to the destinaton
            {
                //-------------------------------------------------------------//
                // move directly to the destination from the current location
                //
                // This case occurs when the destination cannot be reached.
                //-------------------------------------------------------------//

                //--- seek from the current location to the destination ---//
                //bound_check_x((preNonblockedXLoc = unitNodeXLoc-preLeaderVecX*move_scale));
                //bound_check_y((preNonblockedYLoc = unitNodeYLoc-preLeaderVecY*move_scale));
                err_when(num_of_result_node<1);
                preNonblockedXLoc = (cur_result_node_ptr-1)->node_x;
                preNonblockedYLoc = (cur_result_node_ptr-1)->node_y;
                err_when(preNonblockedXLoc<0 || preNonblockedXLoc>=MAX_WORLD_X_LOC);
                err_when(preNonblockedYLoc<0 || preNonblockedYLoc>=MAX_WORLD_Y_LOC);

                bound_check_x((virDestX = nextNonblockedLeaderXLoc+x_offset));
                bound_check_y((virDestY = nextNonblockedLeaderYLoc+y_offset));
                err_when(partOfResultNodePtr!=NULL);

                //------------------------------------------------//
                // set to incomplete_search for later searching
                //------------------------------------------------//
                incomplete_search++;
                reuse_path_status = REUSE_PATH_INCOMPLETE_SEARCH;

#ifdef DEBUG
                int ddX1 = abs((cur_result_node_ptr-1)->node_x-preNonblockedXLoc);
                int ddY1 = abs((cur_result_node_ptr-1)->node_y-preNonblockedYLoc);
                err_when(ddX1 && ddY1 && ddX1!=ddY1);
#endif

                err_when(unit_size!=1);
                seek_path.seek(preNonblockedXLoc, preNonblockedYLoc, virDestX, virDestY, cur_group_id, mobile_type, 1);
                partOfResultNodePtr = seek_path.get_result(partOfResultNodeNum, reuse_path_dist);

                //---------------- connect the two paths together ----------------//
                if(partOfResultNodePtr!=NULL)
                {
#ifdef DEBUG
                    int ddX = abs((cur_result_node_ptr-1)->node_x-partOfResultNodePtr[0].node_x);
                    int ddY = abs((cur_result_node_ptr-1)->node_y-partOfResultNodePtr[0].node_y);
                    err_when(ddX && ddY && ddX!=ddY);
#endif

                    err_when(preNonblockedXLoc!=partOfResultNodePtr->node_x || preNonblockedYLoc!=partOfResultNodePtr->node_y);

                    restNode = partOfResultNodeNum-1;
                    curNodePtr = partOfResultNodePtr+1;

                    while(restNode)
                    {
                        add_result(curNodePtr->node_x, curNodePtr->node_y);
                        curNodePtr++;
                        restNode--;
                    }

                    debug_reuse_check_path(); //-************** debug checking

                    mem_del(partOfResultNodePtr);
                    partOfResultNodePtr = NULL;
                }
            }//end if get_next_nonblocked_offset_loc()

            //-------------------------------------------------------------------------------------------------//
            // update leaderNode?Loc since it may be changed after calling get_next_nonblocked_offset_loc()
            //-------------------------------------------------------------------------------------------------//
            leaderNodeXLoc = nextNonblockedLeaderXLoc;
            leaderNodeYLoc = nextNonblockedLeaderYLoc;
        }

        debug_reuse_check_path(); //-************** debug checking
        err_when(partOfResultNodePtr!=NULL);
    }	// end while

    err_when(partOfResultNodePtr!=NULL);
    debug_reuse_check_path(); //-************** debug checking
}
コード例 #7
0
ファイル: OSPREOFF.cpp プロジェクト: sraboy/7kaa
//-------- Begin of function SeekPathReuse::seek_path_join_offset ---------//
// The join-offset-path method.
//
void SeekPathReuse::seek_path_join_offset()
{
    if(!is_leader_path_valid())
        return;

    //----------------------------------------------------------------------//
    // checking for incomplete searching
    //----------------------------------------------------------------------//
    if(is_node_avail_empty())
    {
        incomplete_search++;
        reuse_path_status = REUSE_PATH_INCOMPLETE_SEARCH;
        return;
    }

    err_when(unit_size!=1);
    memset(reuse_node_matrix, 0, sizeof(short)*MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC/4);
    path_reuse_result_node_ptr = NULL;

    //--------------------------------------------------------------//
    // initialization and declaring variables
    //--------------------------------------------------------------//
    int connectResultNodeNum;
    ResultNode* connectResultNodePtr=NULL;

    cur_leader_node_ptr = reuse_leader_path_backup;
    cur_leader_node_num = 1;

    int leaderNodeXLoc = cur_leader_node_ptr->node_x;
    int leaderNodeYLoc = cur_leader_node_ptr->node_y;

#ifdef DEBUG
    int debugLoopCount = 0;
#endif

    do
    {
        err_when(++debugLoopCount>10000);
        set_index_in_node_matrix(leaderNodeXLoc+x_offset, leaderNodeYLoc+y_offset);
    } while(get_next_offset_loc(leaderNodeXLoc, leaderNodeYLoc));

    //--------------------------------------------------------------//
    // copy the node_matrix to that node_matrix used in class SeekPath
    //--------------------------------------------------------------//
    err_when(unit_size!=1);
    seek_path.set_node_matrix(reuse_node_matrix);

    //--------------------------------------------------------------//
    // process shortest path searching to find a walkable point in
    // the offset path for connection
    //--------------------------------------------------------------//
    //--- if the starting location is already in the offset path, process it immediately ---//
    err_when(unit_size!=1);
    short *locNode = reuse_node_matrix + MAX_WORLD_X_LOC/2*(start_y/2) + (start_x/2);

    if(*locNode > max_node && mobile_type==UNIT_LAND)	// starting point on the reuse offset path
    {
        connectResultNodePtr = (ResultNode*) mem_add(sizeof(ResultNode)*2);
        ResultNode* curNode = connectResultNodePtr;
        curNode->node_x = start_x;
        curNode->node_y = start_y;
        connectResultNodeNum = 1;
        curNode++;

        switch(*locNode-max_node)
        {
        case 1:
            if(start_x%2 || start_y%2)
            {
                curNode->node_x = (start_x%2) ? start_x-1 : start_x;
                curNode->node_y = (start_y%2) ? start_y-1 : start_y;
                connectResultNodeNum++;
            }
            break;

        case 2:
            if(!(start_x%2 && start_y%2==0))
            {
                curNode->node_x = (start_x%2) ? start_x : start_x+1;
                curNode->node_y = (start_y%2) ? start_y-1 : start_y;
                connectResultNodeNum++;
            }
            break;

        case 3:
            if(!(start_x%2==0 && start_y%2))
            {
                curNode->node_x = (start_x%2) ? start_x-1 : start_x;
                curNode->node_y = (start_y%2) ? start_y : start_y+1;
                connectResultNodeNum++;
            }
            break;

        case 4:
            if(start_x%2==0 || start_y%2==0)
            {
                curNode->node_x = (start_x%2) ? start_x : start_x+1;
                curNode->node_y = (start_y%2) ? start_y : start_y+1;
                connectResultNodeNum++;
            }
            break;
        }

        //********BUGHERE
        // unable to handle this blocked case now, abort path-reuse and seeking instead
        if(connectResultNodeNum>1 && !can_walk(curNode->node_x, curNode->node_y))
        {
            path_reuse_result_node_ptr = call_seek(start_x, start_y, vir_dest_x, vir_dest_y, cur_group_id, mobile_type, SEARCH_MODE_IN_A_GROUP, num_of_result_node);
            mem_del(connectResultNodePtr);
            return;
        }
    }
    else
    {
        //------------- seek for connection point ------------//
        connectResultNodePtr = call_seek(start_x, start_y, vir_dest_x, vir_dest_y, cur_group_id, mobile_type,
                                         SEARCH_MODE_REUSE, connectResultNodeNum);
        err_when(connectResultNodePtr!=NULL && connectResultNodeNum<2);

        if(connectResultNodePtr==NULL || connectResultNodeNum==0)	// cannot reach the destination
        {
            if(connectResultNodePtr!=NULL)
                mem_del(connectResultNodePtr);

            return;
        }
    }

    //--------------------------------------------------------------//
    // constructing data structure
    //--------------------------------------------------------------//
    result_node_array_def_size += result_node_array_reset_amount;
    path_reuse_result_node_ptr = (ResultNode*) mem_add(sizeof(ResultNode)* result_node_array_def_size);
    memset(path_reuse_result_node_ptr, 0, sizeof(ResultNode)* result_node_array_def_size);
    cur_result_node_ptr = path_reuse_result_node_ptr;
    num_of_result_node = 0;

    //--------------------------------------------------------------//
    // add the result path
    //--------------------------------------------------------------//
    ResultNode* curResultNode = connectResultNodePtr;
    for(int i=0; i<connectResultNodeNum; i++)
    {
        add_result(curResultNode->node_x, curResultNode->node_y);
        curResultNode++;
    }

    //--------------------------------------------------------------//
    // determine the joining point in the offset path
    //--------------------------------------------------------------//
    cur_leader_node_ptr = reuse_leader_path_backup;
    cur_leader_node_num = 1;

    ResultNode *endNode = connectResultNodePtr + connectResultNodeNum - 1;
    short findConnectionPoint = 0;

    if(endNode->node_x==vir_dest_x && endNode->node_y==vir_dest_y)
    {
        if(connectResultNodePtr!=NULL)
            mem_del(connectResultNodePtr);
        return; // already the destination location
    }

    //------------------------------------------------------------------------------------//
    // find a offset-reference point in leader path
    //------------------------------------------------------------------------------------//
    leaderNodeXLoc = cur_leader_node_ptr->node_x;
    leaderNodeYLoc = cur_leader_node_ptr->node_y;
    short notEnd = 1;
    sys_yield(); // update cursor position

    int unitDestX, unitDestY; // for the current searching unit, using the leader path
    do
    {
        //---------- boundary checking -----------//
        bound_check_x((unitDestX = leaderNodeXLoc+x_offset));
        bound_check_y((unitDestY = leaderNodeYLoc+y_offset));

        if(endNode->node_x==unitDestX && endNode->node_y==unitDestY)
            findConnectionPoint = 1;	// ok, connected
        else
            notEnd = get_next_offset_loc(leaderNodeXLoc, leaderNodeYLoc);

        if(!notEnd)
            break;
    } while(!findConnectionPoint);

    sys_yield(); // update cursor position

    //-------------- clear the temporary path ------------//
    if(connectResultNodePtr!=NULL)
        mem_del(connectResultNodePtr);

    //-----------------------------------------------------------------------------//
    // return since cannot find a connection point
    //-----------------------------------------------------------------------------//
    if(!findConnectionPoint)
    {
        //----------------------------------------------------------------------//
        // checking for incomplete searching
        //----------------------------------------------------------------------//
        if(is_node_avail_empty())
        {
            incomplete_search++;
            reuse_path_status = REUSE_PATH_INCOMPLETE_SEARCH;
        }

        if(num_of_result_node==1)
        {
            mem_del(path_reuse_result_node_ptr);
            path_reuse_result_node_ptr = NULL;
            num_of_result_node = 0;
        }
        return;
    }

    //-----------------------------------------------------------------------------//
    // update pointer cur_leader_node_ptr if necessary
    //-----------------------------------------------------------------------------//
    if(leaderNodeXLoc==cur_leader_node_ptr->node_x && leaderNodeYLoc==cur_leader_node_ptr->node_y)	// at the turning point
    {
        if(cur_leader_node_num < reuse_leader_path_node_num)
        {
            cur_leader_node_num++;
            cur_leader_node_ptr++;
        }
        else	// join at the end of the offset path, search finished
            return;
    }

    //----------------------------------------------------------------------------------------//
    // at this moment, the searching unit has a offset path to the leader path.
    // There are not processed leader nodes. These nodes are pointed by cur_leader_node_ptr.
    //----------------------------------------------------------------------------------------//
    use_offset_method(leaderNodeXLoc, leaderNodeYLoc);	// changed to offset method for the rest

    //----------------------------------------------------------------------//
    // checking for incomplete searching
    //----------------------------------------------------------------------//
    ResultNode *lastNode = path_reuse_result_node_ptr + num_of_result_node - 1;
    if((lastNode->node_x!=vir_dest_x || lastNode->node_y!=vir_dest_y) && is_node_avail_empty())
    {
        incomplete_search++;
        reuse_path_status = REUSE_PATH_INCOMPLETE_SEARCH;
    }
}