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); }
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); }
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; }
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(); } }
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(); } }
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."); } } } }
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(); } }
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; } }