Exemplo n.º 1
0
void move()
{
	if (status->objects[0].long_attack_casting==0) longattack_target=-1;
	if (longattack_target!=-1)
	{
		int enemy=enemy_id(longattack_target);
		if (map->objects[enemy].shield_time>=status->objects[0].long_attack_casting);
		Position pos=map->objects[enemy].pos;
		if (Distance(pos,status->objects[0].pos)>=kLongAttackRange[status->objects[0].skill_level[LONG_ATTACK]]-kMaxMoveSpeed*2)
		{
			Position speed;
			speed.x=-100*(status->objects[0].pos.x-pos.x);
			speed.y=-100*(status->objects[0].pos.y-pos.y);
			speed.z=-100*(status->objects[0].pos.z-pos.z);
			Move(status->objects[0].id,speed);
			return;
		};
	};
	int danger=danger_move();
	if (danger!=-1)
	{
		Position speed;
		speed.x=100*(status->objects[0].pos.x-map->objects[danger].pos.x);
		speed.y=100*(status->objects[0].pos.y-map->objects[danger].pos.y);
		speed.z=100*(status->objects[0].pos.z-map->objects[danger].pos.z);
		Move(status->objects[0].id,speed);
		return;
	};
	int enemy=find_enemy();
	if (enemy!=-1)
	{
		Position speed;
		speed.x=-100*(status->objects[0].pos.x-map->objects[enemy].pos.x);
		speed.y=-100*(status->objects[0].pos.y-map->objects[enemy].pos.y);
		speed.z=-100*(status->objects[0].pos.z-map->objects[enemy].pos.z);
		Move(status->objects[0].id,speed);
		return;
	};
	int ENERGY=find_ENERGY();
	if (ENERGY!=-1)
	{
		Position speed;
		speed.x=-100*(status->objects[0].pos.x-map->objects[ENERGY].pos.x);
		speed.y=-100*(status->objects[0].pos.y-map->objects[ENERGY].pos.y);
		speed.z=-100*(status->objects[0].pos.z-map->objects[ENERGY].pos.z);
		Move(status->objects[0].id,speed);
		return;
	};
	Position speed;
	speed.x=-100*(status->objects[0].pos.x-(kMapSize>>1));
	speed.y=-100*(status->objects[0].pos.y-(kMapSize>>1));
	speed.z=-100*(status->objects[0].pos.z-(kMapSize>>1));
	Move(status->objects[0].id,speed);
	return;

};
Exemplo n.º 2
0
void move()
{
    int danger = danger_move();
    if (danger != -1)
    {
        Position speed;
        speed.x = 100 * (status->objects[0].pos.x - map->objects[danger].pos.x);
        speed.y = 100 * (status->objects[0].pos.y - map->objects[danger].pos.y);
        speed.z = 100 * (status->objects[0].pos.z - map->objects[danger].pos.z);
        Move(status->objects[0].id, speed);
        return;
    };
    int enemy = find_enemy();
    if (enemy != -1)
    {
        Position speed;
        speed.x = -100 * (status->objects[0].pos.x - map->objects[enemy].pos.x);
        speed.y = -100 * (status->objects[0].pos.y - map->objects[enemy].pos.y);
        speed.z = -100 * (status->objects[0].pos.z - map->objects[enemy].pos.z);
        Move(status->objects[0].id, speed);
        return;
    };
    int ENERGY = find_ENERGY();
    if (ENERGY != -1)
    {
        Position speed;
        speed.x = -100 * (status->objects[0].pos.x - map->objects[ENERGY].pos.x);
        speed.y = -100 * (status->objects[0].pos.y - map->objects[ENERGY].pos.y);
        speed.z = -100 * (status->objects[0].pos.z - map->objects[ENERGY].pos.z);
        Move(status->objects[0].id, speed);
        return;
    };
    Position speed;
    speed.x = -100 * (status->objects[0].pos.x - (kMapSize >> 1));
    speed.y = -100 * (status->objects[0].pos.y - (kMapSize >> 1));
    speed.z = -100 * (status->objects[0].pos.z - (kMapSize >> 1));
    Move(status->objects[0].id, speed);
    return;

};
Exemplo n.º 3
0
void	play_loop(t_share *shared, t_player *player)
{
	usleep(TIME);
	lock();
	if (shared->kill == TRUE)
	{
		if (shared->nb_team == 1)
		{
			unlock();
			shared->end = TRUE;
		}
	}
	if (check_if_dead(shared, player) == -1)
	{
		shared->kill = TRUE;
		unlock();
		return ;
	}
	find_enemy(shared, player);
	move(shared, player);
	unlock();
}
Exemplo n.º 4
0
bool melee(mob_t * attacker, int speed)
{
  char line[DEFLEN];
  mob_t * target;
  int att_x;
  int range;
  int i;

  range = attacker->range;

  att_x = attacker->x;

  if (speed > 0)
    att_x++;

  for (i = 0; i < range; i++)
  {
    att_x += speed;

    target = find_enemy(attacker, player->y, att_x);

    if (target == NULL)
      continue;

    if (target->type == MOB_MIMIC && target->attack_phase == 0)
    {
      pwait("WAIT! THAT IS A SMALL MIMIC!");
      target->attack_phase = 1;
      target->flags = 0;
      return true;
    }
    else if (target->type == MOB_BLURK && target->attack_phase == 0)
    {
      draw_board_norefresh();
      pwait("OH NO! AN INSIDIOUS BLURK BARS YOUR WAY!");
      target->attack_phase = 1;
      target->flags = 0;
      return true;
    }

    // Attack!

    // The attacker must always lower their shield
    attacker->shd_up = 0;

    if (attacker == player && game->weapon > WPN_UNARMED)
    {
      damage_weapon(1);
    }

    // If the target has their shield up and they are facing each other
    if (target->shd_up && target->flip != attacker->flip)
    {
      if (shield_block(target))
      {
	mob_text(target, "BLOCK");
	damage_shield(target);

	if (target->type == MOB_KNAVE)
	{
	  if (target->attack_phase == 0)
	    target->attack_phase = 1;
	  else if (target->attack_phase == 1 || target->attack_phase == 2)
	  {
	    move_towards_player(target);
	  }
	}

	return true;
      }
    }

    damage(attacker, target);
    
    if (attacker->attack_frames == 2)
    {
      attacker->flags = GFX_ATTACK2;
      draw_board(); lpause();
      attacker->flags = 0;
    }

    attacker->flags = GFX_ATTACK;
    draw_board(); lpause();
    attacker->flags = 0;

    damage_armor(target);

    // Draining dagger restores attacker HP
    if (attacker == player && game->weapon == WPN_DRAIN)
    {
      attacker->hp += 1;
    }
    
    if (target->hp > 0)
    {
      // Keep track of who we are fighting
      if (attacker == player)
      {
	enemy_bar = target->index;
	enemy_bar_time = BAR_TIMEOUT;
	draw_bars();
      }
      else if (target == player)
      {
	enemy_bar = attacker->index;
	enemy_bar_time = BAR_TIMEOUT;
	draw_bars();
      }
    }
    
    target->flags = GFX_HURT;
    draw_board(); lpause();
    target->flags = 0;

    if (target->hp <= 0)
    {
      if (target == player)
      {
	snprintf(line, DEFLEN,
		 "YOU WERE %s\n"
		 "BY %s%s",
		 attacker->killverb,
		 article[attacker->article],
		 mob_name[attacker->type]);

	draw_bars();
	game_over(line, false);
      }
      else
      {
	kill_enemy(target);
      }
    }

    if (attacker->type == MOB_ROGUE &&
	game->player_gold > ROGUE_STEAL_GOLD &&
	rand() % 100 < ROGUE_STEAL_CHANCE)
    {
      rogue_escape(attacker);
    }
    
    return true;
  }

  return false;
}
Exemplo n.º 5
0
int shoot_missile(mob_t * attacker, int dir)
{
  char line[DEFLEN];
  mob_t * target;
  int m_y; int m_x;
  int sc_y; int sc_x;
  int count;
  int m_type;
  int adjust_y;
  int passes;
  int pass;
  int xbow;
  chtype color;
  chtype missile;

//   attacker = &game->mob[mi];

  xbow = false;
  passes = 1;

  adjust_y = water_offset(attacker);
  m_y = attacker->y;
  sc_y = m_y - view_y - 1;

  m_x = attacker->x +
    (attacker->flip ? -attacker->pack_w + 2 : attacker->pack_w - 2) +
    dir * 2;

  if (attacker->type == MOB_EYE)
  {
    m_type = MIS_DISINT;
    sc_y -= 1;
    m_x = attacker->x;
  }
  else if (attacker->type == MOB_LICH)
  {
    m_type = MIS_FIREBALL;
    sc_y -= 1;
  }
  else if (attacker == player)
  {
    if (game->weapon == WPN_BOW)
      m_type = MIS_ARROW;
    else if (game->weapon == WPN_3XBOW)
    {
      xbow = true;
      m_type = MIS_ARROW;

      if (water_offset(attacker))
	passes = 2;
      else
	passes = 3;
    }
    else if (game->weapon == WPN_BLASTER)
    {
      m_type = MIS_BLASTER;
      adjust_y -= 1;
    }
  }
  else
  {
    m_type = MIS_ARROW;
  }

  draw_board();
  
  for (pass = 0; pass < passes; pass++)
  {
    count = 0;
    
    if (xbow)
    {
      m_x = attacker->x +
	(attacker->flip ? -attacker->pack_w + 2 : attacker->pack_w - 2) +
	dir * 2;
      
      if (pass == 0)
	adjust_y = water_offset(attacker) - 1;
      else if (pass == 1)
	adjust_y = water_offset(attacker);
      else if (pass == 2)
	adjust_y = water_offset(attacker) + 1;
    }

    while (1)
    {
      m_x += dir;
      sc_x = m_x - view_x;
      count++;

      if (sc_x < 0 || sc_x >= BOARD_W)
	goto end_pass;//break;//return 0;
      
      target = find_enemy(attacker, m_y, m_x + dir);
      
      if (target == NULL)
      {
	if (game->blinded)
	  continue;
	
	if (m_type != MIS_BLASTER && count % 2 == 1)
	  continue;
	
	// Skip the length of the barrel
	if (m_type == MIS_BLASTER && count < 4)
	  continue;
	
	missile = '?';
	color = COLOR_PAIR(PAIR_GREEN);
	
	if (m_type == MIS_ARROW)
	{
	  missile = '-';
	  color = COLOR_PAIR(PAIR_MAGENTA);
	}
	if (m_type == MIS_BLASTER)
	{
	  missile = '=';
	  color = COLOR_PAIR(PAIR_MAGENTA);
	}
	else if (m_type == MIS_FIREBALL)
	{
	  missile = '*';
	  color = COLOR_PAIR(PAIR_RED);
	}
	else if (m_type == MIS_DISINT)
	{
	  missile = (dir > 0 ? '>' : '<');
	  color = COLOR_PAIR(PAIR_RED);
	}
	
	if (water_join(gtile(m_y - 1, m_x)))
	{
	  color = COLOR_PAIR(PAIR_BLACK_ON_CYAN);
	}
	
	if (m_type == MIS_BLASTER)
	{
	  mvwaddch(board, sc_y + adjust_y, sc_x, '_' | color);
/*	if (count % 2)
	mvwaddch(board, sc_y, sc_x, (dir > 0 ? ')' : '(') | color);
	else
	mvwaddch(board, sc_y - 1, sc_x, (dir > 0 ? ')' : '(') | color);*/
	}
	else
	  mvwaddch(board, sc_y + adjust_y, sc_x, missile | color);
	
	
	wrefresh(board);
	spause();
	
	continue;
      }
      
      if (target->shd_up &&
	  ((!target->flip && dir < 0) ||
	   (target->flip && dir > 0)) )
      {
	if (target == player &&
	    m_type == MIS_DISINT &&
	    target->shd_type != SHD_NONE &&
	    target->shd_type != SHD_MAGIC)
	{
	  flush_input();
	  snprintf(line, DEFLEN,
		   "DISINTEGRATION BEAM!!\n\nYOUR %s\nCRUMBLES TO DUST!",
		   armor_name[target->shd_type]);
	  pwait(line);
	  target->shd_type = SHD_NONE;
	  target->shd_up = false;
	  goto end_pass;//return true;
	}
	
	if (m_type != MIS_BLASTER && shield_block(target))
	{
	  mob_text(target, "BLOCK");
	  damage_shield(target);
	  goto end_pass; //return true;
	}
      }
      
      if (target == player && m_type == MIS_DISINT)
      {
	if (target->armor_type != ARMOR_NONE &&
	    target->armor_type != ARMOR_MAGIC)
	{
	  flush_input();
	  snprintf(line, DEFLEN,
		   "DISINTEGRATION BEAM!!\n\nYOUR %s\nCRUMBLES TO DUST!",
		   armor_name[target->armor_type]);
	  pwait(line);
	  target->armor_type = ARMOR_NONE;
	  goto end_pass;// return true;
	}
	
	if (game->weapon != WPN_UNARMED)
	{
	  flush_input();
	  snprintf(line, DEFLEN,
		   "DISINTEGRATION BEAM!!\n\nYOUR %s\nCRUMBLES TO DUST!",
		   weapon_name[game->weapon]);
	  pwait(line);
	  give_weapon(WPN_UNARMED);
	  goto end_pass; //return true;
	}
      }
      
      damage(attacker, target);
      
      if (m_type == MIS_ARROW)
      {
	target->flags = GFX_HURT;
	draw_board(); lpause();
	target->flags = 0;
      }
      else if (m_type == MIS_BLASTER)
      {
	target->flags = GFX_HURT;
	draw_board(); lpause();
	target->flags = 0;
      }
      else if (m_type == MIS_FIREBALL)
      {
	explosion(sc_y, sc_x + dir);
      }
      
      if (target == player)
      {
	draw_bars();
      }
      
      if (target->hp <= 0)
      {
	if (target == player)
	{
	  snprintf(line, DEFLEN,
		   "YOU WERE %s\n"
		   "BY %s%s",
		   (m_type == MIS_FIREBALL ? "FRIED" :
		    (m_type == MIS_DISINT ? "DISINTEGRATED" : "SHOT")),
		   article[attacker->article],
		   mob_name[attacker->type]);
	  draw_board();
	  game_over(line, false);
	}
	else
	{
	  if (!xbow || pass == passes - 1)
	    kill_enemy(target);

	  goto end_pass;
	}
      }
      else if (target != player)
      {
	enemy_bar = target->index;
	enemy_bar_time = BAR_TIMEOUT;
	draw_bars();
	
	// update the number of eyes it has
	if (target->type == MOB_BIGSPIDER)
	  draw_board();//	  draw_board();
      }

      damage_armor(target);
      goto end_pass;
    }

  end_pass:
    continue;
  }
  
//      return 1;
//    }
    
  return 1;
}
Exemplo n.º 6
0
// ------------------------------------------------------------------------
// window to display an adventure map
// ------------------------------------------------------------------------
void t_adventure_map_window::check_enemy_attack( t_army* army, t_handler enemy_attack_started_handler )
{
	if (m_attacking_enemy != 0)
		return;

	if (army->empty() || army->is_graveyard())
		return;

	t_adventure_path_finder*			 frame_path_finder;
	t_owned_ptr<t_adventure_path_finder> local_finder;
	t_adventure_path_finder*			 path_finder;
	t_adv_map_point						 point;

	point = army->get_position();
	frame_path_finder = m_frame->get_path_finder();
	if (frame_path_finder->get_army() == army)
		path_finder = frame_path_finder;
	else
	{
		local_finder.reset( new t_adventure_path_finder( *m_map ));
		path_finder = local_finder.get();
		path_finder->set_army( army );
	}

	if ( !path_finder->get_data( point ).actual_enemy_adjacent )
		return;

	// find adjacent army
	t_direction	direction;
	t_army*		enemy;

	enemy = find_enemy( *m_map, *path_finder, point, *army, &direction );
	assert( enemy != 0 );
	if (enemy == 0)
		return;

	t_level_map_point_2d enemy_position = enemy->get_position();

	if ((abs( enemy_position.row - point.row ) > 1 
		 || abs(enemy_position.column - point.column ) > 1)
		&& enemy->ai_value() * 5.0 <= army->ai_value())
	{
		if (attempt_retreat( enemy, direction, this ))
			return;
	}

	// suppress activation if the enemy is hidden, except for neutrals
	if (enemy->get_owner_number() >= 0)
	{
		int team;

		if (army->get_owner_number() < 0)
			team = -1;
		else
			team = army->get_owner()->get_team();
		if (!enemy->is_visible_to( team ))
			return;
	}

	// move enemy to attack
	t_adventure_path path;

	local_finder.reset( new t_adventure_path_finder( *m_map ));
	path_finder = local_finder.get();
	path_finder->set_army( enemy );

	path_finder->set_path_type( k_path_search_enemy_activation );
	if (!path_finder->get_path( army->get_position(), path ))
		return;

	// Allow caller to close windows and the like before combat actually starts
	enemy_attack_started_handler();

	t_counted_ptr<t_army_mover> mover;
	t_window_ptr				ref = this;

	m_attacking_enemy = enemy;
	enemy->set_path( path );
	m_map->clear_path();
	m_map->clear_selection();
	enemy->set_in_combat( true ); // make visible regardless of stealth as it attacks.
	run_object_mover( new t_enemy_army_attack( this, enemy, army ), false );
}
Exemplo n.º 7
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() );
}