OUNITAM.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : OUNITAM.CPP
  21. //Description : Object UnitArray - part 2
  22. //
  23. // For the detail, see ounitam.txt
  24. #include <math.h>
  25. #include <ALL.h>
  26. #include <OVGA.h>
  27. #include <OSYS.h>
  28. #include <OSTR.h>
  29. #include <OREMOTE.h>
  30. #include <OWORLD.h>
  31. #include <OTERRAIN.h>
  32. #include <OUNIT.h>
  33. #ifdef NO_DEBUG_UNIT
  34. #undef err_when
  35. #undef err_here
  36. #undef err_if
  37. #undef err_else
  38. #undef err_now
  39. #define err_when(cond)
  40. #define err_here()
  41. #define err_if(cond)
  42. #define err_else
  43. #define err_now(msg)
  44. #undef DEBUG
  45. #endif
  46. //----------- Define static variables -----------//
  47. //------ static variables for all actions -------//
  48. short UnitArray::selected_land_unit_count;
  49. short UnitArray::selected_sea_unit_count;
  50. short UnitArray::selected_air_unit_count;
  51. short *UnitArray::selected_land_unit_array=NULL;
  52. short *UnitArray::selected_sea_unit_array=NULL;
  53. short *UnitArray::selected_air_unit_array=NULL;
  54. //------ static variables for movement -------//
  55. static short square_size, not_tested_loc, rec_height, rec_width;
  56. static int move_scale; // use integer for intrgral division
  57. static int x, y;
  58. static short lower_right_case, upper_left_case; // indicate which case should be used
  59. static int *distance, *sorted_member, *sorted_distance;
  60. static char *done_flag;
  61. //static int rec_x1, rec_y1, rec_x2, rec_y2; // for bondary, corner improvement
  62. static short *filtering_unit_array;
  63. static int filtering_unit_count;
  64. static short *filtered_unit_array;
  65. static int filtered_unit_count;
  66. //-------------- define static functions -------------//
  67. static int cal_rectangle_lower_right_x(int refXLoc)
  68. {
  69. // the rule: refXLoc + (rec_width/(move_scale*2))*move_scale
  70. if(move_scale==1)
  71. return refXLoc + rec_width/2;
  72. else // move_scale == 2
  73. return refXLoc + (rec_width/4)*2;
  74. }
  75. static int cal_rectangle_lower_right_y(int refYLoc)
  76. {
  77. // the rule: refYLoc + ((rec_height-move_scale)/(move_scale*2))*move_scale
  78. if(move_scale==1)
  79. return refYLoc + (rec_height-1)/2;
  80. else // move_scale == 2
  81. return refYLoc + ((rec_height-2)/4)*2;
  82. }
  83. static int cal_rectangle_upper_left_x(int refXLoc)
  84. {
  85. // the rule: refXLoc - ((rec_width-move_scale)/(move_scale*2))*move_scale
  86. if(move_scale==1)
  87. return refXLoc - (rec_width-1)/2;
  88. else // move_scale == 2
  89. return refXLoc - ((rec_width-2)/4)*2;
  90. }
  91. static int cal_rectangle_upper_left_y(int refYLoc)
  92. {
  93. // the rule: refYLoc - (rec_height/(move_scale*2))*move_scale
  94. if(move_scale==1)
  95. return refYLoc - rec_height/2;
  96. else // move_scale == 2
  97. return refYLoc - (rec_height/4)*2;
  98. }
  99. //--------- Begin of function UnitArray::move_to ---------//
  100. //
  101. // Order the unit to move to a specific location following the
  102. // shortest path.
  103. //
  104. // <int> destXLoc, destYLoc - the location of the destination.
  105. // <int> divided - whether the units are divided by their mobile type
  106. // <short*> selectedUnitArray - an array of recno of selected units.
  107. // <int> selectedCount - no. of selected units.
  108. // [char] remoteAction - whether this is an action carried out by a remote machine or not.
  109. // (default: 0)
  110. //
  111. // Note: the caller function must make sure all units in selectedUnitArray are validate (non-deleted)
  112. //
  113. void UnitArray::move_to(int destXLoc, int destYLoc, int divided, short* selectedUnitArray, int selectedCount, char remoteAction)
  114. {
  115. err_when(destXLoc<0 || destYLoc<0 || destXLoc>MAX_WORLD_X_LOC-1 || destYLoc>MAX_WORLD_Y_LOC-1);
  116. //-------- if it's a multiplayer game --------//
  117. if( !remoteAction && remote.is_enable() )
  118. {
  119. short* shortPtr = (short*) remote.new_send_queue_msg(MSG_UNIT_MOVE,
  120. sizeof(short) * (4+selectedCount) );
  121. shortPtr[0] = destXLoc;
  122. shortPtr[1] = destYLoc;
  123. shortPtr[2] = selectedCount;
  124. shortPtr[3] = divided;
  125. memcpy( shortPtr+4, selectedUnitArray, sizeof(short) * selectedCount );
  126. }
  127. else
  128. {
  129. err_when( selectedCount > 10000 ); // error
  130. if(!divided)
  131. {
  132. //----------- divide units ------------//
  133. divide_array(destXLoc, destYLoc, selectedUnitArray, selectedCount);
  134. //---------- process group move --------------//
  135. // ##### patch begin Gilbert 18/8 ######//
  136. if(selected_land_unit_count)
  137. move_to(destXLoc, destYLoc, 1, selected_land_unit_array, selected_land_unit_count, COMMAND_AUTO);
  138. if(selected_sea_unit_count)
  139. {
  140. Location *locPtr = world.get_loc(destXLoc, destYLoc);
  141. if(terrain_res[locPtr->terrain_id]->average_type == TERRAIN_OCEAN)
  142. move_to(destXLoc, destYLoc, 1, selected_sea_unit_array, selected_sea_unit_count, COMMAND_AUTO);
  143. else
  144. ship_to_beach(destXLoc, destYLoc, 1, selected_sea_unit_array, selected_sea_unit_count, COMMAND_AUTO);
  145. }
  146. if(selected_air_unit_count)
  147. move_to(destXLoc, destYLoc, 1, selected_air_unit_array, selected_air_unit_count, COMMAND_AUTO);
  148. // ##### patch end Gilbert 18/8 ######//
  149. //---------------- deinit static parameters ------------------//
  150. selected_land_unit_count = selected_sea_unit_count = selected_air_unit_count = 0;
  151. mem_del(selected_land_unit_array);
  152. mem_del(selected_sea_unit_array);
  153. mem_del(selected_air_unit_array);
  154. return;
  155. }
  156. else
  157. {
  158. //---------------------------------------------------------//
  159. // set the unit_group_id
  160. //---------------------------------------------------------//
  161. Unit* unitPtr;
  162. DWORD curGroupId = unit_array.cur_group_id++;
  163. for(int k=0; k<selectedCount; k++)
  164. {
  165. unitPtr = (Unit*) get_ptr(selectedUnitArray[k]);
  166. err_when(!unitPtr);
  167. err_when(!unitPtr->is_visible() || unitPtr->hit_points<=0);
  168. unitPtr->unit_group_id = curGroupId;
  169. unitPtr->action_mode = ACTION_MOVE;
  170. unitPtr->action_para = 0;
  171. if(unitPtr->action_mode2!=ACTION_MOVE)
  172. {
  173. unitPtr->action_mode2 = ACTION_MOVE;
  174. unitPtr->action_para2 = 0;
  175. unitPtr->action_x_loc2 = unitPtr->action_y_loc2 = -1;
  176. }// else keep the data to check whether same action mode is ordered
  177. }
  178. //--------------------------------------------------------------//
  179. // if only the leader unit is moving, no need to use formation
  180. // movement although the button is pushed
  181. //--------------------------------------------------------------//
  182. if(selectedCount==1)
  183. {
  184. unitPtr = (Unit*) get_ptr(selectedUnitArray[0]);
  185. unitPtr->move_to(destXLoc, destYLoc, 1);
  186. }
  187. else
  188. {
  189. Unit *firstUnitPtr = operator[](selectedUnitArray[0]);
  190. if(firstUnitPtr->mobile_type==UNIT_LAND)
  191. {
  192. move_to_now_with_filter(destXLoc, destYLoc, selectedUnitArray, selectedCount);
  193. seek_path.set_sub_mode(); // reset sub_mode searching
  194. seek_path_reuse.set_sub_mode(); //------ reset sub mode of path reuse searching
  195. }
  196. else
  197. move_to_now_with_filter(destXLoc, destYLoc, selectedUnitArray, selectedCount);
  198. }
  199. }
  200. }
  201. }
  202. //----------- End of function UnitArray::move_to -----------//
  203. //----------Begin of function UnitArray::move_to_now_with_filter------------//
  204. // the selected units may be in different territory. Group them by their region id
  205. // and process searching for each group
  206. //
  207. // <int> destX - the x location to move to
  208. // <int> destY - the y location to move to
  209. // <short*> selectedUnitArray - recno. of selected units
  210. // <int> selectedCount - num of selected units
  211. //
  212. void UnitArray::move_to_now_with_filter(int destX, int destY, short* selectedUnitArray, int selectedCount)
  213. {
  214. int destRegionId = world.get_loc(destX, destY)->region_id;
  215. Unit *unitPtr = operator[](selectedUnitArray[0]);
  216. //-------------- no filtering for unit air --------------------------//
  217. if(unitPtr->mobile_type==UNIT_AIR)
  218. {
  219. move_to_now(destX, destY, selectedUnitArray, selectedCount);
  220. return;
  221. }
  222. //----------------- init data structure --------------//
  223. int arraySize = sizeof(short)*selectedCount;
  224. filtered_unit_array = (short*) mem_add(arraySize);
  225. filtering_unit_array = (short*) mem_add(arraySize);
  226. memcpy(filtering_unit_array, selectedUnitArray, arraySize);
  227. filtering_unit_count = selectedCount;
  228. int unprocessCount = selectedCount;
  229. int filterRegionId = destRegionId;
  230. int filterDestX = destX, filterDestY = destY;
  231. int loopCount, filteringCount, i;
  232. //-------------------------------------------------------------------------------//
  233. // group the unit by their region id and process group searching for each group
  234. //-------------------------------------------------------------------------------//
  235. for(loopCount=0; loopCount<=unprocessCount; loopCount++) // checking for unprocessCount+1, plus one for the case that unit not on the same territory of destination
  236. {
  237. memset(filtered_unit_array, 0, arraySize);
  238. filtered_unit_count = 0;
  239. filteringCount = filtering_unit_count;
  240. filtering_unit_count = 0;
  241. //-------------- filter for filterRegionId --------------//
  242. for(i=0; i<filteringCount; i++)
  243. {
  244. unitPtr = operator[](filtering_unit_array[i]);
  245. if(world.get_loc(unitPtr->next_x_loc(), unitPtr->next_y_loc())->region_id==filterRegionId)
  246. filtered_unit_array[filtered_unit_count++] = filtering_unit_array[i];
  247. else
  248. filtering_unit_array[filtering_unit_count++] = filtering_unit_array[i];
  249. }
  250. //---- process for filtered_unit_array and prepare for looping ----//
  251. if(filtered_unit_count)
  252. move_to_now(filterDestX, filterDestY, filtered_unit_array, filtered_unit_count);
  253. if(!filtering_unit_count)
  254. break;
  255. //---------------- update parameters for next checking ------------------//
  256. unitPtr = operator[](filtering_unit_array[0]);
  257. filterRegionId = world.get_loc(unitPtr->next_x_loc(), unitPtr->next_y_loc())->region_id;
  258. filterDestX = destX;
  259. filterDestY = destY;
  260. unitPtr->different_territory_destination(filterDestX, filterDestY); // reference parameters to get the location the units should move to
  261. }
  262. mem_del(filtered_unit_array);
  263. mem_del(filtering_unit_array);
  264. }
  265. //----------- End of function UnitArray::move_to_now_with_filter -----------//
  266. //--------- Begin of function UnitArray::move_to_now ---------//
  267. //
  268. // Order the unit to move to a specific location following the
  269. // shortest path.
  270. //
  271. // <int> destXLoc, destYLoc - the location of the destination.
  272. // <short*> selectedUnitArray - an array of recno of selected units.
  273. // <int> selectedCount - no. of selected units.
  274. //
  275. void UnitArray::move_to_now(int destXLoc, int destYLoc, short* selectedUnitArray, int selectedCount)
  276. {
  277. err_when(destXLoc<0 || destYLoc<0 || destXLoc>=MAX_WORLD_X_LOC || destYLoc>=MAX_WORLD_Y_LOC);
  278. err_when( selectedCount > 10000 );
  279. //------------ define vars -----------------------//
  280. int unprocessCount;// = selectedCount; // num. of unprocessed sprite
  281. int k; // for counting
  282. short vecX, vecY; // used to reset x, y
  283. short oddCount, evenCount;
  284. int j;
  285. Unit* unitPtr = unit_array[selectedUnitArray[0]];
  286. DWORD curGroupId = unitPtr->unit_group_id;
  287. int mobileType = unitPtr->mobile_type;
  288. Location *worldLocMatrix=world.loc_matrix, *locPtr;
  289. //int sizeOneSelectedCount=0, sizeTwoSelectedCount=0;
  290. int sizeOneSelectedCount = selectedCount;
  291. //---------- set Unit::unit_group_id and count the unit by size ----------//
  292. int i;
  293. for( i=0 ; i<selectedCount ; i++ )
  294. {
  295. unitPtr = operator[](selectedUnitArray[i]);
  296. err_when(unitPtr->cur_action==SPRITE_IDLE && (unitPtr->cur_x!=unitPtr->next_x || unitPtr->cur_y!=unitPtr->next_y));
  297. err_when(unitPtr->action_para); // action_para should be set to zero in move_to()
  298. if(unitPtr->cur_action==SPRITE_ATTACK)
  299. unitPtr->stop();
  300. err_when(unitPtr->cur_action==SPRITE_ATTACK && unitPtr->action_para==0);
  301. if(unitPtr->cur_action==SPRITE_IDLE)
  302. unitPtr->set_ready();
  303. /*switch(unitPtr->sprite_info->loc_width)
  304. {
  305. case 1: sizeOneSelectedCount++;
  306. break;
  307. case 2: sizeTwoSelectedCount++;
  308. break;
  309. default: err_here();
  310. break;
  311. }*/
  312. }
  313. unprocessCount = sizeOneSelectedCount;
  314. //---- construct array to store size one selected unit ----//
  315. short* selectedSizeOneUnitArray;
  316. if(sizeOneSelectedCount)
  317. {
  318. selectedSizeOneUnitArray = (short*)mem_add(sizeof(short)*sizeOneSelectedCount);
  319. memset(selectedSizeOneUnitArray, 0, sizeof(short)*sizeOneSelectedCount);
  320. for(i=0, k=0; i<selectedCount && unprocessCount; i++)
  321. {
  322. unitPtr = operator[](selectedUnitArray[i]);
  323. if(unitPtr->sprite_info->loc_width==1)
  324. {
  325. selectedSizeOneUnitArray[k++] = selectedUnitArray[i];
  326. unprocessCount--;
  327. }
  328. }
  329. }
  330. unprocessCount = sizeOneSelectedCount;
  331. //----------- variables initialization ---------------//
  332. int destX, destY;
  333. if(mobileType==UNIT_LAND)
  334. {
  335. x = destX = destXLoc;
  336. y = destY = destYLoc;
  337. move_scale = 1;
  338. }
  339. else // UNIT_AIR, UNIT_SEA
  340. {
  341. x = destX = (destXLoc/2)*2;
  342. y = destY = (destYLoc/2)*2;
  343. move_scale = 2;
  344. }
  345. //if(sizeOneSelectedCount)
  346. //{
  347. //----- initialize parameters and construct data structure -----//
  348. oddCount =1;
  349. evenCount = 3;
  350. square_size = not_tested_loc = lower_right_case = upper_left_case = 0;
  351. distance = (int*)mem_add(sizeof(int)*sizeOneSelectedCount); // used in the function construct_sorted_array and this function,
  352. memset(distance, 0, sizeof(int)*sizeOneSelectedCount); // and allocate/free the memory in this function
  353. sorted_distance = (int*)mem_add(sizeof(int)*sizeOneSelectedCount);
  354. memset(sorted_distance, 0, sizeof(int)*sizeOneSelectedCount);
  355. sorted_member = (int*)mem_add(sizeof(int)*sizeOneSelectedCount);
  356. memset(sorted_member, 0, sizeof(int)*sizeOneSelectedCount);
  357. done_flag = (char*)mem_add(sizeof(char)*sizeOneSelectedCount);
  358. memset(done_flag, 0, sizeof(char)*sizeOneSelectedCount);
  359. //--- calculate the rectangle size used to allocate space for the sprites----//
  360. unprocessCount = sizeOneSelectedCount;
  361. while(unprocessCount)
  362. {
  363. //=============================
  364. // process odd size square
  365. //=============================
  366. vecX = short(oddCount/4)*move_scale;
  367. vecY = vecX;
  368. k = 0;
  369. for(j=0; j<oddCount && unprocessCount; j++)
  370. {
  371. x = destX+vecX;
  372. y = destY+vecY;
  373. if(x>=0 && y>=0 && x<MAX_WORLD_X_LOC && y<MAX_WORLD_Y_LOC)
  374. {
  375. if( worldLocMatrix[y*MAX_WORLD_X_LOC+x].is_unit_group_accessible(mobileType, curGroupId) )
  376. unprocessCount--;
  377. }
  378. if(k++ < int(oddCount/2)) // reset vecX, vecY
  379. vecX -= move_scale;
  380. else
  381. vecY -= move_scale;
  382. }
  383. square_size+=move_scale;
  384. if(j<oddCount)
  385. not_tested_loc = oddCount-j;
  386. oddCount+=4;
  387. if(unprocessCount)
  388. {
  389. //=============================
  390. // process even size square
  391. //=============================
  392. vecY = (-short(evenCount/4)-1)*move_scale;
  393. vecX = vecY+move_scale;
  394. k = 0;
  395. for(j=0; j<evenCount && unprocessCount; j++)
  396. {
  397. x = destX+vecX;
  398. y = destY+vecY;
  399. if(x>=0 && y>=0 && x<MAX_WORLD_X_LOC && y<MAX_WORLD_Y_LOC)
  400. {
  401. if(worldLocMatrix[y*MAX_WORLD_X_LOC+x].is_unit_group_accessible(mobileType, curGroupId) )
  402. unprocessCount--;
  403. }
  404. if(k++ < int(evenCount/2)) // reset vecX, vecY
  405. vecX += move_scale;
  406. else
  407. vecY += move_scale;
  408. }
  409. square_size+=move_scale;
  410. if(j<evenCount)
  411. not_tested_loc = evenCount-j;
  412. evenCount+=4;
  413. }
  414. }
  415. rec_height = rec_width = square_size; // get the height and width of the rectangle
  416. if(not_tested_loc >= (square_size/move_scale))
  417. rec_width -= move_scale;
  418. //--- decide to use upper_left_case or lower_right_case, however, it maybe changed for boundary improvement----//
  419. x = cal_rectangle_lower_right_x(destX);
  420. y = cal_rectangle_lower_right_y(destY);
  421. for(i=0; i<sizeOneSelectedCount; i++)
  422. {
  423. unitPtr = (Unit*) get_ptr(selectedSizeOneUnitArray[i]);
  424. if(unitPtr->next_y_loc()<y) // lower_right_case or upper_left_case
  425. lower_right_case++;
  426. else if(unitPtr->next_y_loc()>y)
  427. upper_left_case++;
  428. }
  429. if(lower_right_case==upper_left_case) // in case both values are equal, check by upper_left_case
  430. {
  431. x = cal_rectangle_upper_left_x(destX);
  432. y = cal_rectangle_upper_left_y(destY);
  433. lower_right_case = upper_left_case = 0;
  434. for(i=0; i<sizeOneSelectedCount; i++)
  435. {
  436. unitPtr = (Unit*) get_ptr(selectedSizeOneUnitArray[i]);
  437. if(unitPtr->next_y_loc()<y) // lower_right_case or upper_left_case
  438. lower_right_case++;
  439. else if(unitPtr->next_y_loc()>y)
  440. upper_left_case++;
  441. }
  442. }
  443. //------------ determine x, y and lower_right_case/upper_left_case-----------//
  444. determine_position_to_construct_table(selectedCount, destX, destY, mobileType);
  445. err_when(x<0 || y<0 || x>=MAX_WORLD_X_LOC || y>=MAX_WORLD_Y_LOC);
  446. //------------ construct a table to store distance -------//
  447. construct_sorted_array(selectedSizeOneUnitArray, sizeOneSelectedCount); // distance and sorted_member should be initialized first
  448. err_when(x<0 || y<0 || x>=MAX_WORLD_X_LOC || y>=MAX_WORLD_Y_LOC);
  449. //------------ process the movement -----------//
  450. unprocessCount = sizeOneSelectedCount;//selectedCount;
  451. k=0;
  452. //-******************* auto correct ***********************-//
  453. int autoCorrectStartX = x;
  454. int autoCorrectStartY = y;
  455. //-******************* auto correct ***********************-//
  456. if(lower_right_case >= upper_left_case)
  457. {
  458. while(unprocessCount)
  459. {
  460. locPtr = worldLocMatrix+y*MAX_WORLD_X_LOC+x;
  461. for(i=x; i>x-rec_width && unprocessCount; i-=move_scale, locPtr-=move_scale)
  462. {
  463. if(locPtr->is_unit_group_accessible(mobileType, curGroupId))
  464. {
  465. do
  466. {
  467. unitPtr = (Unit*) get_ptr(selectedSizeOneUnitArray[sorted_member[k++]]);
  468. }while(unitPtr->sprite_info->loc_width>1);
  469. err_when(k>sizeOneSelectedCount);
  470. if(sizeOneSelectedCount>1)
  471. {
  472. if(unprocessCount==sizeOneSelectedCount) // the first unit to move
  473. {
  474. unitPtr->move_to(i, y, 1, 4, 0, sizeOneSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_INITIAL);
  475. if(unitPtr->mobile_type==UNIT_LAND && unitPtr->nation_recno)
  476. unitPtr->select_search_sub_mode(unitPtr->next_x_loc(), unitPtr->next_y_loc(), i, y, unitPtr->nation_recno, SEARCH_MODE_REUSE);
  477. unitPtr->move_to(i, y, 1, 4, 0, sizeOneSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_FIRST_SEEK);
  478. }
  479. else
  480. {
  481. err_when(unprocessCount==sizeOneSelectedCount);
  482. if(unitPtr->mobile_type==UNIT_LAND && unitPtr->nation_recno)
  483. unitPtr->select_search_sub_mode(unitPtr->next_x_loc(), unitPtr->next_y_loc(), i, y, unitPtr->nation_recno, SEARCH_MODE_REUSE);
  484. unitPtr->move_to(i, y, 1, 4, 0, sizeOneSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_SEARCH);
  485. }
  486. }
  487. else
  488. unitPtr->move_to(i, y, 1);
  489. unprocessCount--;
  490. }
  491. }
  492. y-=move_scale;
  493. //-******************* auto correct ***********************-//
  494. #ifdef DEBUG
  495. err_when(unprocessCount && y<0);
  496. #else
  497. if(unprocessCount && y<0)
  498. y = autoCorrectStartY;
  499. #endif
  500. //-******************* auto correct ***********************-//
  501. }
  502. }
  503. else // upper_left_case
  504. {
  505. while(unprocessCount)
  506. {
  507. locPtr = worldLocMatrix+y*MAX_WORLD_X_LOC+x;
  508. for(i=x; i<x+rec_width && unprocessCount; i+=move_scale, locPtr+=move_scale)
  509. {
  510. if(locPtr->is_unit_group_accessible(mobileType, curGroupId))
  511. {
  512. do
  513. {
  514. unitPtr = (Unit*) get_ptr(selectedSizeOneUnitArray[sorted_member[k++]]);
  515. }while(unitPtr->sprite_info->loc_width>1);
  516. err_when(k>sizeOneSelectedCount);
  517. if(sizeOneSelectedCount>1)
  518. {
  519. if(unprocessCount==sizeOneSelectedCount) // the first unit to move
  520. {
  521. unitPtr->move_to(i, y, 1, 4, 0, sizeOneSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_INITIAL);
  522. if(unitPtr->mobile_type==UNIT_LAND && unitPtr->nation_recno)
  523. unitPtr->select_search_sub_mode(unitPtr->next_x_loc(), unitPtr->next_y_loc(), i, y, unitPtr->nation_recno, SEARCH_MODE_REUSE);
  524. unitPtr->move_to(i, y, 1, 4, 0, sizeOneSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_FIRST_SEEK);
  525. }
  526. else
  527. {
  528. err_when(unprocessCount==sizeOneSelectedCount);
  529. if(unitPtr->mobile_type==UNIT_LAND && unitPtr->nation_recno)
  530. unitPtr->select_search_sub_mode(unitPtr->next_x_loc(), unitPtr->next_y_loc(), i, y, unitPtr->nation_recno, SEARCH_MODE_REUSE);
  531. unitPtr->move_to(i, y, 1, 4, 0, sizeOneSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_SEARCH);
  532. }
  533. }
  534. else
  535. unitPtr->move_to(i, y, 1);
  536. unprocessCount--;
  537. }
  538. }
  539. y+=move_scale;
  540. //-******************* auto correct ***********************-//
  541. #ifdef DEBUG
  542. err_when(unprocessCount && y>=MAX_WORLD_Y_LOC);
  543. #else
  544. if(unprocessCount && y>=MAX_WORLD_Y_LOC)
  545. y = autoCorrectStartY;
  546. #endif
  547. //-******************* auto correct ***********************-//
  548. }
  549. }
  550. //---------------- destruct data structure --------------//
  551. mem_del(done_flag);
  552. mem_del(sorted_distance);
  553. mem_del(sorted_member);
  554. mem_del(distance);
  555. mem_del(selectedSizeOneUnitArray);
  556. //}// end if (sizeOneSelectedCount)
  557. /*
  558. //=============================================================================//
  559. //----- order sprite with size two to move to a specified position ------------//
  560. //=============================================================================//
  561. int sizeTwoUnprocessCount = sizeTwoSelectedCount;
  562. int surX, surY, suaCount=0;
  563. char w, h, blocked=0;
  564. if(sizeOneSelectedCount) // mix, size one units have processed
  565. {
  566. if(rec_width>square_size)
  567. square_size = rec_width;
  568. if(rec_height>square_size)
  569. square_size = rec_height;
  570. square_size = ((square_size+1)/2)<<1; // change to multiply of two
  571. rec_width = rec_height = square_size;
  572. x = destX-rec_width/2+1;
  573. y = destY-rec_height/2;
  574. }
  575. else // all are size 2 units
  576. {
  577. //-***************** testing ********************-//
  578. err_here();
  579. //-***************** testing ********************-//
  580. square_size = rec_width = rec_height = 2;
  581. x = destX;
  582. y = destY;
  583. if(x<0)
  584. x = 0;
  585. else if(x>=MAX_WORLD_X_LOC-1)
  586. x = MAX_WORLD_X_LOC-2;
  587. if(y<0)
  588. y = 0;
  589. else if(y>=MAX_WORLD_Y_LOC-1)
  590. y = MAX_WORLD_Y_LOC-2;
  591. blocked = 0;
  592. for(h=0, surY=y; h<2 && !blocked; h++, surY++)
  593. {
  594. for(w=0, surX=x; w<2 && !blocked; w++, surX++)
  595. {
  596. locPtr = worldLocMatrix+surY*MAX_WORLD_X_LOC+surX;
  597. blocked = !locPtr->is_unit_group_accessible(mobileType, curGroupId);
  598. }
  599. }
  600. if(!blocked)
  601. {
  602. do
  603. {
  604. unitPtr = (Unit*) get_ptr(selectedUnitArray[suaCount++]);
  605. }while(unitPtr->sprite_info->loc_width<2);
  606. if(sizeTwoSelectedCount>1)
  607. {
  608. unitPtr->move_to(x, y, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_INITIAL);
  609. unitPtr->move_to(x, y, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_FIRST_SEEK);
  610. }
  611. else
  612. unitPtr->move_to(x, y, 1);
  613. sizeTwoUnprocessCount--;
  614. }
  615. }
  616. while(sizeTwoUnprocessCount)
  617. {
  618. //-***************** testing ********************-//
  619. err_here();
  620. //-***************** testing ********************-//
  621. int moveToX, moveToY;
  622. int boundedX, boundedY;
  623. //------------- upper edge --------------//
  624. moveToY = y-2;
  625. moveToX = x;
  626. if(moveToY>=0)
  627. {
  628. if(x+rec_width+2 > MAX_WORLD_X_LOC-2)
  629. boundedX = MAX_WORLD_X_LOC-1;
  630. else
  631. boundedX = x+rec_width+2;
  632. while(moveToX<boundedX && sizeTwoUnprocessCount)
  633. {
  634. //--------------- is the position blocked? ----------//
  635. if(moveToX>=MAX_WORLD_X_LOC-1 || moveToY>=MAX_WORLD_Y_LOC-1)
  636. blocked = 1;
  637. else
  638. {
  639. blocked = 0;
  640. for(h=0, surY=moveToY; h<2 && !blocked; h++, surY++)
  641. {
  642. for(w=0, surX=moveToX; w<2 && !blocked; w++, surX++)
  643. {
  644. locPtr = worldLocMatrix+surY*MAX_WORLD_X_LOC+surX;
  645. blocked = !locPtr->is_unit_group_accessible(mobileType, curGroupId);
  646. }
  647. }
  648. }
  649. if(!blocked)
  650. {
  651. do
  652. {
  653. unitPtr = (Unit*) get_ptr(selectedUnitArray[suaCount++]);
  654. }while(unitPtr->sprite_info->loc_width<2);
  655. if(sizeTwoSelectedCount>1)
  656. {
  657. if(sizeTwoUnprocessCount==sizeTwoSelectedCount) // the first unit to move
  658. {
  659. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_INITIAL);
  660. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_FIRST_SEEK);
  661. }
  662. else
  663. {
  664. err_if(sizeTwoUnprocessCount==sizeTwoSelectedCount)
  665. err_here();
  666. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_SEARCH);
  667. }
  668. }
  669. else
  670. unitPtr->move_to(moveToX, moveToY, 1);
  671. sizeTwoUnprocessCount--;
  672. }
  673. moveToX+=2;
  674. }
  675. }
  676. //------------- right edge --------------//
  677. moveToX = x+rec_width;
  678. moveToY = y;
  679. if(moveToX<MAX_WORLD_X_LOC-1)
  680. {
  681. if(y+rec_height+2 > MAX_WORLD_Y_LOC-2)
  682. boundedY = MAX_WORLD_Y_LOC-1;
  683. else
  684. boundedY = y+rec_height+2;
  685. while(moveToY<boundedY && sizeTwoUnprocessCount)
  686. {
  687. //--------------- is the position blocked? ----------//
  688. if(moveToX>=MAX_WORLD_X_LOC-1 || moveToY>=MAX_WORLD_Y_LOC-1)
  689. blocked = 1;
  690. else
  691. {
  692. blocked = 0;
  693. for(h=0, surY=moveToY; h<2 && !blocked; h++, surY++)
  694. {
  695. for(w=0, surX=moveToX; w<2 && !blocked; w++, surX++)
  696. {
  697. locPtr = worldLocMatrix+surY*MAX_WORLD_X_LOC+surX;
  698. blocked = !locPtr->is_unit_group_accessible(mobileType, curGroupId);
  699. }
  700. }
  701. }
  702. if(!blocked)
  703. {
  704. do
  705. {
  706. unitPtr = (Unit*) get_ptr(selectedUnitArray[suaCount++]);
  707. }while(unitPtr->sprite_info->loc_width<2);
  708. if(sizeTwoSelectedCount>1)
  709. {
  710. if(sizeTwoUnprocessCount==sizeTwoSelectedCount) // the first unit to move
  711. {
  712. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_INITIAL);
  713. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_FIRST_SEEK);
  714. }
  715. else
  716. {
  717. err_if(sizeTwoUnprocessCount==sizeTwoSelectedCount)
  718. err_here();
  719. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_SEARCH);
  720. }
  721. }
  722. else
  723. unitPtr->move_to(moveToX, moveToY, 1);
  724. sizeTwoUnprocessCount--;
  725. }
  726. moveToY+=2;
  727. }
  728. }
  729. //------------- lower edge ----------------//
  730. moveToX = x+rec_width-2;
  731. moveToY = y+rec_height;
  732. if(moveToY<MAX_WORLD_Y_LOC-1)
  733. {
  734. if(x-3 < 0)
  735. boundedX = -1;
  736. else
  737. boundedX = x-3;
  738. while(moveToX>boundedX && sizeTwoUnprocessCount)
  739. {
  740. //--------------- is the position blocked? ----------//
  741. if(moveToX>=MAX_WORLD_X_LOC-1 || moveToY>=MAX_WORLD_Y_LOC-1)
  742. blocked = 1;
  743. else
  744. {
  745. blocked = 0;
  746. for(h=0, surY=moveToY; h<2 && !blocked; h++, surY++)
  747. {
  748. for(w=0, surX=moveToX; w<2 && !blocked; w++, surX++)
  749. {
  750. locPtr = worldLocMatrix+surY*MAX_WORLD_X_LOC+surX;
  751. blocked = !locPtr->is_unit_group_accessible(mobileType, curGroupId);
  752. }
  753. }
  754. }
  755. if(!blocked)
  756. {
  757. do
  758. {
  759. unitPtr = (Unit*) get_ptr(selectedUnitArray[suaCount++]);
  760. }while(unitPtr->sprite_info->loc_width<2);
  761. if(sizeTwoSelectedCount>1)
  762. {
  763. if(sizeTwoUnprocessCount==sizeTwoSelectedCount) // the first unit to move
  764. {
  765. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_INITIAL);
  766. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_FIRST_SEEK);
  767. }
  768. else
  769. {
  770. err_if(sizeTwoUnprocessCount==sizeTwoSelectedCount)
  771. err_here();
  772. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_SEARCH);
  773. }
  774. }
  775. else
  776. unitPtr->move_to(moveToX, moveToY, 1);
  777. sizeTwoUnprocessCount--;
  778. }
  779. moveToX-=2;
  780. }
  781. }
  782. //------------- left edge ---------------//
  783. moveToX = x-2;
  784. moveToY = y+rec_height-2;
  785. if(moveToX>=0)
  786. {
  787. if(y-3 < 0)
  788. boundedY = -1;
  789. else
  790. boundedY = y-3;
  791. while(moveToY>boundedY && sizeTwoUnprocessCount)
  792. {
  793. //--------------- is the position blocked? ----------//
  794. if(moveToX>=MAX_WORLD_X_LOC-1 || moveToY>=MAX_WORLD_Y_LOC-1)
  795. blocked = 1;
  796. else
  797. {
  798. blocked = 0;
  799. for(h=0, surY=moveToY; h<2 && !blocked; h++, surY++)
  800. {
  801. for(w=0, surX=moveToX; w<2 && !blocked; w++, surX++)
  802. {
  803. locPtr = worldLocMatrix+surY*MAX_WORLD_X_LOC+surX;
  804. blocked = !locPtr->is_unit_group_accessible(mobileType, curGroupId);
  805. }
  806. }
  807. }
  808. if(!blocked)
  809. {
  810. do
  811. {
  812. unitPtr = (Unit*) get_ptr(selectedUnitArray[suaCount++]);
  813. }while(unitPtr->sprite_info->loc_width<2);
  814. if(sizeTwoSelectedCount>1)
  815. {
  816. if(sizeTwoUnprocessCount==sizeTwoSelectedCount) // the first unit to move
  817. {
  818. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_INITIAL);
  819. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_FIRST_SEEK);
  820. }
  821. else
  822. {
  823. err_if(sizeTwoUnprocessCount==sizeTwoSelectedCount)
  824. err_here();
  825. unitPtr->move_to(moveToX, moveToY, 1, 4, 0, sizeTwoSelectedCount, GENERAL_GROUP_MOVEMENT, REUSE_PATH_SEARCH);
  826. }
  827. }
  828. else
  829. unitPtr->move_to(moveToX, moveToY, 1);
  830. sizeTwoUnprocessCount--;
  831. }
  832. moveToY-=2;
  833. }
  834. }
  835. //------- reset square_size, rec_width, rec_height -----------//
  836. rec_width+=4;
  837. rec_height+=4;
  838. x-=2;
  839. y-=2;
  840. }*/
  841. }
  842. //----------- End of function UnitArray::move_to_now -----------//
  843. //----------Begin of function UnitArray::construct_sorted_array------------//
  844. //
  845. // construct a table to store the d(x,y) value from the reference(rectangule
  846. // starting) point in group movement control
  847. //
  848. // For the detail, see ounitam.txt
  849. //
  850. //
  851. // <short*> selectedUnitArray - an array of recno of selected units.
  852. // <int> selectedCount - no. of selected units.
  853. //
  854. void UnitArray::construct_sorted_array(short* selectedUnitArray, int selectedCount)
  855. {
  856. Unit* unitPtr;
  857. int min, dist; // for comparison
  858. int i, j, k;
  859. const int c = 1000; // c value for the d(x,y) function
  860. if(lower_right_case >= upper_left_case)
  861. {
  862. for(i=0; i<selectedCount; i++)
  863. {
  864. unitPtr = (Unit*) get_ptr(selectedUnitArray[i]);
  865. // d(x,y)=x+c*|y|
  866. distance[i] = MAX_WORLD_X_LOC; // to aviod -ve no. in the following line
  867. distance[i] += (x-unitPtr->cur_x_loc()+c*abs(unitPtr->cur_y_loc()-y)); // plus/minus x coord difference
  868. }
  869. }
  870. else // upper_left_case
  871. {
  872. for(i=0; i<selectedCount; i++)
  873. {
  874. unitPtr = (Unit*) get_ptr(selectedUnitArray[i]);
  875. // d(x,y)=x+c*|y|
  876. distance[i] = MAX_WORLD_X_LOC; // to aviod -ve no. in the following line
  877. distance[i] += (unitPtr->cur_x_loc()-x+c*abs(unitPtr->cur_y_loc()-y)); // plus/minus x coord difference
  878. }
  879. }
  880. //---------------------------------------------------------------//
  881. // this part of code using a technique to adjust the distance value
  882. // such that the selected group can change from lower right form
  883. // to upper left form or upper left form to lower right form in a
  884. // better way.
  885. //---------------------------------------------------------------//
  886. //------ sorting the distance and store in sortedDistance Array -------//
  887. for(j=0; j<selectedCount; j++)
  888. {
  889. min = 0xFFFFFF;
  890. for(i=0; i<selectedCount; i++)
  891. {
  892. if(done_flag[i]==0 && (dist = distance[i])<min)
  893. {
  894. min = dist;
  895. k = i;
  896. }
  897. }
  898. sorted_distance[j] = k;
  899. done_flag[k] = 1;
  900. }
  901. //----------------- find the minimum value --------------//
  902. #ifdef DEBUG
  903. min = 0xFFFFFF;
  904. for(j=0; j<selectedCount; j++)
  905. {
  906. if((dist = distance[j])<min)
  907. min = dist;
  908. }
  909. err_when(min!=distance[sorted_distance[0]]);
  910. #else
  911. min = distance[sorted_distance[0]];
  912. #endif
  913. int defArraySize = 5; //****** BUGHERE, 5 is chosen arbitrary
  914. int *leftQuotZ = (int*) mem_add(defArraySize*sizeof(int));
  915. int *rightQuotZ = (int*) mem_add(defArraySize*sizeof(int));
  916. int remainder = min%c;
  917. int index;
  918. //-- adjust the value to allow changing form between upper left and lower right shape --//
  919. for(j=0; j<defArraySize; j++)
  920. leftQuotZ[j] = rightQuotZ[j] = min-remainder;
  921. for(j=0; j<selectedCount; j++)
  922. {
  923. if((dist = distance[sorted_distance[j]]%c) < remainder)
  924. {
  925. if((index = remainder-dist) <= defArraySize) // the case can be handled by this array size
  926. {
  927. distance[sorted_distance[j]] = leftQuotZ[index-1] + dist;
  928. leftQuotZ[index-1] += c;
  929. }
  930. }
  931. else
  932. {
  933. if(dist>=remainder)
  934. {
  935. if((index = dist-remainder) < defArraySize) // the case can be handled by this array size
  936. {
  937. distance[sorted_distance[j]] = rightQuotZ[index] + dist;
  938. rightQuotZ[index] += c;
  939. }
  940. }
  941. }
  942. }
  943. mem_del(leftQuotZ);
  944. mem_del(rightQuotZ);
  945. //---------- sorting -------------//
  946. for(j=0; j<selectedCount; j++)
  947. {
  948. min = 0xFFFFFF;
  949. for(i=0; i<selectedCount; i++)
  950. {
  951. if((dist = distance[i])<min)
  952. {
  953. min = dist;
  954. k = i;
  955. }
  956. }
  957. sorted_member[j] = k;
  958. distance[k] = 0xFFFFFF;
  959. }
  960. }
  961. //--------End of function UnitArray::construct_sorted_array----------------//
  962. //--- Begin of function UnitArray::determine_position_to_construct_table ---//
  963. //
  964. // determine the position of the rectangule starting point in the two forms
  965. // (i.e. upper left case or lower right case). This point is used to indicate
  966. // the direction to fill the rectangle
  967. //
  968. // <int> destXLoc, destYLoc - the location of the destination.
  969. // <int> selectedCount - no. of selected units.
  970. //
  971. void UnitArray::determine_position_to_construct_table(int selectedCount, int destXLoc, int destYLoc, char mobileType)
  972. {
  973. //======================================================================//
  974. // boundary, corner improvement
  975. //======================================================================//
  976. int sqrtValue;
  977. //======================================================================//
  978. // lower right case
  979. //======================================================================//
  980. if(lower_right_case>=upper_left_case)
  981. {
  982. //--------- calculate x, y location for lower right case ---------//
  983. x = cal_rectangle_lower_right_x(destXLoc);
  984. y = cal_rectangle_lower_right_y(destYLoc);
  985. if(x<rec_width)
  986. {
  987. //================== left edge =================//
  988. sqrtValue = (int)sqrt(selectedCount);
  989. if(sqrtValue*sqrtValue != selectedCount)
  990. sqrtValue++;
  991. if(mobileType!=UNIT_LAND)
  992. sqrtValue = sqrtValue<<1; // change to scale 2
  993. rec_width = rec_height = sqrtValue;
  994. //------------- top left corner --------------//
  995. if(y<rec_height)
  996. {
  997. upper_left_case = lower_right_case+1;
  998. x = y = 0;
  999. }
  1000. //------------ bottom left corner ---------------//
  1001. else if(y>=MAX_WORLD_Y_LOC-move_scale)
  1002. {
  1003. if(not_tested_loc>=square_size/move_scale)
  1004. rec_width -= move_scale;
  1005. x = rec_width-move_scale;
  1006. y = MAX_WORLD_Y_LOC-move_scale;
  1007. }
  1008. //------------- just left edge -------------//
  1009. else
  1010. x = rec_width-move_scale;
  1011. }
  1012. else if(x>=MAX_WORLD_X_LOC-move_scale)
  1013. {
  1014. //============== right edge ==============//
  1015. //----------- top right corner -----------//
  1016. if(y<rec_height)
  1017. {
  1018. sqrtValue = (int)sqrt(selectedCount);
  1019. if(sqrtValue*sqrtValue != selectedCount)
  1020. sqrtValue++;
  1021. if(mobileType!=UNIT_LAND)
  1022. sqrtValue = sqrtValue<<1; // change to scale 2
  1023. rec_width = rec_height = sqrtValue;
  1024. upper_left_case = lower_right_case+1;
  1025. x = MAX_WORLD_X_LOC-rec_width;
  1026. y = 0;
  1027. }
  1028. //---------- bottom right corner ------------//
  1029. else if(y>=MAX_WORLD_Y_LOC-move_scale)
  1030. {
  1031. y = MAX_WORLD_Y_LOC-move_scale;
  1032. x = MAX_WORLD_X_LOC-move_scale;
  1033. }
  1034. //---------- just right edge ---------------//
  1035. else
  1036. {
  1037. int squareSize = square_size/move_scale;
  1038. if(squareSize*(squareSize-1)>=selectedCount)
  1039. rec_width -= move_scale;
  1040. x = MAX_WORLD_X_LOC-move_scale;
  1041. }
  1042. }
  1043. else if(y<rec_height)
  1044. {
  1045. //================= top edge ===============//
  1046. sqrtValue = (int)sqrt(selectedCount);
  1047. if(sqrtValue*sqrtValue != selectedCount)
  1048. sqrtValue++;
  1049. if(mobileType!=UNIT_LAND)
  1050. sqrtValue = sqrtValue<<1; // change to scale 2
  1051. rec_width = rec_height = sqrtValue;
  1052. upper_left_case = lower_right_case+1;
  1053. //if(mobileType==UNIT_LAND)
  1054. // x = destXLoc-((rec_width-1)/2);
  1055. //else
  1056. // x = destXLoc-(rec_width/4)*2;
  1057. x = cal_rectangle_upper_left_x(destXLoc);
  1058. y = 0;
  1059. }
  1060. else if(y>=MAX_WORLD_Y_LOC-move_scale)
  1061. {
  1062. //================== bottom edge ====================//
  1063. if(not_tested_loc>=square_size/move_scale)
  1064. rec_width += move_scale;
  1065. //if(mobileType==UNIT_LAND)
  1066. // x = destXLoc+(rec_width/2);
  1067. //else
  1068. // x = destXLoc+(rec_width/4)*2;
  1069. x = cal_rectangle_lower_right_x(destXLoc);
  1070. y = MAX_WORLD_Y_LOC-move_scale;
  1071. }
  1072. }
  1073. //======================================================================//
  1074. // upper left case
  1075. //======================================================================//
  1076. else
  1077. {
  1078. //--------- calculate x, y location for upper left case ---------//
  1079. x = cal_rectangle_upper_left_x(destXLoc);
  1080. y = cal_rectangle_upper_left_y(destYLoc);
  1081. if(x<0)
  1082. {
  1083. //================= left edge ==================//
  1084. //------------- top left corner --------------//
  1085. if(y<0)
  1086. {
  1087. sqrtValue = (int)sqrt(selectedCount);
  1088. if(sqrtValue*sqrtValue != selectedCount)
  1089. sqrtValue++;
  1090. if(mobileType!=UNIT_LAND)
  1091. sqrtValue = sqrtValue<<1; // change to scale 2
  1092. rec_width = rec_height = sqrtValue;
  1093. x = y = 0;
  1094. }
  1095. //------------- bottom left corner --------------//
  1096. else if(y+rec_height>=MAX_WORLD_Y_LOC-move_scale)
  1097. {
  1098. lower_right_case = upper_left_case+1;
  1099. x = rec_width-move_scale;
  1100. y = MAX_WORLD_Y_LOC-move_scale;
  1101. }
  1102. //------------- just left edge ------------------//
  1103. else
  1104. {
  1105. sqrtValue = (int)sqrt(selectedCount);
  1106. if(sqrtValue*sqrtValue != selectedCount)
  1107. sqrtValue++;
  1108. if(mobileType!=UNIT_LAND)
  1109. sqrtValue = sqrtValue<<1; // change to scale 2
  1110. rec_width = rec_height = sqrtValue;
  1111. x = 0;
  1112. }
  1113. }
  1114. //================ right edge ================//
  1115. else if(x+rec_width>=MAX_WORLD_X_LOC-move_scale)
  1116. {
  1117. //------------- top right corner ------------------//
  1118. if(y<0)
  1119. {
  1120. sqrtValue = (int)sqrt(selectedCount);
  1121. if(sqrtValue*sqrtValue != selectedCount)
  1122. sqrtValue++;
  1123. if(mobileType!=UNIT_LAND)
  1124. sqrtValue = sqrtValue<<1; // change to scale 2
  1125. rec_width = rec_height = sqrtValue;
  1126. x = MAX_WORLD_X_LOC-rec_width;
  1127. y = 0;
  1128. }
  1129. //------------- bottom right corner ------------------//
  1130. else if(y+rec_height>=MAX_WORLD_Y_LOC-move_scale)
  1131. {
  1132. lower_right_case = upper_left_case+1;
  1133. x = MAX_WORLD_X_LOC-move_scale;
  1134. y = MAX_WORLD_Y_LOC-move_scale;
  1135. }
  1136. //------------- just right edge ------------------//
  1137. else
  1138. {
  1139. sqrtValue = (int)sqrt(selectedCount);
  1140. if(sqrtValue*sqrtValue != selectedCount)
  1141. sqrtValue++;
  1142. if(mobileType!=UNIT_LAND)
  1143. sqrtValue = sqrtValue<<1; // change to scale 2
  1144. rec_width = rec_height = sqrtValue;
  1145. int squareSize = square_size/move_scale;
  1146. if(squareSize*(squareSize-1)>=selectedCount)
  1147. rec_width -= move_scale;
  1148. lower_right_case = upper_left_case+1;
  1149. x = MAX_WORLD_X_LOC-move_scale;
  1150. //if(mobileType==UNIT_LAND)
  1151. // y = destYLoc+((rec_height-1)/2);
  1152. //else
  1153. // y = destYLoc+((rec_height-2)/4)*2;
  1154. y = cal_rectangle_lower_right_y(destYLoc);
  1155. }
  1156. }
  1157. //================= top edge ================//
  1158. else if(y<0)
  1159. {
  1160. sqrtValue = (int)sqrt(selectedCount);
  1161. if(sqrtValue*sqrtValue != selectedCount)
  1162. sqrtValue++;
  1163. rec_width = rec_height = sqrtValue;
  1164. y = 0;
  1165. }
  1166. //================= bottom edge ================//
  1167. else if(y+rec_height>=MAX_WORLD_Y_LOC-move_scale)
  1168. {
  1169. if(not_tested_loc>=square_size)
  1170. rec_width += move_scale;
  1171. y = MAX_WORLD_Y_LOC-move_scale;
  1172. }
  1173. }
  1174. /*if(lower_right_case>=upper_left_case)
  1175. {
  1176. x = cal_rectangle_lower_right_x(destXLoc);
  1177. y = cal_rectangle_lower_right_y(destYLoc);
  1178. rec_x1 = x - rec_width + move_scale;
  1179. rec_y1 = y - rec_height + move_scale;
  1180. rec_x2 = x;
  1181. rec_y2 = y;
  1182. }
  1183. else
  1184. {
  1185. x = cal_rectangle_upper_left_x(destXLoc);
  1186. y = cal_rectangle_upper_left_y(destYLoc);
  1187. }*/
  1188. }
  1189. //--- End of function UnitArray::determine_position_to_construct_table -----//