Example #1
0
void t_move_missile::on_idle()
{
    t_uint32 new_time = get_time();

    // update animation (if any)
    if (elapsed_time( new_time, m_last_update_time ) >= m_delay )
    {
        int frame = m_missile.get_current_frame_num();

        frame++;
        if (frame >= m_missile.get_frame_count())
            frame = 0;
        m_battlefield.set_current_frame_num( m_missile, frame );
        m_last_update_time = new_time;
    }

    t_map_point_3d position;
    t_uint32       next_time = get_next_time() - get_delay();
    int			   skip_limit = 1;

    // move missile forward one space
    while (elapsed_time( new_time, next_time ) >= 0 && skip_limit-- > 0 )
    {
        next_time += get_delay();
        if (m_distance_left <= 0)
        {
            t_idle_ptr reference = this;

            suspend_idle_processing();
            m_battlefield.remove_object( &m_missile );
            animation_ended();
            m_end_handler( m_attacker, m_target_position );
            return;
        }

        t_map_point_3d delta;
        int            distance;

        // limit distance moved to distance left
        position = m_missile.get_position();
        distance = m_move_distance;
        if (distance > m_distance_left)
            distance = m_distance_left;
        m_distance_left -= distance;
        // add distance to accumulator
        m_sum += m_delta * distance;
        // find integer portion of moved distance
        delta = m_sum / m_distance;
        position += delta;
        m_sum -= delta * m_distance;
        // calculate parabolic arc
        if (m_is_parabolic)
        {
            position.height += m_vertical_velocity - k_gravity;
            m_vertical_velocity -= k_gravity << 1;
        }
    }
    set_next_time( next_time );
    m_battlefield.move_object( m_missile, position );
}
Example #2
0
// ------------------------------------------------------------------------
// do movement that's hidden
// ------------------------------------------------------------------------
void t_army_mover::do_hidden_move()
{
	if (m_is_visible)
		return;
	if (m_path.size() == 0)
	{
		finish_path();
		return;
	}

	t_adventure_map const&  map = *m_army->get_map();
	t_player&				player = map.get_player();
	int						team = player.get_team();

	declare_timer( timer_1, "do_hidden_movement" );
	while (!m_is_visible && !m_halted)
	{
		t_adventure_path_point& point = m_path[m_step];

		m_army->move( point );
		expend_movement( point.move_cost );
		mark_eluded_armies();
		if (m_step == m_path.size() - 1)
		{
			finish_path();
			return;
		}
		trigger_event();
		if (m_halted) 
			return;
		m_is_visible = !m_army->hidden_by_fog_of_war( team ) && show_enemy_moves();
		if (m_is_visible)
			break; // break here, because start_new_square will increment step.
		++m_step;
		declare_timer( timer_2, "on_starting_new_square: hidden" );
		on_starting_new_square();
	}
	if (m_halted)
		return;
	m_army->set_action( k_adv_actor_action_walk );
	m_distance = compute_overall_distance( m_path, m_step + 1 );
	start_new_square();
	prepare_move( 0 );
	set_next_time( get_time() + get_delay() );
}
Example #3
0
 void set_step_interval(const Real value)
 {
     set_next_time(the_current_time_ + value);
 }
