/* * Seven Kingdoms: Ancient Adversaries * * Copyright 1997,1998 Enlight Software Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #ifdef NO_DEBUG_SEARCH #undef err_when #undef err_here #undef err_if #undef err_else #undef err_now #define err_when(cond) #define err_here() #define err_if(cond) #define err_else #define err_now(msg) #undef debug_reuse_check_path #undef debug_reuse_check_xy_magn #define debug_reuse_check_path() #define debug_reuse_check_xy_magn(x1, y1, x2, y2) #undef DEBUG #endif //------ Begin of function SeekPathReuse::remove_duplicate_node ---------// // this function is used to remove duplicate node // void SeekPathReuse::remove_duplicate_node(ResultNode resultList[], int& nodeCount) { //------------------------------------------------------------// // remove duplicate node //------------------------------------------------------------// ResultNode* curNodePtr = resultList+1; ResultNode* preNodePtr = resultList; ResultNode* writeNodePtr = resultList; int count = 0; err_when(mobile_type!=UNIT_LAND && (preNodePtr->node_x%2 || preNodePtr->node_y%2)); for(int i=1; inode_x%2 || curNodePtr->node_y%2)); if(i%40==0) sys_yield(); // update cursor position if(curNodePtr->node_x!=preNodePtr->node_x || curNodePtr->node_y!=preNodePtr->node_y) { writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; #ifdef DEBUG ResultNode *debugPtr; int vX, vY; if(i>1) { debugPtr = writeNodePtr; vX = debugPtr->node_x - writeNodePtr->node_x; vY = debugPtr->node_y - writeNodePtr->node_y; } err_when(i>1 && vX!=0 && vY!=0 && abs(vX)!=abs(vY)); #endif writeNodePtr++; preNodePtr = curNodePtr; curNodePtr++; count++; } else curNodePtr++; } writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; count++; nodeCount = count; } //-------- End of function SeekPathReuse::remove_duplicate_node ---------// //-------- Begin of function SeekPathReuse::smooth_reuse_path ---------// ResultNode* SeekPathReuse::smooth_reuse_path(ResultNode* resultPath, int& resultNodeNum) { //------------------------------------------------------------// // to handle all the unexpected case in turning direction or // reverse direction in reuse path. Finally, a well-shaped // path will be returned. //------------------------------------------------------------// //-----------------------------------------------------------// // remove duplicate node //-----------------------------------------------------------// remove_duplicate_node(resultPath, resultNodeNum); if(mobile_type==UNIT_LAND) resultPath = smooth_path(resultPath, resultNodeNum); else resultPath = smooth_path2(resultPath, resultNodeNum); return resultPath; } //--------- End of function SeekPathReuse::smooth_reuse_path ---------// //-------- Begin of function SeekPathReuse::smooth_path ---------// ResultNode* SeekPathReuse::smooth_path(ResultNode* resultPath, int& resultNodeNum) { err_when(mobile_type!=UNIT_LAND); #define UNKNOWN_FACTOR 5 //----------------------------------------------------------------------------// // to handle all the unexpected case in turning direction or reverse direction // in reuse path. Finally, a well-shaped path will be returned. //----------------------------------------------------------------------------// ResultNode *preNodePtr; ResultNode *writeNodePtr; ResultNode *curNodePtr; ResultNode *oldPreNodePtr; ResultNode *wellShapedNodePtr; short changed = 1; int count = 0, i; //int resultVectorX, resultVectorY; int tempXLoc, tempYLoc; int necessaryPoint, type; //------------------------------------------------------------// // smoothing the path //------------------------------------------------------------// while(changed) { oldPreNodePtr = resultPath; // may point to writeNodePtr or tempReuseResultPtr list preNodePtr = resultPath+1; // may point to writeNodePtr or tempReuseResultPtr list curNodePtr = resultPath+2; // always point to the tempReuseResultPtr list count = 0; changed = 0; if(resultNodeNum>2) { wellShapedNodePtr = (ResultNode*)mem_add(resultNodeNum*UNKNOWN_FACTOR*sizeof(ResultNode*)); //********BUGHERE memset(wellShapedNodePtr, 0, resultNodeNum*UNKNOWN_FACTOR*sizeof(ResultNode*)); // num of ResultNode may not be enough for use writeNodePtr = wellShapedNodePtr; //---------- write the beginning node ---------// *writeNodePtr = *oldPreNodePtr; count++; i = 2; do { //-------------------------------------------------// // calculate the vector offset and vector magnitude //-------------------------------------------------// vec_x = preNodePtr->node_x-oldPreNodePtr->node_x; vec_y = preNodePtr->node_y-oldPreNodePtr->node_y; err_when(vec_x==0 && vec_y==0); vec_magn = (vec_x!=0) ? abs(vec_x) : abs(vec_y); vec_x /= vec_magn; vec_y /= vec_magn; new_vec_x = curNodePtr->node_x - preNodePtr->node_x; new_vec_y = curNodePtr->node_y - preNodePtr->node_y; err_when(new_vec_x==0 && new_vec_y==0); new_vec_magn = (new_vec_x!=0)?abs(new_vec_x):abs(new_vec_y); new_vec_x /= new_vec_magn; new_vec_y /= new_vec_magn; //----------------------------------------------// // (1) same direction //----------------------------------------------// if(vec_x==new_vec_x && vec_y==new_vec_y) { preNodePtr = curNodePtr; curNodePtr++; err_when(oldPreNodePtr->node_x==preNodePtr->node_x && oldPreNodePtr->node_y==preNodePtr->node_y); continue; } //----------------------------------------------// // (2) reverse direction //----------------------------------------------// if(vec_x==-new_vec_x && vec_y==-new_vec_y) { //--- old vector magnitude != new vector magnitude ----// if(vec_magn!=new_vec_magn) { preNodePtr = curNodePtr; curNodePtr++; err_when(i+1!=resultNodeNum && preNodePtr->node_x==curNodePtr->node_x && preNodePtr->node_y==curNodePtr->node_y); } else if(i+2node_x==preNodePtr->node_x && oldPreNodePtr->node_y==preNodePtr->node_y); continue; } result_vec_x = vec_x+new_vec_x; result_vec_y = vec_y+new_vec_y; necessaryPoint = 0; //----------------------------------------------// // (3) turn 45 degree //----------------------------------------------// if(abs(result_vec_x)<=move_scale && abs(result_vec_y)<=move_scale && (result_vec_x==0 || result_vec_y==0)) { err_when(result_vec_x>=2*move_scale || result_vec_y>=2*move_scale); if((vec_x==0 || vec_y==0) && vec_magn>move_scale) { //--------- choose the farther location if possible --------------// tempXLoc = preNodePtr->node_x - 2*vec_x; tempYLoc = preNodePtr->node_y - 2*vec_y; if(vec_magn>2*move_scale) // add a new point { oldPreNodePtr->node_x = tempXLoc; oldPreNodePtr->node_y = tempYLoc; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; }//else vec_magn==2*move_scale, do nothing } else { //------------------------------------------------------------------------------------// // 1) the vector direction is not horizontal or vertical (only one step is checked), or // 2) the direction is matched but vec_magn==move_scale //------------------------------------------------------------------------------------// if(vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x-vec_x; oldPreNodePtr->node_y = preNodePtr->node_y-vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } } if(new_vec_magn>move_scale) { preNodePtr->node_x += new_vec_x; preNodePtr->node_y += new_vec_y; debug_reuse_check_xy_magn(preNodePtr->node_x, preNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; count++; oldPreNodePtr = preNodePtr; } preNodePtr = curNodePtr; curNodePtr++; changed++; continue; } //----------------------------------------------// // (4) turn 90 degree //----------------------------------------------// if(vec_x*new_vec_x+vec_y*new_vec_y==0) { type = (vec_x==0 || vec_y==0) ? 0 : 1; // 0 for + case, 1 for x case if(type==1) // x case { err_when(new_vec_x-vec_x!=0 && new_vec_y-vec_y!=0); tempXLoc = preNodePtr->node_x+(new_vec_x-vec_x)/2; tempYLoc = preNodePtr->node_y+(new_vec_y-vec_y)/2; if(can_walk(tempXLoc, tempYLoc)) { if(vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x-vec_x; oldPreNodePtr->node_y = preNodePtr->node_y-vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } if(new_vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x+new_vec_x; oldPreNodePtr->node_y = preNodePtr->node_y+new_vec_y; err_when(oldPreNodePtr->node_x==curNodePtr->node_x && oldPreNodePtr->node_y==curNodePtr->node_y); err_when(oldPreNodePtr->node_x==preNodePtr->node_x && oldPreNodePtr->node_y==preNodePtr->node_y); debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } preNodePtr = curNodePtr; curNodePtr++; } else necessaryPoint = 1; } else // + case { if(vec_magn>move_scale && new_vec_magn>move_scale) { tempXLoc = preNodePtr->node_x+new_vec_x-vec_x; tempYLoc = preNodePtr->node_y+new_vec_y-vec_y; if(can_walk(tempXLoc, tempYLoc)) { if(vec_magn>2*move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x-2*vec_x; oldPreNodePtr->node_y = preNodePtr->node_y-2*vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } if(new_vec_magn>2*move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x+2*new_vec_x; oldPreNodePtr->node_y = preNodePtr->node_y+2*new_vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } preNodePtr = curNodePtr; curNodePtr++; } else necessaryPoint = 1; } else // not both vector magnitude>move_scale { if(vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x-vec_x; oldPreNodePtr->node_y = preNodePtr->node_y-vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } if(new_vec_magn>move_scale) { preNodePtr->node_x += new_vec_x; preNodePtr->node_y += new_vec_y; debug_reuse_check_xy_magn(preNodePtr->node_x, preNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; count++; oldPreNodePtr = preNodePtr; } preNodePtr = curNodePtr; curNodePtr++; } } if(!necessaryPoint) { changed++; continue; } } //--------------------------------------------------// // (5) this point is necessary for the reuse-path //--------------------------------------------------// debug_reuse_check_xy_magn(preNodePtr->node_x, preNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; count++; oldPreNodePtr = preNodePtr; preNodePtr = curNodePtr; curNodePtr++; err_when(oldPreNodePtr->node_x==preNodePtr->node_x && oldPreNodePtr->node_y==preNodePtr->node_y); }while(++inode_x, preNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; //------- write the end node -----------// writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; count++; resultNodeNum = count; mem_del(resultPath); resultPath = wellShapedNodePtr; wellShapedNodePtr = NULL; } } return resultPath; } //--------- End of function SeekPathReuse::smooth_path ---------// //-------- Begin of function SeekPathReuse::smooth_path2 ---------// // another version of smooth_path(). This version is for unit's // mobile_type == UNIT_SEA or UNIT_AIR // ResultNode* SeekPathReuse::smooth_path2(ResultNode* resultPath, int& resultNodeNum) { err_when(mobile_type!=UNIT_SEA && mobile_type!=UNIT_AIR); #define UNKNOWN_FACTOR 5 #ifdef DEBUG //------------------------------------------------------------------------// // used to debug for the path of UNIT_SEA //------------------------------------------------------------------------// if(mobile_type==UNIT_SEA && resultNodeNum>1) { ResultNode *debugPtr1 = resultPath; ResultNode *debugPtr2 = resultPath+1; int di=1, dj, dvecX, dvecY, magn; while(dinode_x-debugPtr1->node_x; dvecY = debugPtr2->node_y-debugPtr1->node_y; magn = (abs(dvecX) > abs(dvecY)) ? abs(dvecX) : abs(dvecY); dvecX /= magn; dvecY /= magn; for(dj=1; dj<=magn; dj++) if(mobile_type==UNIT_SEA) err_when(!world.get_loc(debugPtr1->node_x+dvecX*dj, debugPtr1->node_y+dvecY*dj)->sailable()); di++; debugPtr1++; debugPtr2++; } } #endif //----------------------------------------------------------------------------// // to handle all the unexpected case in turning direction or reverse direction // in reuse path. Finally, a well-shaped path will be returned. //----------------------------------------------------------------------------// ResultNode *preNodePtr; ResultNode *writeNodePtr; ResultNode *curNodePtr; ResultNode *oldPreNodePtr; ResultNode *wellShapedNodePtr; short changed = 1; int count = 0, i; int tempXLoc, tempYLoc, tempVectorX, tempVectorY; int necessaryPoint, type; //------------------------------------------------------------// // smoothing the path //------------------------------------------------------------// while(changed) { oldPreNodePtr = resultPath; // may point to writeNodePtr or tempReuseResultPtr list preNodePtr = resultPath+1; // may point to writeNodePtr or tempReuseResultPtr list curNodePtr = resultPath+2; // always point to the tempReuseResultPtr list count = 0; changed = 0; if(resultNodeNum>2) { wellShapedNodePtr = (ResultNode*)mem_add(resultNodeNum*UNKNOWN_FACTOR*sizeof(ResultNode*)); //********BUGHERE memset(wellShapedNodePtr, 0, resultNodeNum*UNKNOWN_FACTOR*sizeof(ResultNode*)); // num of ResultNode may not be enough for use writeNodePtr = wellShapedNodePtr; //---------- write the beginning node ---------// writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; i = 2; do { //-------------------------------------------------// // calculate the vector offset and vector magnitude //-------------------------------------------------// vec_x = preNodePtr->node_x-oldPreNodePtr->node_x; vec_y = preNodePtr->node_y-oldPreNodePtr->node_y; err_when(vec_x==0 && vec_y==0); vec_magn = (vec_x!=0) ? abs(vec_x) : abs(vec_y); (vec_x /= vec_magn) *= move_scale; (vec_y /= vec_magn) *= move_scale; new_vec_x = curNodePtr->node_x-preNodePtr->node_x; new_vec_y = curNodePtr->node_y-preNodePtr->node_y; err_when(new_vec_x==0 && new_vec_y==0); new_vec_magn = (new_vec_x!=0) ? abs(new_vec_x) : abs(new_vec_y); (new_vec_x /= new_vec_magn) *= move_scale; (new_vec_y /= new_vec_magn) *= move_scale; //----------------------------------------------// // (1) same direction //----------------------------------------------// if(vec_x==new_vec_x && vec_y==new_vec_y) { preNodePtr = curNodePtr; curNodePtr++; err_when(oldPreNodePtr->node_x==preNodePtr->node_x && oldPreNodePtr->node_y==preNodePtr->node_y); continue; } //----------------------------------------------// // (2) reverse direction //----------------------------------------------// if(vec_x==-new_vec_x && vec_y==-new_vec_y) { //--- old vector magnitude != new vector magnitude ----// if(vec_magn!=new_vec_magn) { preNodePtr = curNodePtr; curNodePtr++; err_when(i+1!=resultNodeNum && preNodePtr->node_x==curNodePtr->node_x && preNodePtr->node_y==curNodePtr->node_y); } else if(i+2node_x==preNodePtr->node_x && oldPreNodePtr->node_y==preNodePtr->node_y); continue; } result_vec_x = vec_x+new_vec_x; result_vec_y = vec_y+new_vec_y; err_when(result_vec_x%2 || result_vec_y%2); necessaryPoint = 0; //----------------------------------------------// // (3) turn 45 degree //----------------------------------------------// if(abs(result_vec_x)<=move_scale && abs(result_vec_y)<=move_scale && (result_vec_x==0 || result_vec_y==0)) { err_when(result_vec_x>=2*move_scale || result_vec_y>=2*move_scale); if((vec_x==0 || vec_y==0) && vec_magn>move_scale) { //-------------------------------------------------------------------------------------------// // check one more point if the entering vector direction is horizontal or vertical //-------------------------------------------------------------------------------------------// tempXLoc = preNodePtr->node_x - 2*vec_x; tempYLoc = preNodePtr->node_y - 2*vec_y; tempVectorX = vec_x + result_vec_x; tempVectorY = vec_y + result_vec_y; err_when((tempXLoc+tempVectorX/2)%2==0 && (tempYLoc+tempVectorY/2)%2==0); if(can_walk(tempXLoc+tempVectorX/2, tempYLoc+tempVectorY/2)) { //------- checking for the farther point -------// if(vec_magn>2*move_scale) // add a new point { oldPreNodePtr->node_x = tempXLoc; oldPreNodePtr->node_y = tempYLoc; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } } else if(can_walk(preNodePtr->node_x+(new_vec_x-vec_x)/2, preNodePtr->node_y+(new_vec_y-vec_y)/2)) { //-------------------------------------------------------------------------------------------// // 1) the vector entering direction is not horizontal or vetical (only one can be processed), or // 2) the vector entering direction is matched, but vec_magn==move_scale //-------------------------------------------------------------------------------------------// if(vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x-vec_x; oldPreNodePtr->node_y = preNodePtr->node_y-vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } } else necessaryPoint = 1; //--- failure checking in the near point ----// } else { //------------------------------------------------------------------------------------// // 1) the vector direction is not horizontal or vertical (only one step is checked), or // 2) the direction is matched but vec_magn==move_scale //------------------------------------------------------------------------------------// if(can_walk(preNodePtr->node_x+(new_vec_x-vec_x)/2, preNodePtr->node_y+(new_vec_y-vec_y)/2)) { if(vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x-vec_x; oldPreNodePtr->node_y = preNodePtr->node_y-vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } } else necessaryPoint = 1; } if(!necessaryPoint) { if(new_vec_magn>move_scale) { preNodePtr->node_x += new_vec_x; preNodePtr->node_y += new_vec_y; debug_reuse_check_xy_magn(preNodePtr->node_x, preNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; count++; oldPreNodePtr = preNodePtr; } preNodePtr = curNodePtr; curNodePtr++; changed++; continue; } } //----------------------------------------------// // (4) turn 90 degree //----------------------------------------------// if(!necessaryPoint && vec_x*new_vec_x+vec_y*new_vec_y==0) { type = (vec_x==0 || vec_y==0) ? 0 : 1; // 0 for + case, 1 for x case if(type==1) // x case { tempXLoc = preNodePtr->node_x+(new_vec_x-vec_x)/2; tempYLoc = preNodePtr->node_y+(new_vec_y-vec_y)/2; if(can_walk(tempXLoc, tempYLoc) && can_walk(tempXLoc-result_vec_x/4, tempYLoc-result_vec_y/4) && can_walk(tempXLoc+result_vec_x/4, tempYLoc+result_vec_y/4)) { if(vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x-vec_x; oldPreNodePtr->node_y = preNodePtr->node_y-vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } if(new_vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x+new_vec_x; oldPreNodePtr->node_y = preNodePtr->node_y+new_vec_y; err_when(oldPreNodePtr->node_x==curNodePtr->node_x && oldPreNodePtr->node_y==curNodePtr->node_y); err_when(oldPreNodePtr->node_x==preNodePtr->node_x && oldPreNodePtr->node_y==preNodePtr->node_y); debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } preNodePtr = curNodePtr; curNodePtr++; } else necessaryPoint = 1; } else // + case { tempVectorX = new_vec_x-vec_x; tempVectorY = new_vec_y-vec_y; tempXLoc = preNodePtr->node_x+tempVectorX/2; tempYLoc = preNodePtr->node_y+tempVectorY/2; err_when(tempXLoc%2==0 || tempYLoc%2==0); if(can_walk(tempXLoc, tempYLoc)) { if(vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x-vec_x; oldPreNodePtr->node_y = preNodePtr->node_y-vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } if(new_vec_magn>move_scale) { oldPreNodePtr->node_x = preNodePtr->node_x+new_vec_x; oldPreNodePtr->node_y = preNodePtr->node_y+new_vec_y; debug_reuse_check_xy_magn(oldPreNodePtr->node_x, oldPreNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = oldPreNodePtr->node_x; writeNodePtr->node_y = oldPreNodePtr->node_y; count++; } preNodePtr = curNodePtr; curNodePtr++; } else necessaryPoint = 1; } if(!necessaryPoint) { changed++; continue; } } //--------------------------------------------------// // (5) this point is necessary for the reuse-path //--------------------------------------------------// debug_reuse_check_xy_magn(preNodePtr->node_x, preNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; count++; oldPreNodePtr = preNodePtr; preNodePtr = curNodePtr; curNodePtr++; err_when(oldPreNodePtr->node_x==preNodePtr->node_x && oldPreNodePtr->node_y==preNodePtr->node_y); }while(++inode_x, preNodePtr->node_y, writeNodePtr->node_x, writeNodePtr->node_y);//**** debug checking writeNodePtr++; //------- write the end node -----------// writeNodePtr->node_x = preNodePtr->node_x; writeNodePtr->node_y = preNodePtr->node_y; count++; resultNodeNum = count; mem_del(resultPath); resultPath = wellShapedNodePtr; wellShapedNodePtr = NULL; } } #ifdef DEBUG //------------------------------------------------------------------------// // used to debug for the path of UNIT_SEA //------------------------------------------------------------------------// if(mobile_type==UNIT_SEA && resultNodeNum>1) { ResultNode *debugPtr1 = resultPath; ResultNode *debugPtr2 = resultPath+1; int di=1, dj, dvecX, dvecY, magn; while(dinode_x-debugPtr1->node_x; dvecY = debugPtr2->node_y-debugPtr1->node_y; magn = (abs(dvecX) > abs(dvecY)) ? abs(dvecX) : abs(dvecY); dvecX /= magn; dvecY /= magn; for(dj=1; dj<=magn; dj++) err_when(!world.get_loc(debugPtr1->node_x+dvecX*dj, debugPtr1->node_y+dvecY*dj)->sailable()); di++; debugPtr1++; debugPtr2++; } } #endif return resultPath; } //--------- End of function SeekPathReuse::smooth_path2 ---------//