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