Exemple #1
0
bool place_free(dungeon_t* dungeon, int x, int y, creature_t* creature)
{
  int index = y * dungeon->width + x;
  tile_t* tile = &dungeon->map[index];

  if (creature)
  {
    if (!tile_is_walkable_by(*tile, creature))
      return false;
  }
  else
  {
    if (!(tile->properties & TILE_PROP_WALKABLE))
      return false;
  }

  if (get_creature_at(dungeon, x, y))
    return false;

  if (player.pos.x == x && player.pos.y == y)
    return false;

  if (count_items_at(dungeon, x, y) > 0)
    return false;

  return true;
}
Exemple #2
0
bool autochat()
{
  std::vector<creature_t*> found_creatures;

  for (int y = player.pos.y - 1; y <= player.pos.y + 1; y++)
  {
    for (int x = player.pos.x - 1; x <= player.pos.x + 1; x++)
    {
      creature_t* creature = get_creature_at(current_dungeon, x, y);

      if (creature)
      {
        found_creatures.push_back(creature);
      }
    }
  }

  if (found_creatures.size() == 1)
  {
    chat(found_creatures.front());

    return true;
  }

  return false;
}
Exemple #3
0
coord_t pick_walkable_position_in_area(dungeon_t* dungeon, int start_x, int start_y, int end_x, int end_y, creature_t* creature)
{
  std::vector<coord_t> coords;

  for (int y = start_y; y < end_y; y++)
  {
    for (int x = start_x; x < end_x; x++)
    {
      if (x >= 0 && y >= 0 && x < dungeon->width && y < dungeon->height &&
          get_creature_at(dungeon, x, y) == 0)
      {
        tile_t* tile = get_tile_at(dungeon, x, y);

        if (creature && tile_is_walkable_by(*tile, creature))
        {
          coord_t coord = {x, y};
          coords.push_back(coord);
        }
      }
    }
  }

  if (coords.size() > 0)
  {
    std::random_shuffle(coords.begin(), coords.end());

    return coords.front();
  }

  coord_t bad = {-1, -1};

  return bad;
}
Exemple #4
0
bool CCreature::trymove( int relative_x, int relative_y )
{
    if(main_map.get_grid_at(x + relative_x,y + relative_y) == WALL_CHAR)
        return false;
    if (get_creature_at(x + relative_x, y + relative_y))
        return false;
    unmap();
    x += relative_x; y += relative_y;
    map();
    return true;
}
int _is_ally_in_ray(creature_t* caster, creature_t* target)
{
  int x, y;
  TCODLine::init(caster->pos.x, caster->pos.y, target->pos.x, target->pos.y);
  while (!TCODLine::step(&x, &y))
  {
    creature_t* creature = get_creature_at(current_dungeon, x, y);
    if (creature && creature_t::is_allies(caster, creature))
      return 1;
  }
  return 0;
}
Exemple #6
0
bool CCreature::tryattack( int relative_x, int relative_y )
{
    if (! (relative_x != 0) ^ (relative_y != 0))
        return false;
    if(abs(relative_x) > 1 || abs(relative_y) > 1)
        return false;
    CCreature * creat = get_creature_at(x + relative_x, y + relative_y);
    if (!creat)
        return false;
    //disp.gameprintf("%s attacks %s.", get_name(), creat->get_name());
    creat->takedamage(get_attack_dmg(), get_AP());
    return true;
}
Exemple #7
0
coord_t _get_random_walkable_for_item(dungeon_t* dungeon)
{
  int px, py;
  do
  {
    px = random(0, dungeon->width - 1);
    py = random(0, dungeon->height - 1);
  } while (!(get_tile_at(dungeon, px, py)->properties & TILE_PROP_WALKABLE) || get_creature_at(dungeon, px, py));

  coord_t coord = { px, py };

  return coord;
}
Exemple #8
0
void creature_t::try_move(int move_x, int move_y)
{
  tile_t* tile = get_tile_at(current_dungeon, move_x, move_y);
  if (tile && (tile_is_walkable_by(*tile, this)))
  {
    creature_t* thing = get_creature_at(current_dungeon, move_x, move_y);
    if (thing)
    {
      if (get_active_effects_for(this) & EF_CONFUSE)
      {
        creature_attacks(this, thing);
      }
      else if ((is_ally() && !thing->is_ally()) || (!is_ally() && thing->is_ally()))
      {
        // The two creatures are enemies.
        creature_attacks(this, thing);
      }
    }
    else if (player.pos.x == move_x && player.pos.y == move_y)
    {
      if (!is_friendly() || (get_active_effects_for(this) & EF_CONFUSE))
      {
        // Not ally with player, or confused.
        creature_attacks(this, &player);
      }
    }
    else
    {
      pos.x = move_x;
      pos.y = move_y;
    }
  }
  else if (tile && tile->id == TILE_DOOR_CLOSED)
  {
    if (flag & CF_INTELLIGENT)
    {
      open_door(current_dungeon, this, move_x, move_y);
      //creature->pos.x = move_x;
      //creature->pos.y = move_y;
    }
  }
}
Exemple #9
0
void _take_stairs(stairs_t* stairs)
{
    dungeon_t* prev_dungeon = current_dungeon;

    TRACE("take_stairs: stairs->to_branch=%s", stairs->to_branch.c_str());

    // Arrive from town to infinite dungeon: clear infinite dungeon.
    if (stairs->to && stairs->to_branch == BRANCH_INFINITE_DUNGEON && current_branch->name != BRANCH_INFINITE_DUNGEON)
    {
        stairs->to = nullptr;
        branch_t* inf_branch = find_branch(stairs->to_branch);

        for (dungeon_t* dungeon : inf_branch->dungeons)
        {
            destroy_dungeon(dungeon);
        }
        inf_branch->dungeons.clear();
    }

    // Generate the next dungeon if needed.
    if (stairs->to == nullptr && stairs->to_branch == current_branch->name)
    {
        dungeon_t* next_level = generate_next_level(current_branch);
        create_up_stairs(next_level, current_branch, prev_dungeon, stairs);
    }
    else if (stairs->to == nullptr)
    {
        // Stairs to a new branch.
        branch_t* prev_branch = current_branch;
        current_branch = create_branch(stairs->to_branch);

        dungeon_t* next_level = current_branch->dungeons.front();

        // Check if the level has stairs that lead back to the branch already.
        bool has_stairs = false;
        for (int i = 0; i < next_level->num_stairs; i++)
        {
            if (next_level->stairs[i]->to_branch == prev_branch->name)
                has_stairs = true;
        }

        if (!has_stairs)
            create_up_stairs(next_level, prev_branch, prev_dungeon, stairs);
        else
            stairs->to = next_level;
    }

    dungeon_t* dst = stairs->to;
    current_dungeon = dst;
    current_branch = find_branch(stairs->to_branch);

    player.pos.x = stairs->warp_x;
    player.pos.y = stairs->warp_y;

    // Do not follow player to the world map.
    if (current_branch->name != "World")
    {
        std::vector<coord_t> free_coords;
        for (int y = player.pos.y - 1; y <= player.pos.y + 1; y++)
            for (int x = player.pos.x - 1; x <= player.pos.x + 1; x++)
                if (place_free(current_dungeon, x, y))
                    free_coords.push_back( coord_t { x, y} );

        std::vector<creature_t*> following_creatures;
        for (int y = stairs->y - 1; y <= stairs->y + 1; y++)
        {
            for (int x = stairs->x - 1; x <= stairs->x + 1; x++)
            {
                creature_t* creature = get_creature_at(prev_dungeon, x, y);

                if (creature && following_creatures.size() < free_coords.size())
                {
                    following_creatures.push_back(creature);
                    remove_creature_no_destroy(prev_dungeon, creature);
                }
            }
        }

        for (size_t i = 0; i < following_creatures.size(); i++)
        {
            add_creature_to_dungeon(current_dungeon, following_creatures[i], free_coords[i].x, free_coords[i].y);
        }

        if (following_creatures.size() == 1)
            append_msg_log("%s follows you.", capitalize(following_creatures.front()->get_full_name()).c_str());
        else if (following_creatures.size() > 1)
            append_msg_log("Some creatures follow you.");
    }

    clear_action_list();
    append_action_list(&player);
}
Exemple #10
0
void _select_direction()
{
    const std::string move_keys = "lkjhyubn12346789";
    int state = statestack_top();

    char key = io::getchar();

    if (char_in(key, move_keys))
    {
        if (state == STATE_CLOSE_DOOR)
        {
            int x, y;
            x = player.pos.x;
            y = player.pos.y;

            compute_xy_by_direction(direction_from_key(key), &x, &y);

            tile_t* tile = get_tile_at(current_dungeon, x, y);
            if (tile->id == TILE_DOOR_OPEN)
            {
                if (place_free(current_dungeon, x, y)
                        && count_items_at(current_dungeon, x, y) == 0)
                {
                    close_door(current_dungeon, &player, x, y);
                    player.ap -= player.speed;
                }
                else
                {
                    append_msg_log("The door is blocked!");
                }
            }
            else if (tile->id == TILE_DOOR_CLOSED)
            {
                append_msg_log("That door is already closed.");
            }
            else
            {
                append_msg_log("There is no door there!");
            }
            statestack_pop();
        }
        else if (state == STATE_CHAT)
        {
            int x = player.pos.x;
            int y = player.pos.y;

            compute_xy_by_direction(direction_from_key(key), &x, &y);
            creature_t* creature = get_creature_at(current_dungeon, x, y);

            if (creature)
            {
                chat(creature);
            }
            else
            {
                append_msg_log("There is no one there to talk to!");
            }

            statestack_pop();
        }

        return;
    }

    if (key == '\x1B')
    {
        append_msg_log("Nevermind.");
        statestack_pop();
    }
}
Exemple #11
0
void _move_targeting_cursor()
{
    coord_t old_target = target_cursor_position();
    const std::string move_keys = "lkjhyubn12346789vg";
    int state = statestack_top();

    char key = io::getchar();

    if (key == 'v' && state == STATE_EXAMINE)
    {
        coord_t pos = target_cursor_position();
        creature_t* creature_at_tile = get_creature_at(current_dungeon, pos.x, pos.y);
        if (creature_at_tile)
        {
            describe(creature_at_tile);
        }

        // Print tile info after so it doesn't dissapear.
        _examine_tile(pos.x, pos.y);
    }
    else if (key == 'g' && state == STATE_EXAMINE)
    {
        coord_t pos = target_cursor_position();

        if (position_in_fov(current_dungeon, pos.x, pos.y))
        {
            statestack_pop();

            _start_travel(0, true, pos.x, pos.y);
        }
        else
        {
            append_msg_log("You can't travel where you can't see!");
        }
    }
    else if (char_in(key, "<>") && state == STATE_EXAMINE)
    {
        for (int y = 0; y < current_dungeon->height; y++)
        {
            for (int x = 0; x < current_dungeon->width; x++)
            {
                const tile_t* tile = get_tile_at(current_dungeon, x, y);
                TileType tile_type = key == '<' ? TILE_STAIRS_UP : TILE_STAIRS_DOWN;

                if (tile->id == tile_type && position_in_fov(current_dungeon, x, y))
                {
                    init_target_cursor(x, y, false);
                }
            }
        }
    }
    else if (char_in(key, move_keys))
    {
        move_target_cursor(direction_from_key(key));

        if (state == STATE_EXAMINE)
        {
            coord_t target_coord = target_cursor_position();
            _examine_tile(target_coord.x, target_coord.y);
        }
        else if (state == STATE_ZAP_WAND)
        {
            coord_t target_coord = target_cursor_position();
            const spell_t* wand_spell = get_spell_for_wand(get_current_wand());

            if (wand_spell)
            {
                if (!in_range_of_spell(wand_spell, &player, target_coord.x,
                                       target_coord.y))
                {
                    init_target_cursor(old_target.x, old_target.y, true);
                }
            }
        }
        else if (state == STATE_CAST_SPELL)
        {
            coord_t target_coord = target_cursor_position();
            if (!in_range_of_spell(current_spell, &player, target_coord.x,
                                   target_coord.y))
            {
                init_target_cursor(old_target.x, old_target.y,
                                   spell_is_ray_or_missile(current_spell));
            }
        }

        return;
    }

    if (key == '\x1B')
    {
        statestack_pop();
    }
    else if (key == ' ' || key == '\n')
    {
        // What this does depends on state.
        if (state == STATE_EXAMINE)
        {
            statestack_pop();
        }
        else if (state == STATE_ZAP_WAND)
        {
            const spell_t* wand_spell = get_spell_for_wand(get_current_wand());

            coord_t target_coord = target_cursor_position();
            if (wand_spell && in_range_of_spell(wand_spell, &player, target_coord.x,
                                                target_coord.y))
            {
                if (fov_value_at(current_dungeon, target_coord.x, target_coord.y) == LIT)
                {
                    fire_wand(get_current_wand(), &player, target_coord);

                    statestack_pop();
                }
                else
                {
                    append_msg_log("You can't fire your wand where you cannot see.");
                }
            }
            else
            {
                append_msg_log("Out of range.");
            }
        }
        else if (state == STATE_CAST_SPELL)
        {
            coord_t target_coord = target_cursor_position();
            if (in_range_of_spell(current_spell, &player, target_coord.x,
                                  target_coord.y))
            {
                if (fov_value_at(current_dungeon, target_coord.x, target_coord.y) == LIT)
                {
                    cast_spell(current_spell, &player, target_coord.x, target_coord.y);
                    statestack_pop();
                }
                else
                {
                    append_msg_log("You can't cast a spell where you cannot see.");
                }
            }
            else
            {
                append_msg_log("Out of range.");
            }
        }
    }

}