123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816 |
- /*
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
- #include <OSPREUSE.h>
- #include <OUNIT.h>
- #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; i<nodeCount; i++)
- {
- err_when(mobile_type!=UNIT_LAND && (curNodePtr->node_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+2<resultNodeNum) //------ not the end of the array ------//
- {
- //------------ both magnitudes are equal ----------//
- oldPreNodePtr = curNodePtr;
- preNodePtr = oldPreNodePtr+1;
- curNodePtr = preNodePtr+1;
- changed++;
- i++;
- }
- else if(i+1<resultNodeNum)
- {
- preNodePtr = curNodePtr+1; // for writing the last node
- changed++;
- i++;
- }
- else
- break;
- err_when(oldPreNodePtr->node_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(++i<resultNodeNum);
-
- debug_reuse_check_xy_magn(preNodePtr->node_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(di<resultNodeNum)
- {
- dvecX = debugPtr2->node_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+2<resultNodeNum) //------ not the end of the array ------//
- {
- //------------ both magnitudes are equal ----------//
- oldPreNodePtr = curNodePtr;
- preNodePtr = oldPreNodePtr+1;
- curNodePtr = preNodePtr+1;
- changed++;
- i++;
- }
- else if(i+1<resultNodeNum)
- {
- preNodePtr = curNodePtr+1; // for writing the last node
- changed++;
- i++;
- }
- else
- break;
- err_when(oldPreNodePtr->node_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(++i<resultNodeNum);
-
- debug_reuse_check_xy_magn(preNodePtr->node_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(di<resultNodeNum)
- {
- dvecX = debugPtr2->node_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 ---------//
|