OUNITHB.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  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 : OUNITATM.CPP
  21. //Description : Object Unit attack functions to handle blocked movement and group attacking
  22. //Owner : Alex
  23. #include <OWORLD.h>
  24. #include <OFIRM.h>
  25. #include <OTOWN.h>
  26. #include <OUNIT.h>
  27. #include <OTERRAIN.h>
  28. #ifdef NO_DEBUG_UNIT
  29. #undef err_when
  30. #undef err_here
  31. #undef err_if
  32. #undef err_else
  33. #undef err_now
  34. #define err_when(cond)
  35. #define err_here()
  36. #define err_if(cond)
  37. #define err_else
  38. #define err_now(msg)
  39. #undef DEBUG
  40. #endif
  41. //--------- Begin of function Unit::search_or_stop ---------//
  42. // process searching or stop the units
  43. //
  44. // <int> destX - x location to move to
  45. // <int> destY - y location to move to
  46. // <int> preserveAction - preserve action when calling to stop
  47. // <short> searchMode - search mode for searching
  48. // <short> miscNo - miscenllaneous information
  49. //
  50. void Unit::search_or_stop(int destX, int destY, int preserveAction, short searchMode, short miscNo)
  51. {
  52. Location *locPtr = world.get_loc(destX, destY);
  53. if(!locPtr->can_move(mobile_type))
  54. {
  55. stop(KEEP_PRESERVE_ACTION); // let reactivate..() call searching later
  56. //waiting_term = MAX_SEARCH_OT_STOP_WAIT_TERM;
  57. }
  58. else
  59. {
  60. search(destX, destY, preserveAction, searchMode, miscNo);
  61. /*if(mobile_type==UNIT_LAND)
  62. search(destX, destY, preserveAction, searchMode, miscNo);
  63. else
  64. waiting_term = 0;*/
  65. }
  66. }
  67. //----------- End of function Unit::search_or_stop -----------//
  68. //------ Begin of function Unit::search_or_wait ---------//
  69. // call searching or wait
  70. //
  71. void Unit::search_or_wait()
  72. {
  73. #define SQUARE1 9
  74. #define SQUARE2 25
  75. #define SQUARE3 49
  76. #define DIMENSION 7
  77. int curXLoc = next_x_loc(), curYLoc = next_y_loc();
  78. short surrArray[SQUARE3];
  79. int xShift, yShift, checkXLoc, checkYLoc, hasFree, i, shouldWait;
  80. short unitRecno;
  81. Unit *unitPtr;
  82. Location *locPtr;
  83. //----------------------------------------------------------------------------//
  84. // wait if the unit is totally blocked. Otherwise, call searching
  85. //----------------------------------------------------------------------------//
  86. memset(surrArray, 0, sizeof(short)*SQUARE3);
  87. for(shouldWait=0, hasFree=0, i=2; i<=SQUARE3; i++)
  88. {
  89. if(i==SQUARE1 || i==SQUARE2 || i==SQUARE3)
  90. {
  91. if(!hasFree)
  92. {
  93. shouldWait++;
  94. break;
  95. }
  96. else
  97. hasFree = 0;
  98. }
  99. m.cal_move_around_a_point(i, DIMENSION, DIMENSION, xShift, yShift);
  100. checkXLoc = curXLoc+xShift;
  101. checkYLoc = curYLoc+yShift;
  102. if(checkXLoc<0 || checkXLoc>=MAX_WORLD_X_LOC || checkYLoc<0 || checkYLoc>=MAX_WORLD_Y_LOC)
  103. continue;
  104. locPtr = world.get_loc(checkXLoc, checkYLoc);
  105. if(!locPtr->has_unit(mobile_type))
  106. {
  107. hasFree++;
  108. continue;
  109. }
  110. unitRecno = locPtr->unit_recno(mobile_type);
  111. err_when(!unitRecno);
  112. if(unit_array.is_deleted(unitRecno))
  113. continue;
  114. unitPtr = unit_array[unitRecno];
  115. if(unitPtr->nation_recno==nation_recno && unitPtr->unit_group_id==unit_group_id &&
  116. ((unitPtr->cur_action==SPRITE_WAIT && unitPtr->waiting_term>1) || unitPtr->cur_action==SPRITE_TURN ||
  117. unitPtr->cur_action==SPRITE_MOVE))
  118. {
  119. surrArray[i-2] = unitRecno;
  120. unitPtr->unit_group_id++;
  121. }
  122. }
  123. //------------------- call searching if should not wait --------------------//
  124. if(!shouldWait)
  125. search(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_IN_A_GROUP);
  126. //search_or_stop(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_IN_A_GROUP);
  127. for(i=0; i<SQUARE3; i++)
  128. {
  129. if(surrArray[i])
  130. {
  131. err_when(unit_array.is_deleted(surrArray[i]));
  132. unitPtr = unit_array[surrArray[i]];
  133. unitPtr->unit_group_id--;
  134. }
  135. }
  136. if(shouldWait)
  137. set_wait();
  138. }
  139. //-------- End of function Unit::search_or_wait ---------//
  140. //------ Begin of function Unit::handle_blocked_move_s11 -------//
  141. // both blocked and blocking are size 1
  142. //
  143. void Unit::handle_blocked_move_s11(Unit *unitPtr)
  144. {
  145. err_when( world.get_unit_recno(next_x_loc(), next_y_loc(), mobile_type) != sprite_recno );
  146. err_when( world.get_unit_recno(unitPtr->next_x_loc(), unitPtr->next_y_loc(), unitPtr->mobile_type) != unitPtr->sprite_recno );
  147. err_when(cur_x!=next_x || cur_y!=next_y);
  148. int waitTerm;
  149. int moveStep = move_step_magn();
  150. switch(unitPtr->cur_action)
  151. {
  152. //------------------------------------------------------------------------------------//
  153. // handle blocked for units belonging to the same nation. For those belonging to other
  154. // nations, wait for it moving to other locations or search for another path.
  155. //------------------------------------------------------------------------------------//
  156. case SPRITE_WAIT: // the blocking unit is waiting
  157. err_when(unitPtr->go_x==unitPtr->cur_x && unitPtr->go_y==unitPtr->cur_y);
  158. case SPRITE_TURN:
  159. if(unitPtr->nation_recno==nation_recno)
  160. handle_blocked_wait(unitPtr); // check for cycle wait for our nation
  161. else if(waiting_term>=MAX_WAITING_TERM_DIFF)
  162. {
  163. search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall searching
  164. waiting_term = 0;
  165. }
  166. else // wait
  167. set_wait();
  168. return;
  169. //------------------------------------------------------------------------------------//
  170. // We know from the cur_action of the blocking unit it is moving to another locations,
  171. // the blocked unit wait for a number of terms or search again.
  172. //------------------------------------------------------------------------------------//
  173. case SPRITE_MOVE:
  174. case SPRITE_READY_TO_MOVE:
  175. case SPRITE_SHIP_EXTRA_MOVE:
  176. if(unit_id!=UNIT_CARAVAN && unitPtr->unit_id==UNIT_CARAVAN) // don't wait for caravans, and caravans don't wait for other units
  177. {
  178. search(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_A_UNIT_IN_GROUP);
  179. }
  180. else
  181. {
  182. waitTerm = (nation_recno==unitPtr->nation_recno) ? MAX_WAITING_TERM_SAME : MAX_WAITING_TERM_DIFF;
  183. if(waiting_term>=waitTerm)
  184. {
  185. search_or_wait();
  186. waiting_term = 0;
  187. }
  188. else
  189. set_wait();
  190. }
  191. return;
  192. //------------------------------------------------------------------------------------//
  193. // handling blocked for idle unit
  194. //------------------------------------------------------------------------------------//
  195. case SPRITE_IDLE:
  196. err_when(unitPtr->result_node_array!=NULL);
  197. if(unitPtr->action_mode==ACTION_SHIP_TO_BEACH)
  198. {
  199. //----------------------------------------------------------------------//
  200. // the blocking unit is trying to move to beach, so wait a number of terms,
  201. // or call searching again
  202. //----------------------------------------------------------------------//
  203. if(abs(unitPtr->next_x_loc()-unitPtr->action_x_loc2)<=moveStep &&
  204. abs(unitPtr->next_y_loc()-unitPtr->action_y_loc2)<=moveStep &&
  205. terrain_res[world.get_loc(unitPtr->action_x_loc2, unitPtr->action_y_loc2)->terrain_id]->average_type
  206. !=TERRAIN_OCEAN)
  207. {
  208. if(action_mode2==ACTION_SHIP_TO_BEACH && action_x_loc2==unitPtr->action_x_loc2 &&
  209. action_y_loc2==unitPtr->action_y_loc2)
  210. {
  211. int tempX, tempY;
  212. ship_to_beach(action_x_loc2, action_y_loc2, tempX, tempY);
  213. }
  214. else
  215. {
  216. waitTerm = (nation_recno==unitPtr->nation_recno) ? MAX_WAITING_TERM_SAME : MAX_WAITING_TERM_DIFF;
  217. if(waiting_term>=waitTerm)
  218. stop2();
  219. else
  220. set_wait();
  221. }
  222. return;
  223. }
  224. }
  225. if(unitPtr->nation_recno==nation_recno) //-------- same nation
  226. {
  227. //------------------------------------------------------------------------------------//
  228. // units from our nation
  229. //------------------------------------------------------------------------------------//
  230. if(unitPtr->unit_group_id==unit_group_id)
  231. {
  232. //--------------- from the same group -----------------//
  233. if(way_point_count && !unitPtr->way_point_count)
  234. {
  235. //------------ reset way point --------------//
  236. stop2();
  237. reset_way_point_array();
  238. }
  239. else if((unitPtr->next_x_loc() != move_to_x_loc || unitPtr->next_y_loc() != move_to_y_loc) &&
  240. (unitPtr->cur_action==SPRITE_IDLE && unitPtr->action_mode2==ACTION_STOP))
  241. move_to_my_loc(unitPtr); // push the blocking unit and exchange their destination
  242. else if(unitPtr->action_mode == ACTION_SETTLE)
  243. set_wait(); // wait for the settler
  244. else if(waiting_term>MAX_WAITING_TERM_SAME)
  245. {
  246. //---------- stop if wait too long ----------//
  247. terminate_move();
  248. waiting_term = 0;
  249. }
  250. else
  251. set_wait();
  252. }
  253. else if(unitPtr->action_mode2==ACTION_STOP)
  254. handle_blocked_by_idle_unit(unitPtr);
  255. else if(way_point_count && !unitPtr->way_point_count)
  256. {
  257. stop2();
  258. reset_way_point_array();
  259. }
  260. else
  261. search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall A* algorithm by default mode
  262. }
  263. else // different nation
  264. {
  265. //------------------------------------------------------------------------------------//
  266. // units from other nations
  267. //------------------------------------------------------------------------------------//
  268. if(unitPtr->next_x_loc() == move_to_x_loc && unitPtr->next_y_loc() == move_to_y_loc)
  269. {
  270. terminate_move(); // destination occupied by other unit
  271. if(action_mode==ACTION_ATTACK_UNIT && unitPtr->nation_recno!=nation_recno && unitPtr->sprite_recno==action_para)
  272. {
  273. err_when(action_x_loc!=unitPtr->next_x_loc() || action_y_loc!=unitPtr->next_y_loc());
  274. err_when(action_mode2!=ACTION_ATTACK_UNIT && action_mode2!=ACTION_AUTO_DEFENSE_ATTACK_TARGET &&
  275. action_mode2!=ACTION_DEFEND_TOWN_ATTACK_TARGET && action_mode2!=ACTION_MONSTER_DEFEND_ATTACK_TARGET);
  276. err_when(action_para2!=action_para);
  277. err_when(action_x_loc!=action_x_loc2 || action_y_loc!=action_y_loc2);
  278. set_dir(next_x, next_y, unitPtr->next_x, unitPtr->next_y);
  279. if(is_dir_correct())
  280. attack_unit(action_para);
  281. else
  282. set_turn();
  283. cur_frame = 1;
  284. }
  285. }
  286. else
  287. search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall A* algorithm by default mode
  288. }
  289. return;
  290. //------------------------------------------------------------------------------------//
  291. // don't wait for attackers from other nations, search for another path.
  292. //------------------------------------------------------------------------------------//
  293. case SPRITE_ATTACK:
  294. //----------------------------------------------------------------//
  295. // don't wait for other nation unit, call searching again
  296. //----------------------------------------------------------------//
  297. if(nation_recno!=unitPtr->nation_recno)
  298. {
  299. search_or_stop(move_to_x_loc, move_to_y_loc, 1);
  300. return;
  301. }
  302. //------------------------------------------------------------------------------------//
  303. // for attackers owned by our commander, handled blocked case by case as follows.
  304. //------------------------------------------------------------------------------------//
  305. switch(unitPtr->action_mode)
  306. {
  307. case ACTION_ATTACK_UNIT:
  308. if(action_para && !unit_array.is_deleted(action_para))
  309. {
  310. Unit *targetPtr = unit_array[action_para];
  311. handle_blocked_attack_unit(unitPtr, targetPtr);
  312. }
  313. else
  314. search_or_stop(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_A_UNIT_IN_GROUP);
  315. break;
  316. case ACTION_ATTACK_FIRM:
  317. if(!unitPtr->action_para || firm_array.is_deleted(unitPtr->action_para))
  318. set_wait();
  319. else
  320. handle_blocked_attack_firm(unitPtr);
  321. break;
  322. case ACTION_ATTACK_TOWN:
  323. if(!unitPtr->action_para || town_array.is_deleted(unitPtr->action_para))
  324. set_wait();
  325. else
  326. handle_blocked_attack_town(unitPtr);
  327. break;
  328. case ACTION_ATTACK_WALL:
  329. if(unitPtr->action_para)
  330. set_wait();
  331. else
  332. handle_blocked_attack_wall(unitPtr);
  333. break;
  334. case ACTION_GO_CAST_POWER:
  335. set_wait();
  336. break;
  337. default: err_here();
  338. break;
  339. }
  340. return;
  341. //------------------------------------------------------------------------------------//
  342. // the blocked unit can pass after the blocking unit disappears in air.
  343. //------------------------------------------------------------------------------------//
  344. case SPRITE_DIE:
  345. set_wait(); // assume this unit will not wait too long
  346. return;
  347. default:
  348. err_here();
  349. break;
  350. }
  351. err_when(cur_x==go_x && cur_y==go_y && (cur_x!=next_x || cur_y!=next_y));
  352. }
  353. //------- End of function Unit::handle_blocked_move_s11 --------//
  354. //------ Begin of function Unit::handle_blocked_same_target_attack ---------//
  355. // the target of the blocked unit and this unit are same
  356. //
  357. // <Unit*> unitPtr - pointer to blocking uit
  358. // <Unit*> targetPtr - pointer to target unit
  359. //
  360. void Unit::handle_blocked_same_target_attack(Unit* unitPtr, Unit* targetPtr)
  361. {
  362. //----------------------------------------------------------//
  363. // this unit is now waiting and the unit pointed by unitPtr
  364. // is attacking the unit pointed by targetPtr
  365. //----------------------------------------------------------//
  366. err_when(cur_x%ZOOM_LOC_WIDTH || cur_y%ZOOM_LOC_HEIGHT);
  367. err_when(cur_x!=next_x || cur_y!=next_y);
  368. err_when(cur_x==go_x && cur_y==go_y);
  369. if(space_for_attack(action_x_loc, action_y_loc, targetPtr->mobile_type, targetPtr->sprite_info->loc_width, targetPtr->sprite_info->loc_height))
  370. {
  371. err_when(action_x_loc!=action_x_loc2 || action_y_loc!=action_y_loc2);
  372. search_or_stop(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_TO_ATTACK, targetPtr->sprite_recno);
  373. //search(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_TO_ATTACK, targetPtr->sprite_recno);
  374. }
  375. else if(in_any_defense_mode())
  376. {
  377. err_when(action_mode2!=ACTION_AUTO_DEFENSE_ATTACK_TARGET && action_mode2!=ACTION_DEFEND_TOWN_ATTACK_TARGET &&
  378. action_mode2!=ACTION_MONSTER_DEFEND_ATTACK_TARGET);
  379. general_defend_mode_detect_target();
  380. }
  381. else if(m.points_distance(next_x_loc(), next_y_loc(), action_x_loc, action_y_loc)<ATTACK_DETECT_DISTANCE)
  382. {
  383. //------------------------------------------------------------------------//
  384. // if the target is within the detect range, stop the unit's action to detect
  385. // another target if any exist. In case, there is no other target, the unit
  386. // will still attack the original target since it is the only target in the
  387. // detect range
  388. //------------------------------------------------------------------------//
  389. stop2(KEEP_DEFENSE_MODE);
  390. }
  391. else
  392. set_wait(); // set wait to stop the movement
  393. }
  394. //------- End of function Unit::handle_blocked_same_target_attack --------//
  395. //--------- Begin of function Unit::handle_blocked_attack_unit ---------//
  396. // the blocking unit is attacking against other unit
  397. //
  398. // <Unit*> unitPtr - pointer to blocking uit
  399. // <Unit*> targetPtr - pointer to target unit
  400. //
  401. void Unit::handle_blocked_attack_unit(Unit* unitPtr, Unit* targetPtr)
  402. {
  403. if(action_para==targetPtr->sprite_recno && unitPtr->action_para==targetPtr->sprite_recno &&
  404. action_mode==unitPtr->action_mode)
  405. { //----------------- both attack the same target --------------------//
  406. err_when(unit_array.is_deleted(action_para));
  407. handle_blocked_same_target_attack(unitPtr, targetPtr);
  408. }
  409. else
  410. search_or_stop(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_A_UNIT_IN_GROUP); // recall A* algorithm
  411. //search(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_A_UNIT_IN_GROUP); // recall A* algorithm
  412. }
  413. //----------- End of function Unit::handle_blocked_attack_unit -----------//
  414. //--------- Begin of function Unit::handle_blocked_attack_firm ---------//
  415. // handle the case that the way of this unit to the target firm is blocked by
  416. // another unit
  417. //
  418. // <Unit*> unitPtr - the blocking unit
  419. //
  420. void Unit::handle_blocked_attack_firm(Unit *unitPtr)
  421. {
  422. if(action_x_loc==unitPtr->action_x_loc && action_y_loc==unitPtr->action_y_loc && action_para==unitPtr->action_para &&
  423. action_mode==unitPtr->action_mode)
  424. {
  425. //------------- both attacks the same firm ------------//
  426. Location *locPtr = world.get_loc(action_x_loc, action_y_loc);
  427. if(!locPtr->is_firm())
  428. stop2(KEEP_DEFENSE_MODE); // stop since firm is deleted
  429. else
  430. {
  431. Firm *firmPtr = firm_array[action_para];
  432. FirmInfo *firmInfo = firm_res[firmPtr->firm_id];
  433. if(space_for_attack(action_x_loc, action_y_loc, UNIT_LAND, firmInfo->loc_width, firmInfo->loc_height))
  434. {
  435. //------------ found surrounding place to attack the firm -------------//
  436. if(mobile_type==UNIT_LAND)
  437. set_move_to_surround(firmPtr->loc_x1, firmPtr->loc_y1, firmInfo->loc_width, firmInfo->loc_height, BUILDING_TYPE_FIRM_MOVE_TO);
  438. else
  439. attack_firm(firmPtr->loc_x1, firmPtr->loc_y1);
  440. }
  441. else // no surrounding place found, stop now
  442. stop(KEEP_PRESERVE_ACTION);
  443. }
  444. }
  445. else // let process_idle() handle it
  446. stop();
  447. }
  448. //----------- End of function Unit::handle_blocked_attack_firm -----------//
  449. //--------- Begin of function Unit::handle_blocked_attack_town ---------//
  450. // handle the case that the way of this unit to the target town is blocked by
  451. // another unit
  452. //
  453. // <Unit*> unitPtr - the blocking unit
  454. //
  455. void Unit::handle_blocked_attack_town(Unit *unitPtr)
  456. {
  457. if(action_x_loc==unitPtr->action_x_loc && action_y_loc==unitPtr->action_y_loc && action_para==unitPtr->action_para &&
  458. action_mode==unitPtr->action_mode)
  459. {
  460. //---------------- both attacks the same town ----------------------//
  461. Location *locPtr = world.get_loc(action_x_loc, action_y_loc);
  462. if(!locPtr->is_town())
  463. stop2(KEEP_DEFENSE_MODE); // stop since town is deleted
  464. else if(space_for_attack(action_x_loc, action_y_loc, UNIT_LAND, STD_TOWN_LOC_WIDTH, STD_TOWN_LOC_HEIGHT))
  465. {
  466. //------------ found surrounding place to attack the town -------------//
  467. Town *townPtr = town_array[action_para];
  468. {
  469. if(mobile_type==UNIT_LAND)
  470. set_move_to_surround(townPtr->loc_x1, townPtr->loc_y1, STD_TOWN_LOC_WIDTH, STD_TOWN_LOC_HEIGHT, BUILDING_TYPE_TOWN_MOVE_TO);
  471. else
  472. attack_town(townPtr->loc_x1, townPtr->loc_y1);
  473. }
  474. }
  475. else // no surrounding place found, stop now
  476. stop(KEEP_PRESERVE_ACTION);
  477. }
  478. else
  479. stop();
  480. }
  481. //----------- End of function Unit::handle_blocked_attack_town -----------//
  482. //--------- Begin of function Unit::handle_blocked_attack_wall ---------//
  483. // handle the case that the way of this unit to the target wall is blocked by
  484. // another unit
  485. //
  486. // <Unit*> unitPtr - the blocking unit
  487. //
  488. void Unit::handle_blocked_attack_wall(Unit *unitPtr)
  489. {
  490. if(action_x_loc==unitPtr->action_x_loc && action_y_loc==unitPtr->action_y_loc && action_mode==unitPtr->action_mode)
  491. {
  492. //------------- both attacks the same wall ------------//
  493. Location *locPtr = world.get_loc(action_x_loc, action_y_loc);
  494. if(!locPtr->is_wall())
  495. stop2(KEEP_DEFENSE_MODE); // stop since wall is deleted
  496. else if(space_for_attack(action_x_loc, action_y_loc, UNIT_LAND, 1, 1))
  497. {
  498. //------------ found surrounding place to attack the wall -------------//
  499. if(mobile_type==UNIT_LAND)
  500. set_move_to_surround(action_x_loc, action_y_loc, 1, 1, BUILDING_TYPE_WALL); // search for a unit only, not for a group
  501. else
  502. attack_wall(action_x_loc, action_y_loc);
  503. }
  504. else // no surrounding place found, stop now
  505. stop(KEEP_PRESERVE_ACTION); // no space available, so stop to wait for space to attack the wall
  506. }
  507. else
  508. {
  509. if(action_x_loc==-1 || action_y_loc==-1)
  510. stop();
  511. else
  512. set_wait();
  513. }
  514. }
  515. //----------- End of function Unit::handle_blocked_attack_wall -----------//