//------------------- 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; }
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; }
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; }
//-------- 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; } }
//-------- 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; }
//-------- 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 }
//-------- 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; } }