Example #4
0
// ------------------------------------------------------------------------
// Initialize from local or derived constructor. If use_army_path is false,
// m_path must already be set up.
// ------------------------------------------------------------------------
void t_army_mover::initialize( t_adventure_map_window* window, t_army* army, 
							   bool limit_move, t_adventure_path_finder const* path_finder,
							   bool use_army_path )
{

	m_window = window;
	m_army = army;
	m_in_trigger = false;
	m_exceeded_move_limit = false;
	m_is_visible = false;
	m_movement_expended = 0;
	m_has_trigger		= false;
	m_landing			= false;
	m_limit_move		= limit_move;
	m_original_position	= army->get_position();
	
	t_adventure_map&		map = *army->get_map();

	if ( use_army_path )
	{
		t_adventure_path		path = army->get_path();

		int						i;
		int						move_left = army->get_movement();
		bool					is_boat = army->is_boat();
		bool					enemy_enforced_dest = false;
		t_creature_array const*	restricting_enemy = NULL;
		t_adv_map_point			restricted_dest;
		t_player*				owner = army->get_owner();
		bool					is_computer = owner && owner->is_computer();
		bool					built_boat = false;
		bool					hidden_enemy = false;

		// copy path until we run out of movement or encounter a trigger
		for (i = path.size() - 1; i >= 0; i--)
		{
			t_adventure_path_point& point = path[i];

			// If the path goes into the attack radius of a hidden enemy
			// then truncate the path
			if (	path_finder != 0
				&&	point.actual_enemy_adjacent
				&&	point.actual_enemy_distance > 0
				&&	(	!point.visible_enemy_adjacent
					||	point.actual_enemy_direction != point.visible_enemy_direction
					||	point.actual_enemy_distance != point.visible_enemy_distance ))
			{
				restricting_enemy = find_enemy( map, *path_finder, point, *m_army );
				if (restricting_enemy != 0)
				{
					int stealth_advantage;

					stealth_advantage = restricting_enemy->get_stealth_level()
									  - m_army->get_anti_stealth_level();
					if (stealth_advantage <= 0)
						break;
					if (stealth_advantage == 1 || restricting_enemy->get_owner_number() < 0)
						hidden_enemy = true;
				}
			}
			if ( path_finder && ( point.visible_restricts_movement || enemy_enforced_dest ) )
			{
				if (enemy_enforced_dest)
				{
					if ( (point != restricted_dest) && (point != restricting_enemy->get_position()) )
						break;
				}
				else
				{
					restricting_enemy = find_restrictive_enemy( map, *path_finder, point, *m_army );
					if (restricting_enemy != NULL)
						enemy_enforced_dest = true;
				}
				restricted_dest = point + get_direction_offset( point.actual_enemy_direction );
			} 

			if (point.move_cost > move_left && limit_move) {
				
				m_actual_destination = point.last_point;
				m_exceeded_move_limit = true;
				break;
			}
			if (map.get_trigger_object( point.last_point, point.direction, army ))
			{
				m_has_trigger   = true;
				m_trigger_point = point;
			}
			if (is_boat)
			{
				if (!map.is_ocean( point ))
				{
					m_landing = true;
					m_trigger_point = point;
					break;
				}
			}
			else
				if (is_computer && !m_has_trigger && map.is_ocean( point ) && !m_exceeded_move_limit)
				{
					t_adventure_tile const& last_tile = map[point];

					t_hero*	most_spell_points = NULL;
					if ( map.has_empty_boat( *m_army->get_owner() ) )
					{
						int		most_spell_points_count = 0;
						for (int i = 0; i < t_creature_array::k_size; i++)
						{
							t_hero* hero = (*m_army)[i].get_hero();
							if (hero && hero->can_cast( k_spell_summon_boat ))
							{
								int cur_spell_points = hero->get_spell_points();
								if ( (most_spell_points == NULL) || ( cur_spell_points > most_spell_points_count ) )
								{
									most_spell_points = hero;
									most_spell_points_count = cur_spell_points;
								}
							}
						}
					}

					if (most_spell_points != NULL)
					{
						army->get_adventure_frame()->ai_cast_summon_boat( *m_army, *most_spell_points, point );
					}
					else
						if (last_tile.ai_can_build_ship())
						{
							t_adventure_object& object = map.get_adv_object(last_tile.ai_get_shipyard_id());
							t_adv_shipyard* shipyard = dynamic_cast< t_adv_shipyard* >( &object );
							t_adv_map_point boat_position;
							if (shipyard != NULL) 
								built_boat = shipyard->find_new_ship_position( boat_position );
							else
							{
								t_town* town = object.get_town();
								if (town)
								{
									if ( !town->has( k_town_shipyard) )
									{
										if (town->has_built())
											break;
										town->buy_building( k_town_shipyard );
									}
									built_boat = town->find_new_ship_position( boat_position, false );
								}
							}

							if (built_boat)
							{
								t_army* boat = new t_army( army->get_creatures().get_leader().get_alignment() );
								boat->set_owner( army->get_owner_number() );
								boat->place( map, boat_position );
								owner->spend( army->get_ai()->get_boat_cost() ); // This destination pick wouldn't have been 
																				 // made unless he already had the cash.
							}
						}
				}
		
			if (map[point].blocks_army( *army, map, point.on_bridge, k_path_search_move_army ))
				break;
			// if the path actually enters a cell of an enemy, stop.
			if (point.actual_enemy_adjacent && point.actual_enemy_distance == 0)
				break;
			m_path.push_back( point );
			if (m_has_trigger || built_boat || hidden_enemy)
				break;
		}
	}
	
	m_halted = false;
	m_step = -1;
	m_distance = compute_overall_distance( m_path, 0 );
	if (m_path.size() == 0)
	{
		m_cell_distance = 0;
		m_crossing_point = -1;
		m_distance = 0;
		m_frames = 0;
		m_divisor = 1;
		m_delta = t_screen_point(0,0);
		m_offset = t_screen_point(0,0);
		m_distance_delta = 0;
		m_is_visible = !m_army->hidden_by_fog_of_war( map.get_player().get_team() );
	}
	else
	{
		m_army->set_action( k_adv_actor_action_prewalk );
		start_new_square();
		prepare_move( 0 );
	}
	set_next_time( get_time() );
}
Example #5
0
// ------------------------------------------------------------------------
// class to move army on adventure map
// ------------------------------------------------------------------------
void t_army_mover::do_movement()
{
	int							frame = m_army->get_frame();
	int							frame_count = m_army->get_frame_count();
	t_adv_actor_action_id		action = m_army->get_action();
	t_uint32					current_time = get_time();
	t_uint32					next_time = get_next_time() - get_delay();
	t_counted_ptr<t_army_mover> ref = this;
	t_window_ptr				adv_frame = m_window->get_frame();	// temporary reference to prevent the adventure frame
																	// from removing itself if the game is over
	bool						entered_new_square = false;

	declare_timer( timer_1, "do_movement" );
	while ( m_frames > 0 && (!m_is_visible || elapsed_time( current_time, next_time ) >= 0) )
	{
		m_offset += m_delta;
		m_cell_distance -= m_distance_delta;
		if (m_cell_distance <= m_crossing_point)
		{
			enter_new_square();
		}
		m_army->set_frame_offset( m_offset / m_divisor );
		frame++;
		if (action == k_adv_actor_action_walk && frame == frame_count)
			frame = 0;
		if (frame < frame_count)
			m_army->set_frame( frame );
		m_frames--;
		if (m_is_visible)
			next_time += get_delay();
	}
	if (m_is_visible)
		set_next_time( next_time );
	// if m_frames is zero, we've hit the center of the cell, or we've
	// finished a prewalk / walk / postwalk sequence
	if (m_frames == 0)
	{
		if ((action == k_adv_actor_action_postwalk || m_path.size() == 0)
			&& m_distance + m_cell_distance == 0)
		{
			finish_path();
			return;
		}
		if (m_cell_distance == 0) 
		{
			start_new_square();

			entered_new_square = true;

			trigger_event();
			if (m_halted) 
				return;
		}
		else
		{
			m_cell_distance /= m_divisor;
			m_crossing_point /= m_divisor;
		}
		prepare_move( frame );
	}

	if (entered_new_square)
	{
		declare_timer( timer_2, "on_starting_new_square" );
		on_starting_new_square();
	}
}