Exemple #1
0
//--------- Begin of function Sprite::process_turn --------//
void Sprite::process_turn()
{
	err_when(!sprite_info->need_turning);
	match_dir();
	if(is_dir_correct())
		cur_action = SPRITE_MOVE;
}
Exemple #2
0
//--------- Begin of function Unit::process_ship_to_beach ---------//
// process unit action SHIP_TO_BEACH
//
void Unit::process_ship_to_beach()
{
	//----- action_mode never clear, in_beach to skip idle checking
	if(cur_action==SPRITE_IDLE)
	{
		int shipXLoc = next_x_loc();
		int shipYLoc = next_y_loc();
		if(shipXLoc==move_to_x_loc && shipYLoc==move_to_y_loc)
		{
			if(abs(move_to_x_loc-action_x_loc2)<=2 && abs(move_to_y_loc-action_y_loc2)<=2)
			{
				UnitMarine *shipPtr = (UnitMarine*) this;
				//------------------------------------------------------------------------------//
				// determine whether extra_move is required
				//------------------------------------------------------------------------------//
				switch(shipPtr->extra_move_in_beach)
				{
					case NO_EXTRA_MOVE:
							if(abs(shipXLoc-action_x_loc2)>1 || abs(shipYLoc-action_y_loc2)>1)
							{
								err_when(abs(shipXLoc-action_x_loc2)>2 || abs(shipYLoc-action_y_loc2)>2);
								err_when(result_node_array);

								shipPtr->extra_move();
							}
							else
							{
								//shipPtr->in_beach = 1;
								shipPtr->extra_move_in_beach = NO_EXTRA_MOVE;
								
							//#### trevor 23/10 #####//
								if(ai_action_id)
									nation_array[nation_recno]->action_finished(ai_action_id, sprite_recno);
							//#### trevor 23/10 #####//
							}
							break;

					case EXTRA_MOVING_IN:
					case EXTRA_MOVING_OUT:
							//err_when(cur_action!=SPRITE_SHIP_EXTRA_MOVE);
							break;

							//#### trevor 23/10 #####//

					case EXTRA_MOVE_FINISH:
							if(ai_action_id)
								nation_array[nation_recno]->action_finished(ai_action_id, sprite_recno);
							break;

							//#### trevor 23/10 #####//

					default: err_here();
								break;
				}
			}
		}			
		else
			reset_action_para();
	}
	else if(cur_action==SPRITE_TURN && is_dir_correct())
		set_move();
}
Exemple #3
0
//------ Begin of function Unit::handle_blocked_move_s11 -------//
// both blocked and blocking are size 1
//
void Unit::handle_blocked_move_s11(Unit *unitPtr)
{
	err_when( world.get_unit_recno(next_x_loc(), next_y_loc(), mobile_type) != sprite_recno );
	err_when( world.get_unit_recno(unitPtr->next_x_loc(), unitPtr->next_y_loc(), unitPtr->mobile_type) != unitPtr->sprite_recno );
	err_when(cur_x!=next_x || cur_y!=next_y);

	int waitTerm;
	int moveStep = move_step_magn();

	switch(unitPtr->cur_action)
	{
		//------------------------------------------------------------------------------------//
		// handle blocked for units belonging to the same nation.  For those belonging to other
		// nations, wait for it moving to other locations or search for another path.
		//------------------------------------------------------------------------------------//
		case SPRITE_WAIT: // the blocking unit is waiting
				err_when(unitPtr->go_x==unitPtr->cur_x && unitPtr->go_y==unitPtr->cur_y);
		
		case SPRITE_TURN:
				if(unitPtr->nation_recno==nation_recno)
					handle_blocked_wait(unitPtr); // check for cycle wait for our nation
				else if(waiting_term>=MAX_WAITING_TERM_DIFF)
				{
					search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall searching
					waiting_term = 0;
				}
				else // wait
					set_wait();
				return;

		//------------------------------------------------------------------------------------//
		// We know from the cur_action of the blocking unit it is moving to another locations,
		// the blocked unit wait for a number of terms or search again.
		//------------------------------------------------------------------------------------//
		case SPRITE_MOVE:
		case SPRITE_READY_TO_MOVE:
		case SPRITE_SHIP_EXTRA_MOVE:
				if(unit_id!=UNIT_CARAVAN && unitPtr->unit_id==UNIT_CARAVAN) // don't wait for caravans, and caravans don't wait for other units
				{
					search(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_A_UNIT_IN_GROUP);
				}
				else
				{
					waitTerm = (nation_recno==unitPtr->nation_recno) ? MAX_WAITING_TERM_SAME : MAX_WAITING_TERM_DIFF;
					if(waiting_term>=waitTerm)
					{
						search_or_wait();
						waiting_term = 0;
					}
					else
						set_wait();
				}
				return;

		//------------------------------------------------------------------------------------//
		// handling blocked for idle unit
		//------------------------------------------------------------------------------------//
		case SPRITE_IDLE:
				err_when(unitPtr->result_node_array!=NULL);
				if(unitPtr->action_mode==ACTION_SHIP_TO_BEACH)
				{
					//----------------------------------------------------------------------//
					// the blocking unit is trying to move to beach, so wait a number of terms,
					// or call searching again
					//----------------------------------------------------------------------//
					if(abs(unitPtr->next_x_loc()-unitPtr->action_x_loc2)<=moveStep &&
						abs(unitPtr->next_y_loc()-unitPtr->action_y_loc2)<=moveStep &&
						terrain_res[world.get_loc(unitPtr->action_x_loc2, unitPtr->action_y_loc2)->terrain_id]->average_type
						!=TERRAIN_OCEAN)
					{
						if(action_mode2==ACTION_SHIP_TO_BEACH && action_x_loc2==unitPtr->action_x_loc2 &&
							action_y_loc2==unitPtr->action_y_loc2)
						{
							int tempX, tempY;
							ship_to_beach(action_x_loc2, action_y_loc2, tempX, tempY);
						}
						else
						{
							waitTerm = (nation_recno==unitPtr->nation_recno) ? MAX_WAITING_TERM_SAME : MAX_WAITING_TERM_DIFF;
							if(waiting_term>=waitTerm)
								stop2();
							else
								set_wait();
						}
						return;
					}
				}

				if(unitPtr->nation_recno==nation_recno) //-------- same nation
				{
					//------------------------------------------------------------------------------------//
					// units from our nation
					//------------------------------------------------------------------------------------//
					if(unitPtr->unit_group_id==unit_group_id)
					{
						//--------------- from the same group -----------------//
						if(way_point_count && !unitPtr->way_point_count)
						{
							//------------ reset way point --------------//
							stop2();
							reset_way_point_array();
						}
						else if((unitPtr->next_x_loc() != move_to_x_loc || unitPtr->next_y_loc() != move_to_y_loc) &&
							(unitPtr->cur_action==SPRITE_IDLE && unitPtr->action_mode2==ACTION_STOP))
							move_to_my_loc(unitPtr); // push the blocking unit and exchange their destination
						else if(unitPtr->action_mode == ACTION_SETTLE)
							set_wait(); // wait for the settler
						else if(waiting_term>MAX_WAITING_TERM_SAME)
						{
							//---------- stop if wait too long ----------//
							terminate_move();
							waiting_term = 0;
						}
						else
							set_wait();
					}
					else if(unitPtr->action_mode2==ACTION_STOP)
						handle_blocked_by_idle_unit(unitPtr);
					else if(way_point_count && !unitPtr->way_point_count)
					{
						stop2();
						reset_way_point_array();
					}
					else
						search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall A* algorithm by default mode
				}
				else // different nation
				{
					//------------------------------------------------------------------------------------//
					// units from other nations
					//------------------------------------------------------------------------------------//
					if(unitPtr->next_x_loc() == move_to_x_loc && unitPtr->next_y_loc() == move_to_y_loc)
					{  
						terminate_move(); // destination occupied by other unit

						if(action_mode==ACTION_ATTACK_UNIT && unitPtr->nation_recno!=nation_recno && unitPtr->sprite_recno==action_para)
						{
							err_when(action_x_loc!=unitPtr->next_x_loc() || action_y_loc!=unitPtr->next_y_loc());
							err_when(action_mode2!=ACTION_ATTACK_UNIT && action_mode2!=ACTION_AUTO_DEFENSE_ATTACK_TARGET &&
										action_mode2!=ACTION_DEFEND_TOWN_ATTACK_TARGET && action_mode2!=ACTION_MONSTER_DEFEND_ATTACK_TARGET);
							err_when(action_para2!=action_para);
							err_when(action_x_loc!=action_x_loc2 || action_y_loc!=action_y_loc2);
							
							set_dir(next_x, next_y, unitPtr->next_x, unitPtr->next_y);
							if(is_dir_correct())
								attack_unit(action_para);
							else
								set_turn();
							cur_frame  = 1;
						}
					}
					else
						search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall A* algorithm by default mode
				}
				return;

		//------------------------------------------------------------------------------------//
		// don't wait for attackers from other nations, search for another path.
		//------------------------------------------------------------------------------------//
		case SPRITE_ATTACK:
				//----------------------------------------------------------------//
				// don't wait for other nation unit, call searching again
				//----------------------------------------------------------------//
				if(nation_recno!=unitPtr->nation_recno)
				{
					search_or_stop(move_to_x_loc, move_to_y_loc, 1);
					return;
				}

				//------------------------------------------------------------------------------------//
				// for attackers owned by our commander, handled blocked case by case as follows.
				//------------------------------------------------------------------------------------//
				switch(unitPtr->action_mode)
				{
					case ACTION_ATTACK_UNIT:
							if(action_para && !unit_array.is_deleted(action_para))
							{
								Unit *targetPtr = unit_array[action_para];
								handle_blocked_attack_unit(unitPtr, targetPtr);
							}
							else
								search_or_stop(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_A_UNIT_IN_GROUP);
							break;

					case ACTION_ATTACK_FIRM:
							if(!unitPtr->action_para || firm_array.is_deleted(unitPtr->action_para))
								set_wait();
							else
								handle_blocked_attack_firm(unitPtr);
							break;

					case ACTION_ATTACK_TOWN:
							if(!unitPtr->action_para || town_array.is_deleted(unitPtr->action_para))
								set_wait();
							else
								handle_blocked_attack_town(unitPtr);
							break;

					case ACTION_ATTACK_WALL:
							if(unitPtr->action_para)
								set_wait();
							else
								handle_blocked_attack_wall(unitPtr);
							break;

					case ACTION_GO_CAST_POWER:
							set_wait();
							break;

					default: err_here();
								break;
				}
				return;

		//------------------------------------------------------------------------------------//
		// the blocked unit can pass after the blocking unit disappears in air.
		//------------------------------------------------------------------------------------//
		case SPRITE_DIE:
				set_wait();	// assume this unit will not wait too long
				return;

		default:
				err_here();
				break;
	}
	
	err_when(cur_x==go_x && cur_y==go_y && (cur_x!=next_x || cur_y!=next_y));
}
Exemple #4
0
//--------- Begin of function UnitB::set_next --------//
//
//	set the next coordinates to move to
//
// <int> newNextX, newNextY	- next coordinate to move to
// <int> para						- used to count the result_path_dist
// <int> ignoreBlockCheck		- whether ignore blocking check or not
//
int UnitB::set_next(int newNextX, int newNextY, int para, int ignoreBlockCheck)
{
	static char callingCount=0;

	int curNextXLoc = next_x_loc();
	int curNextYLoc = next_y_loc();
	int newNextXLoc = newNextX >> ZOOM_X_SHIFT_COUNT;
	int newNextYLoc = newNextY >> ZOOM_Y_SHIFT_COUNT;
	//------begin Juliet 14/10-----//
	int tempEndX = newNextXLoc+obj_loc_width()-1;
	int tempEndY = newNextYLoc+obj_loc_height()-1;
	//------end Juliet 14/10-------//
	short w, h, x, y;

	callingCount++;          // this function is being called, prevent recursive calling

	if(curNextXLoc!=newNextXLoc || curNextYLoc!=newNextYLoc)
	{
		if(!is_dir_correct())
		{
			set_turn();
			return 1;
		}
	}

	//----------- blocking check ---------//

	if( !ignoreBlockCheck )
	{
		int isBlocked=0;

		for(h=0, y=newNextYLoc; h<loc_height && !isBlocked ; h++, y++)
		{
			for(w=0, x=newNextXLoc; w<loc_width; w++, x++)
			{
				Location* locPtr = world.get_loc(x,y);

				if( locPtr->can_move(mobile_type) )
					continue;

				//--- this location is occupied by the unit itself ---//

				if( locPtr->unit_recno(mobile_type) == sprite_recno )
					continue;

				isBlocked = 1;
				break;
			}
		}

		if( isBlocked )
		{
			//----- if we have already reach the destination -----//

			
			int rangeX1, rangeY1, rangeX2, rangeY2;

			get_object_range(move_to_loc_x, move_to_loc_y, rangeX1, rangeY1, rangeX2, rangeY2);

			if( m.is_touch( rangeX1, rangeY1, rangeX2, rangeY2,
								 newNextXLoc, newNextYLoc, newNextXLoc+loc_width-1, newNextYLoc+loc_height-1 ) )
			{
				stop_move();
			}
			else //------- otherwise wait ---------//
			{
				set_wait();
			}
			
			callingCount--;
			return 0;
		}
	}

	//--------- set the sprite_recno in new locations -----------//

	for(h=0, y=curNextYLoc; h<loc_height; h++, y++)
	{
		for(w=0, x=curNextXLoc; w<loc_width; w++, x++)
			world.get_loc(x,y)->remove_unit(mobile_type);
	}

	for(h=0, y=newNextYLoc; h<loc_height; h++, y++)
	{
		for(w=0, x=newNextXLoc; w<loc_width; w++, x++)
			world.get_loc(x,y)->set_unit(sprite_recno,mobile_type);
	}

	//----- set the new next coordinate ------//

	next_x = newNextX;
	next_y = newNextY;

	callingCount--;

	if( steps_remaining > 0 )		// steps_remaining can be decreased to negative as set_next() is called when stopping a unit, which is an addition to the steps it is supposed to move 
		steps_remaining--;

	// --------- explore map ---------//

	if( cast_to_Unit() )
		cast_to_Unit()->explore_on_move(curNextXLoc, curNextYLoc, newNextXLoc, newNextYLoc );

	return 1;
}