Пример #1
0
FILE *fopen(const char *path, const char *mode)
{
    int fd;
    int flags = 0;
    if ( char_in('w', mode) )
	flags &= O_CREAT;
    if ( char_in('a', mode) )
	flags &= O_APPEND;
    if ((fd = openat(dir, path, flags)) == -1)
	fd = open(path, flags);
    return fdopen(fd, mode);
}
Пример #2
0
integer_t  to_i(const char* s, int radix)
{
  if ( s == NULL )
    raise(runtime_exception("Cannot convert NULL to INTEGER"));

  int has_sign = (char_in(*s, "+-"));
  int sign = (s[0]=='-'? -1 : 1);

  return sign * atoi(has_sign + s, radix);
}
Пример #3
0
char wait_for_key(const std::string& keys)
{
  char key;
  do
  {
    key = io::getchar();
  } while (!char_in(key, keys) && io::window_is_open());
  // Check for closing of window too so that we can quit the game if that happened.
  return key;
}
Пример #4
0
void item_list::execute()
{
  const std::string keys = "\x1B \nabcdefghijklmnopqrstuvwxyz<>?";
  char key = 0;
  bool done = false;

  while (!done)
  {
    print();
    key = wait_for_key(keys);

    if (char_in(key, "\x1B \n"))
    {
      if (m_examine_mode)
      {
        m_examine_mode = false;
      }
      else
      {
        break;
      }
    }

    if (key == '<')
    {
      if (m_page > 0)
      {
        m_page--;
      }
    }
    else if (key == '>')
    {
      if (m_page == 0 && m_items.size() > PAGE_SIZE)
      {
        m_page++;
      }
    }
    else if (key == '?')
    {
      m_examine_mode = !m_examine_mode;
    }
    else if (valid_entry(key))
    {
      if (!m_examine_mode)
      {
        done = handle_item(get_entry(key).item);
      }
      else
      {
        item_t* item_to_describe = get_entry(key).item;
        describe(item_to_describe);
      }
    }
  }

  if (m_action == ZAP)
  {
    if (key == '\x1B' || key == ' ' || key == '\n')
    {
      // Pop wand selection state.
      statestack_pop();
    }
  }

  // Always cancel if escape;
  if (key == '\x1B')
  {
    m_chosen_items.clear();
    return;
  }

  if (m_action == DROP)
  {
    handle_dropped();
  }
}
Пример #5
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();
    }
}
Пример #6
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.");
            }
        }
    }

}
Пример #7
0
void _read_command()
{
    const std::string move_keys = "lkjhyubn12346789";
    const std::string travel_keys = "LKJHYUBN";

    char key = io::getchar();

    if (char_in(key, move_keys))
    {
        move_player(key);
        return;
    }
    else if (char_in(key, travel_keys))
    {
        _start_travel(tolower(key), false);
        return;
    }

    if (key == ',')
    {
        do_player_pickup(player.pos.x, player.pos.y);
    }
    else if (key == 'i')
    {
        statestack_push(STATE_INVENTORY);
        show_inventory();
        statestack_pop();
    }
    else if (key == 'd')
    {
        statestack_push(STATE_DROP);
        show_inventory();
        statestack_pop();
    }
    else if (key == 'q')
    {
        statestack_push(STATE_QUAF_POTION);
        show_inventory();
        statestack_pop();
    }
    else if (key == 'e')
    {
        if (!_eat_item_on_floor())
        {
            statestack_push(STATE_EAT_FOOD);
            show_inventory();
            statestack_pop();
        }
    }
    else if (key == 'w')
    {
        statestack_push(STATE_WIELD);
        show_inventory();
        statestack_pop();
    }
    else if (key == '.')
    {
        player.ap -= player.speed;
    }
    else if (key == 'x')
    {
        init_target_cursor(player.pos.x, player.pos.y, 0);
        statestack_push(STATE_EXAMINE);
    }
    else if (key == 'r')
    {
        statestack_push(STATE_READ_SCROLL);
        show_inventory();
        statestack_pop();
    }
    else if (key == 'c')
    {
        append_msg_log("Which direction?");
        statestack_push(STATE_CLOSE_DOOR);
    }
    else if (key == 'C')
    {
        if (!autochat())
        {
            append_msg_log("Talk to whom?");
            statestack_push(STATE_CHAT);
        }
    }
    else if (key == 'z')
    {
        draw_spell_list();
    }
    else if (key == 'Z')
    {
        statestack_push(STATE_ZAP_WAND);
        show_inventory();
    }
    else if (key == '<')
    {
        if (upstairs_at(current_dungeon, player.pos.x, player.pos.y))
        {
            append_msg_log("You walk up the stairs.");

            _take_stairs(get_stairs_at(current_dungeon, player.pos.x, player.pos.y));
            player.ap -= player.speed;
        }
        else
        {
            append_msg_log("You can't walk up here!");
        }
    }
    else if (key == '>')
    {
        if (downstairs_at(current_dungeon, player.pos.x, player.pos.y))
        {
            append_msg_log("You walk down the stairs.");

            _take_stairs(get_stairs_at(current_dungeon, player.pos.x, player.pos.y));
            player.ap -= player.speed;
        }
        else
        {
            append_msg_log("You can't walk down here!");
        }
    }
    else if (key == '@')
    {
        show_character_sheet();
    }
    else if (key == '\t')
    {
        move_player_towards_closest_enemy();
    }
    else if (key == 'g')
    {
        item_t* book = item_t::create_item_by_type(ITEM_TYPE_WEAPON);
        item_t* scroll = item_t::create_item("scroll of identify");
        add_item_to_dungeon(current_dungeon, book, player.pos.x, player.pos.y);
        add_item_to_dungeon(current_dungeon, scroll, player.pos.x, player.pos.y);

//    create_effect(&player, EF_FLAME_CLOUDS, 10, 0);

//    cloud_machine_t* machine = new cloud_machine_t;
//    machine->frequency = 100;
//    machine->max_clouds_per_tick = 9;
//    machine->cloud_energy = 100;
//    machine->cloud_entropy = 0;
//    machine->variance = 0;
//    machine->pos = player.pos;
//    machine->radius = 1;
//    machine->type = CLOUD_FLAME;
//    machine->life = 5;
//    machine->cloud_symbol = '*';
//    machine->cloud_color_cycle = { color_red, color_light_red };
//
//    current_dungeon->cloud_system.add_gas_machine(machine, true);
//    item_t* weapon = item_t::create_item_by_type(ITEM_TYPE_WEAPON);
//    add_item_to_dungeon(current_dungeon, weapon, player.pos.x, player.pos.y);
    }
    else if (key == 's')
    {
        //item_t* scroll = item_t::create_item_by_type(ITEM_TYPE_SCROLL);
        //add_item_to_dungeon(current_dungeon, scroll, player.pos.x, player.pos.y);

        hide();
    }
    else if (key == 'Q')
    {
        if (yesno("Do you wish to quit the game?", true))
        {
            _game_running = false;
        }
    }
    else if (key == 'S')
    {
        if (yesno("Save and quit?", true))
        {
            save_game();
            _game_running = false;
        }
    }
    else if (key == 'M')
    {
        show_message_history();
    }
}
Пример #8
0
const char* get_token()
{
  // mutatable return buffer
  static char token[256];

  for ( ;; ) {
    token[0] = token[1] = '\0';
    source = skip_space(source);

    // comment? skip to end of line
    if ( *source == ';' ) {
      while ( *source != '\n' ) {
        ++source;

        if ( *source == '\0' )
          return NULL;
      }

      continue;
    }

    // hash-bang or similar? skip to end of line
    // TODO: Properly handle reader directives like case-folding, etc.
    if ( source[0]=='#' && source[1]=='!' ) {

      // skip to end of line
      const char *start = source;
      while ( *source != '\n' ) ++source;

      if ( !strncmp("#!fold-case", start, source - start) )
        fold_case_flag = true;
      else if ( !strncmp("#!no-fold-case", start, source - start) )
        fold_case_flag = false;

      continue;
    }

    // block-comments?
    if ( source[0]=='#' && source[1]=='|' ) {
      // match nested pairs
      source += 2;
      for ( int n=1; n && *source; ++source ) {
             if ( source[0]=='#' && source[1]=='|' ) { ++source; ++n; }
        else if ( source[0]=='|' && source[1]=='#' ) { ++source; --n; }
      }
      continue;
    }

    // vector form "#( ... )"
    if ( source[0]=='#' && source[1]=='(' ) {
      strcpy(token, "#(");
      source += 2;
      return token;
    }

    // bytevector form "#u8( ... )"
    if ( source[0]=='#' && source[1]=='u' &&
         source[2]=='8' && source[3]=='(' )
    {
      strcpy(token, "#u8(");
      source += 4;
      return token;
    }

    // ignore-next-datum form "#;"
    if ( source[0]=='#' && source[1]==';' ) {
      strcpy(token, "#;");
      source += 2;
      return token;
    }

    if ( char_in(*source, "()'") )
      // tokens ( and )
      token[0] = *source++;
    else {
      // long-form-symbol w/format "|foo bar baz|"
      if ( source[0]=='|' ) {
        const size_t lineno = line;
        token[0]='|';
        source = copy_while(token+1, source+1, sizeof(token)-2, not_pipe);

        if ( *source == '|' )
          ++source;
        else
          raise(parser_exception(format(
            "Invalid |long symbol| on line %lu\n", lineno)));

        const size_t l = strlen(token);
        token[l] = '|';
        token[l+1] = '\0';
      } else
        // other tokens
        source = copy_while(token, source, sizeof(token)-1,
                            string_or_non_delimiter);
    }

    // emit NULL when finished
    return !empty(token) ? token : NULL;
  }
}