static int do_cmd_squelch_aux(void) { int i, j, temp, num, max_num; int col, row; int typeval; cptr tval_desc; char ch, sq; int choice[60]; char buf[160]; byte color; /* Clear screen */ Term_clear(); /* * Print all typeval's and their descriptions * * This uses the above arrays. I combined a few of the * tvals into single typevals. */ for (num = 0; (num<60) && typevals[num].tval; num++) { row = 3 + (num % 20); col = 30 * (num / 20); ch = head[num/26] +num%26; prt(format("[%c] %s", ch, typevals[num].desc), row, col); } /* We need to know the maximal possible tval_index */ max_num = num; /* Choose! */ if (!get_com("Squelch what type of object? (Q: Secondary Menu for Weapons and Armour) ", &ch)) return (0); if (ch=='Q') { /* Switch to secondary squelching menu */ do_qual_squelch(); } else { /* Analyze choice */ num = ch-'a'; /* Bail out if choice is illegal */ if ((num < 0) || (num >= max_num)) return (0); /* Base object type chosen, fill in tval */ typeval = typevals[num].tval; tval_desc = typevals[num].desc; /*** And now we go for k_idx ***/ /* Clear screen */ while (1) { Term_clear(); /* First sort based on value */ /* Step 1: Read into choice array */ for (num = 0, i = 1; (num < 60) && (i < MAX_K_IDX); i++) { object_kind *k_ptr = &k_info[i]; if (tv_to_type[k_ptr->tval] == typeval) { if (k_ptr->flags3 & (TR3_INSTA_ART)) continue; if (!(k_ptr->aware)) continue; choice[num++] = i; } } max_num = num; /* Step 2: Simple bubble sort */ for (i=0; i<max_num; i++) { for (j=i; j<max_num; j++) { if ((k_info[choice[i]].tval>k_info[choice[j]].tval) || ((k_info[choice[i]].tval==k_info[choice[j]].tval) && (k_info[choice[i]].cost>k_info[choice[j]].cost))) { temp = choice[i]; choice[i] = choice[j]; choice[j] = temp; } } } if (!max_num) c_put_str(TERM_RED, "No known objects of this type.", 3, 0); else { for (num = 0; num<max_num; num++) { object_kind *k_ptr = &k_info[choice[num]]; /* Prepare it */ row = 3 + (num % 20); col = 30 * (num / 20); ch = head[num/26] + (num%26); /* Acquire the "name" of object "i" */ strip_name(buf, choice[num]); /* Get the squelch character */ sq = (k_ptr->squelch ? '*' : ' '); /* Get the color */ color = (k_ptr->squelch ? TERM_RED : TERM_L_GREEN); /* Print it */ prt(format("[%c%c] ", ch, sq), row, col); c_put_str(color, buf, row, col+5); } /* Print the legend */ prt("'*': Squelch ' ': Do not squelch", 1, 0); } /* Choose! */ if (!get_com(format("%s : Command? (^A: Squelch all ^U: Unsquelch all)", tval_desc), &ch)) return (1); if (ch==KTRL('A')) { /* ^A --> Squelch all items */ for (i=0; i<max_num; i++) { k_info[choice[i]].squelch = TRUE; } } else if (ch==KTRL('U')) { /* ^U --> Unsquelch all items */ for (i=0; i<max_num; i++) { k_info[choice[i]].squelch = FALSE; } } else { /* Analyze choice */ num = -1; if ((ch >= head[0]) && (ch < head[0] + 26)) num = ch - head[0]; if ((ch >= head[1]) && (ch < head[1] + 26)) num = ch - head[1] + 26; if ((ch >= head[2]) && (ch < head[2] + 17)) num = ch - head[2] + 52; /* Bail out if choice is "illegal" */ if ((num < 0) || (num >= max_num)) return (1); /* Toggle */ k_info[choice[num]].squelch = (k_info[choice[num]].squelch ? FALSE : TRUE); } } } /* And return successful */ return (1); }
/*! * @brief セーブデータ読み込みのメインルーチン / * Attempt to Load a "savefile" * @return 成功すればtrue * @details * <pre> * Version 2.7.0 introduced a slightly different "savefile" format from * older versions, requiring a completely different parsing method. * * Note that savefiles from 2.7.0 - 2.7.2 are completely obsolete. * * Pre-2.8.0 savefiles lose some data, see "load2.c" for info. * * Pre-2.7.0 savefiles lose a lot of things, see "load1.c" for info. * * On multi-user systems, you may only "read" a savefile if you will be * allowed to "write" it later, this prevents painful situations in which * the player loads a savefile belonging to someone else, and then is not * allowed to save his game when he quits. * * We return "TRUE" if the savefile was usable, and we set the global * flag "character_loaded" if a real, living, character was loaded. * * Note that we always try to load the "current" savefile, even if * there is no such file, so we must check for "empty" savefile names. * </pre> */ bool load_player(void) { int fd = -1; errr err = 0; byte vvv[4]; #ifdef VERIFY_TIMESTAMP struct stat statbuf; #endif cptr what = "generic"; /* Paranoia */ turn = 0; /* Paranoia */ p_ptr->is_dead = FALSE; /* Allow empty savefile name */ if (!savefile[0]) return (TRUE); #if !defined(MACINTOSH) && !defined(WINDOWS) /* XXX XXX XXX Fix this */ /* Verify the existance of the savefile */ if (access(savefile, 0) < 0) { /* Give a message */ msg_print(_("セーブファイルがありません。", "Savefile does not exist.")); msg_print(NULL); /* Allow this */ return (TRUE); } #endif #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (!err) { FILE *fkk; char temp[1024]; /* Extract name of lock file */ strcpy(temp, savefile); strcat(temp, ".lok"); /* Check for lock */ fkk = my_fopen(temp, "r"); /* Oops, lock exists */ if (fkk) { /* Close the file */ my_fclose(fkk); /* Message */ msg_print(_("セーブファイルは現在使用中です。", "Savefile is currently in use.")); msg_print(NULL); /* Oops */ return (FALSE); } /* Create a lock file */ fkk = my_fopen(temp, "w"); /* Dump a line of info */ fprintf(fkk, "Lock file for savefile '%s'\n", savefile); /* Close the lock file */ my_fclose(fkk); } #endif /* Okay */ if (!err) { /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* No file */ if (fd < 0) err = -1; /* Message (below) */ if (err) what = _("セーブファイルを開けません。", "Cannot open savefile"); } /* Process file */ if (!err) { #ifdef VERIFY_TIMESTAMP /* Get the timestamp */ (void)fstat(fd, &statbuf); #endif /* Read the first four bytes */ if (fd_read(fd, (char*)(vvv), 4)) err = -1; /* What */ if (err) what = _("セーブファイルを読めません。", "Cannot read savefile"); /* Close the file */ (void)fd_close(fd); } /* Process file */ if (!err) { /* Extract version */ z_major = vvv[0]; z_minor = vvv[1]; z_patch = vvv[2]; sf_extra = vvv[3]; /* Clear screen */ Term_clear(); /* Attempt to load */ err = rd_savefile_new(); /* Message (below) */ if (err) what = _("セーブファイルを解析出来ません。", "Cannot parse savefile"); } /* Paranoia */ if (!err) { /* Invalid turn */ if (!turn) err = -1; /* Message (below) */ if (err) what = _("セーブファイルが壊れています", "Broken savefile"); } #ifdef VERIFY_TIMESTAMP /* Verify timestamp */ if (!err && !arg_wizard) { /* Hack -- Verify the timestamp */ if (sf_when > (statbuf.st_ctime + 100) || sf_when < (statbuf.st_ctime - 100)) { /* Message */ what = _("無効なタイム・スタンプです", "Invalid timestamp"); /* Oops */ err = -1; } } #endif /* Okay */ if (!err) { /* Give a conversion warning */ if ((FAKE_VER_MAJOR != z_major) || (FAKE_VER_MINOR != z_minor) || (FAKE_VER_PATCH != z_patch)) { if (z_major == 2 && z_minor == 0 && z_patch == 6) { msg_print(_("バージョン 2.0.* 用のセーブファイルを変換しました。", "Converted a 2.0.* savefile.")); } else { /* Message */ #ifdef JP msg_format("バージョン %d.%d.%d 用のセーブ・ファイルを変換しました。", (z_major > 9) ? z_major-10 : z_major , z_minor, z_patch); #else msg_format("Converted a %d.%d.%d savefile.", (z_major > 9) ? z_major-10 : z_major , z_minor, z_patch); #endif } msg_print(NULL); } /* Player is dead */ if (p_ptr->is_dead) { /* Cheat death */ if (arg_wizard) { /* A character was loaded */ character_loaded = TRUE; /* Done */ return (TRUE); } /* Player is no longer "dead" */ p_ptr->is_dead = FALSE; /* Count lives */ sf_lives++; /* Done */ return (TRUE); } /* A character was loaded */ character_loaded = TRUE; { u32b tmp = counts_read(2); if (tmp > p_ptr->count) p_ptr->count = tmp; if (counts_read(0) > playtime || counts_read(1) == playtime) counts_write(2, ++p_ptr->count); counts_write(1, playtime); } /* Success */ return (TRUE); } #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (TRUE) { char temp[1024]; /* Extract name of lock file */ strcpy(temp, savefile); strcat(temp, ".lok"); /* Remove lock */ fd_kill(temp); } #endif /* Message */ #ifdef JP msg_format("エラー(%s)がバージョン%d.%d.%d 用セーブファイル読み込み中に発生。", what, (z_major>9) ? z_major - 10 : z_major, z_minor, z_patch); #else msg_format("Error (%s) reading %d.%d.%d savefile.", what, (z_major>9) ? z_major - 10 : z_major, z_minor, z_patch); #endif msg_print(NULL); /* Oops */ return (FALSE); }
/* * Recursive file perusal. * * Return FALSE on "?", otherwise TRUE. * * This function could be made much more efficient with the use of "seek" * functionality, especially when moving backwards through a file, or * forwards through a file by less than a page at a time. XXX XXX XXX */ bool show_file(const char *name, const char *what, int line, int mode) { int i, k, n; struct keypress ch; /* Number of "real" lines passed by */ int next = 0; /* Number of "real" lines in the file */ int size; /* Backup value for "line" */ int back = 0; /* This screen has sub-screens */ bool menu = FALSE; /* Case sensitive search */ bool case_sensitive = FALSE; /* Current help file */ ang_file *fff = NULL; /* Find this string (if any) */ char *find = NULL; /* Jump to this tag */ const char *tag = NULL; /* Hold a string to find */ char finder[80] = ""; /* Hold a string to show */ char shower[80] = ""; /* Filename */ char filename[1024]; /* Describe this thing */ char caption[128] = ""; /* Path buffer */ char path[1024]; /* General buffer */ char buf[1024]; /* Lower case version of the buffer, for searching */ char lc_buf[1024]; /* Sub-menu information */ char hook[26][32]; int wid, hgt; /* TRUE if we are inside a RST block that should be skipped */ bool skip_lines = FALSE; /* Wipe the hooks */ for (i = 0; i < 26; i++) hook[i][0] = '\0'; /* Get size */ Term_get_size(&wid, &hgt); /* Copy the filename */ my_strcpy(filename, name, sizeof(filename)); n = strlen(filename); /* Extract the tag from the filename */ for (i = 0; i < n; i++) { if (filename[i] == '#') { filename[i] = '\0'; tag = filename + i + 1; break; } } /* Redirect the name */ name = filename; /* Hack XXX XXX XXX */ if (what) { my_strcpy(caption, what, sizeof(caption)); my_strcpy(path, name, sizeof(path)); fff = file_open(path, MODE_READ, FTYPE_TEXT); } /* Look in "help" */ if (!fff) { strnfmt(caption, sizeof(caption), "Help file '%s'", name); path_build(path, sizeof(path), ANGBAND_DIR_HELP, name); fff = file_open(path, MODE_READ, FTYPE_TEXT); } /* Look in "info" */ if (!fff) { strnfmt(caption, sizeof(caption), "Info file '%s'", name); path_build(path, sizeof(path), ANGBAND_DIR_INFO, name); fff = file_open(path, MODE_READ, FTYPE_TEXT); } /* Oops */ if (!fff) { /* Message */ msg("Cannot open '%s'.", name); event_signal(EVENT_MESSAGE_FLUSH); /* Oops */ return (TRUE); } /* Pre-Parse the file */ while (TRUE) { /* Read a line or stop */ if (!file_getl(fff, buf, sizeof(buf))) break; /* Skip lines if we are inside a RST directive*/ if(skip_lines){ if(contains_only_spaces(buf)) skip_lines=FALSE; continue; } /* Parse a very small subset of RST */ /* TODO: should be more flexible */ if (prefix(buf, ".. ")) { /* parse ".. menu:: [x] filename.txt" (with exact spacing)*/ if(prefix(buf+strlen(".. "), "menu:: [") && buf[strlen(".. menu:: [x")]==']') { /* This is a menu file */ menu = TRUE; /* Extract the menu item */ k = A2I(buf[strlen(".. menu:: [")]); /* Store the menu item (if valid) */ if ((k >= 0) && (k < 26)) my_strcpy(hook[k], buf + strlen(".. menu:: [x] "), sizeof(hook[0])); } /* parse ".. _some_hyperlink_target:" */ else if (buf[strlen(".. ")] == '_') { if (tag) { /* Remove the closing '>' of the tag */ buf[strlen(buf) - 1] = '\0'; /* Compare with the requested tag */ if (streq(buf + strlen(".. _"), tag)) { /* Remember the tagged line */ line = next; } } } /* Skip this and enter skip mode*/ skip_lines = TRUE; continue; } /* Count the "real" lines */ next++; } /* Save the number of "real" lines */ size = next; /* Display the file */ while (TRUE) { /* Clear screen */ Term_clear(); /* Restrict the visible range */ if (line > (size - (hgt - 4))) line = size - (hgt - 4); if (line < 0) line = 0; skip_lines = FALSE; /* Re-open the file if needed */ if (next > line) { /* Close it */ file_close(fff); /* Hack -- Re-Open the file */ fff = file_open(path, MODE_READ, FTYPE_TEXT); if (!fff) return (TRUE); /* File has been restarted */ next = 0; } /* Goto the selected line */ while (next < line) { /* Get a line */ if (!file_getl(fff, buf, sizeof(buf))) break; /* Skip lines if we are inside a RST directive*/ if(skip_lines){ if(contains_only_spaces(buf)) skip_lines=FALSE; continue; } /* Skip RST directives */ if (prefix(buf, ".. ")) { skip_lines=TRUE; continue; } /* Count the lines */ next++; } /* Dump the next lines of the file */ for (i = 0; i < hgt - 4; ) { /* Hack -- track the "first" line */ if (!i) line = next; /* Get a line of the file or stop */ if (!file_getl(fff, buf, sizeof(buf))) break; /* Skip lines if we are inside a RST directive*/ if(skip_lines){ if(contains_only_spaces(buf)) skip_lines=FALSE; continue; } /* Skip RST directives */ if (prefix(buf, ".. ")) { skip_lines=TRUE; continue; } /* skip | characters */ strskip(buf,'|'); /* escape backslashes */ strescape(buf,'\\'); /* Count the "real" lines */ next++; /* Make a copy of the current line for searching */ my_strcpy(lc_buf, buf, sizeof(lc_buf)); /* Make the line lower case */ if (!case_sensitive) string_lower(lc_buf); /* Hack -- keep searching */ if (find && !i && !strstr(lc_buf, find)) continue; /* Hack -- stop searching */ find = NULL; /* Dump the line */ Term_putstr(0, i+2, -1, COLOUR_WHITE, buf); /* Highlight "shower" */ if (shower[0]) { const char *str = lc_buf; /* Display matches */ while ((str = strstr(str, shower)) != NULL) { int len = strlen(shower); /* Display the match */ Term_putstr(str-lc_buf, i+2, len, COLOUR_YELLOW, &buf[str-lc_buf]); /* Advance */ str += len; } } /* Count the printed lines */ i++; } /* Hack -- failed search */ if (find) { bell("Search string not found!"); line = back; find = NULL; continue; } /* Show a general "title" */ prt(format("[%s, %s, Line %d-%d/%d]", buildid, caption, line, line + hgt - 4, size), 0, 0); /* Prompt -- menu screen */ if (menu) { /* Wait for it */ prt("[Press a Letter, or ESC to exit.]", hgt - 1, 0); } /* Prompt -- small files */ else if (size <= hgt - 4) { /* Wait for it */ prt("[Press ESC to exit.]", hgt - 1, 0); } /* Prompt -- large files */ else { /* Wait for it */ prt("[Press Space to advance, or ESC to exit.]", hgt - 1, 0); } /* Get a keypress */ ch = inkey(); /* Exit the help */ if (ch.code == '?') break; /* Toggle case sensitive on/off */ if (ch.code == '!') { case_sensitive = !case_sensitive; } /* Try showing */ if (ch.code == '&') { /* Get "shower" */ prt("Show: ", hgt - 1, 0); (void)askfor_aux(shower, sizeof(shower), NULL); /* Make the "shower" lowercase */ if (!case_sensitive) string_lower(shower); } /* Try finding */ if (ch.code == '/') { /* Get "finder" */ prt("Find: ", hgt - 1, 0); if (askfor_aux(finder, sizeof(finder), NULL)) { /* Find it */ find = finder; back = line; line = line + 1; /* Make the "finder" lowercase */ if (!case_sensitive) string_lower(finder); /* Show it */ my_strcpy(shower, finder, sizeof(shower)); } } /* Go to a specific line */ if (ch.code == '#') { char tmp[80] = "0"; prt("Goto Line: ", hgt - 1, 0); if (askfor_aux(tmp, sizeof(tmp), NULL)) line = atoi(tmp); } /* Go to a specific file */ if (ch.code == '%') { char ftmp[80] = "help.hlp"; prt("Goto File: ", hgt - 1, 0); if (askfor_aux(ftmp, sizeof(ftmp), NULL)) { if (!show_file(ftmp, NULL, 0, mode)) ch.code = ESCAPE; } } switch (ch.code) { /* up a line */ case ARROW_UP: case '8': line--; break; /* up a page */ case KC_PGUP: case '9': case '-': line -= (hgt - 4); break; /* home */ case KC_HOME: case '7': line = 0; break; /* down a line */ case ARROW_DOWN: case '2': case KC_ENTER: line++; break; /* down a page */ case KC_PGDOWN: case '3': case ' ': line += hgt - 4; break; /* end */ case KC_END: case '1': line = size; break; } /* Recurse on letters */ if (menu && isalpha((unsigned char)ch.code)) { /* Extract the requested menu item */ k = A2I(ch.code); /* Verify the menu item */ if ((k >= 0) && (k <= 25) && hook[k][0]) { /* Recurse on that file */ if (!show_file(hook[k], NULL, 0, mode)) ch.code = ESCAPE; } } /* Exit on escape */ if (ch.code == ESCAPE) break; } /* Close the file */ file_close(fff); /* Done */ return (ch.code != '?'); }
/* Handles all of the display functionality for the history list. */ void history_display(void) { int row, wid, hgt, page_size; char buf[90]; static size_t first_item = 0; size_t max_item = last_printable_item(); size_t i; Term_get_size(&wid, &hgt); /* Six lines provide space for the header and footer */ page_size = hgt - 6; screen_save(); while (1) { struct keypress ch; Term_clear(); /* Print everything to screen */ print_history_header(); row = 0; for (i = first_item; row <= page_size && i < history_ctr; i++) { char location[30]; /* Skip messages about artifacts not yet IDed. */ if (history_masked(i)) continue; /* Get location name */ history_get_place(location, sizeof(location), i); strnfmt(buf, sizeof(buf), "%10d%22s%5d %s", history_list[i].turn, location, history_list[i].clev, history_list[i].event); if (history_list[i].type & HISTORY_ARTIFACT_LOST) my_strcat(buf, " (LOST)", sizeof(buf)); /* Size of header = 5 lines */ prt(buf, row + 5, 0); row++; } prt("[Arrow keys scroll, p for previous page, n for next page, ESC to exit.]", hgt - 1, 0); ch = inkey(); if (ch.code == 'n') { size_t scroll_to = first_item + page_size; while (history_masked(scroll_to) && scroll_to < history_ctr - 1) scroll_to++; first_item = (scroll_to < max_item ? scroll_to : max_item); } else if (ch.code == 'p') { int scroll_to = first_item - page_size; while (history_masked(scroll_to) && scroll_to > 0) scroll_to--; first_item = (scroll_to >= 0 ? scroll_to : 0); } else if (ch.code == ARROW_DOWN) { size_t scroll_to = first_item + 1; while (history_masked(scroll_to) && scroll_to < history_ctr - 1) scroll_to++; first_item = (scroll_to < max_item ? scroll_to : max_item); } else if (ch.code == ARROW_UP) { int scroll_to = first_item - 1; while (history_masked(scroll_to) && scroll_to > 0) scroll_to--; first_item = (scroll_to >= 0 ? scroll_to : 0); } else if (ch.code == ESCAPE) break; } screen_load(); return; }
static void fix_m_list(void) { s32b i, j; /* Scan windows */ for (j = 0; j < 8; j++) { term *old = Term; s32b c = 0; /* No window */ if (!angband_term[j]) continue; /* No relevant flags */ if (!flag_exists(&window_flag[j], FLAG_PW_M_LIST)) continue; /* Activate */ Term_activate(angband_term[j]); /* Clear */ Term_clear(); /* Hallucination */ if (intrinsic(HALLUCINATE)) { c_prt(TERM_WHITE, "You can not see clearly", 0, 0); /* Fresh */ Term_fresh(); /* Restore */ Term_activate(old); return; } /* reset visible count */ for (i = 1; i < max_r_idx; i++) { monster_race *r_ptr = &r_info[i]; r_ptr->total_visible = 0; } /* Count up the number visible in each race */ for_flags(&monst_list); { i = __key; monster_type *m_ptr = get_monster(i); monster_race *r_ptr = &r_info[m_ptr->r_idx]; object_type *o_ptr = get_obj_mimic_obj_at(m_ptr->fy, m_ptr->fx); /* Skip dead monsters */ if (m_ptr->hp < 0) continue; /* Skip unseen monsters */ if (o_ptr != NULL && !o_ptr->marked) { /* Memorized objects */ if (!o_ptr->marked) continue; } else if (!m_ptr->ml) continue; /* Increase for this race */ r_ptr->total_visible++; /* Increase total Count */ c++; } end_for_flags(); /* Are monsters visible? */ if (c) { s32b w, h, num = 0; (void)Term_get_size(&w, &h); c_prt(TERM_WHITE, format("You can see %d monster%s", c, (c > 1 ? "s:" : ":")), 0, 0); for (i = 1; i < max_r_idx; i++) { monster_race *r_ptr = &r_info[i]; /* Default Colour */ byte attr = TERM_SLATE; /* Only visible monsters */ if (!r_ptr->total_visible) continue; /* Uniques */ if (has_flag(r_ptr, FLAG_UNIQUE)) { attr = TERM_L_BLUE; } /* Have we ever killed one? */ if (r_ptr->r_tkills) { if (r_ptr->level > dun_level) { attr = TERM_VIOLET; if (has_flag(r_ptr, FLAG_UNIQUE)) { attr = TERM_RED; } } } else { if (!has_flag(r_ptr, FLAG_UNIQUE)) attr = TERM_GREEN; } /* Dump the monster name */ if (r_ptr->total_visible == 1) { c_prt(attr, (r_ptr->name), (num % (h - 1)) + 1, (num / (h - 1) * 26)); } else { c_prt(attr, format("%s (x%d)", r_ptr->name, r_ptr->total_visible), (num % (h - 1)) + 1, (num / (h - 1)) * 26); } num++; } } else { c_prt(TERM_WHITE, "You see no monsters.", 0, 0); } /* Fresh */ Term_fresh(); /* Restore */ Term_activate(old); } }
/* * Draw the skill tree */ void print_skills(int table[MAX_SKILLS][2], int max, int sel, int start) { int i, j; int wid, hgt; cptr keys; Term_clear(); Term_get_size(&wid, &hgt); c_prt(TERM_WHITE, format("%s Skills Screen", game_module), 0, 28); keys = format("#BEnter#W to develop a branch, #Bup#W/#Bdown#W to move, #Bright#W/#Bleft#W to modify, #B?#W for help"); display_message(0, 1, strlen(keys), TERM_WHITE, keys); c_prt((p_ptr->skill_points) ? TERM_L_BLUE : TERM_L_RED, format("Skill points left: %d", p_ptr->skill_points), 2, 0); print_desc_aux(s_info[table[sel][0]].desc + s_text, 3, 0); for (j = start; j < start + (hgt - 7); j++) { byte color = TERM_WHITE; char deb = ' ', end = ' '; if (j >= max) break; i = table[j][0]; if ((s_info[i].value == 0) && (i != SKILL_MISC)) { if (s_info[i].mod == 0) color = TERM_L_DARK; else color = TERM_ORANGE; } else if (s_info[i].value == SKILL_MAX) color = TERM_L_BLUE; if (s_info[i].hidden) color = TERM_L_RED; if (j == sel) { color = TERM_L_GREEN; deb = '['; end = ']'; } if (!has_child(i)) { c_prt(color, format("%c.%c%s", deb, end, s_info[i].name + s_name), j + 7 - start, table[j][1] * 4); } else if (s_info[i].dev) { c_prt(color, format("%c-%c%s", deb, end, s_info[i].name + s_name), j + 7 - start, table[j][1] * 4); } else { c_prt(color, format("%c+%c%s", deb, end, s_info[i].name + s_name), j + 7 - start, table[j][1] * 4); } c_prt(color, format("%s%02ld.%03ld [%01d.%03d]", s_info[i].value < 0 ? "-" : " ", ABS(s_info[i].value) / SKILL_STEP, ABS(s_info[i].value) % SKILL_STEP, ABS(s_info[i].mod) / 1000, ABS(s_info[i].mod) % 1000), j + 7 - start, 60); } }
static void choose_melee() { int i, j, z = 0; character_icky = TRUE; Term_save(); Term_clear(); j = get_melee_skills(); prt("Choose a melee style:", 0, 0); for (i = 0; i < MAX_MELEE; i++) { if (melee_bool[i]) { prt(format("%c) %s", I2A(z), melee_names[i]), z + 1, 0); melee_num[z] = i; z++; } } while (TRUE) { char c = inkey(); if (c == ESCAPE) break; if (A2I(c) < 0) continue; if (A2I(c) >= j) continue; for (i = 0, z = 0; z < A2I(c); i++) if (melee_bool[i]) z++; for (i = INVEN_WIELD; p_ptr->body_parts[i - INVEN_WIELD] == INVEN_WIELD; i++) { if (p_ptr->inventory[i].k_idx) { if (cursed_p(&p_ptr->inventory[i])) { char name[80]; object_desc(name, &p_ptr->inventory[i], 0, 0); msg_format("Hmmm, your %s seems to be cursed.", name); break; } else { inven_takeoff(i, 255, FALSE); } } } p_ptr->melee_style = melee_skills[melee_num[z]]; energy_use = 100; break; } /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Recalculate hitpoint */ p_ptr->update |= (PU_HP); /* Redraw monster hitpoint */ p_ptr->redraw |= (PR_MH); Term_load(); character_icky = FALSE; }
/* * Interreact with abilitiess */ void do_cmd_ability() { s32b sel = 0, start = 0, max = 0; s32b c; s32b *table; s32b i; s32b wid, hgt; if(!&ab_info[0]) { msg_print("There are no abilities for you to learn!"); return; } C_MAKE(table, max_ab_idx, s32b); /* Initialise the abilities list */ for (i = 0; i < max_ab_idx; i++) { if (ab_info[i].name && (wizard || (!ab_info[i].hidden && show_ability(i)))) add_sorted_ability(table, &max, i); } if (max == 0) { C_FREE(table, max_ab_idx, s32b); msg_print("There are no abilities for you to learn!"); return; } /* Save the screen */ screen_save(); /* Clear the screen */ Term_clear(); while (TRUE) { Term_get_size(&wid, &hgt); /* Display list of skills */ print_abilities(table, max, sel, start); /* Wait for user input */ c = inkey(); /* Leave the skill screen */ if (c == ESCAPE) break; /* Next page */ else if (c == 'n') { sel += (hgt - 7); if (sel >= max) sel = max - 1; } /* Previous page */ else if (c == 'p') { sel -= (hgt - 7); if (sel < 0) sel = 0; } /* Select / increase a skill */ else { s32b dir; /* Allow use of numpad / arrow keys / roguelike keys */ dir = get_keymap_dir(c); /* Move cursor down */ if (dir == 2) sel++; /* Move cursor up */ if (dir == 8) sel--; /* gain ability */ if (dir == 6) gain_ability(table[sel]); /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ if (wizard && (c == '+')) ab_info[table[sel]].acquired = TRUE; if (wizard && (c == '-')) ab_info[table[sel]].acquired = FALSE; /* Contextual help */ if (c == '?') exec_lua(format("ingame_help('select_context', 'ability', '%s')", ab_info[table[sel]].name)); ; /* Handle boundaries and scrolling */ if (sel < 0) sel = max - 1; if (sel >= max) sel = 0; if (sel < start) start = sel; if (sel >= start + (hgt - 7)) start = sel - (hgt - 7) + 1; } } /* Load the screen */ screen_load(); C_FREE(table, max_ab_idx, s32b); /* Update stuffs */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_POWERS | PU_SANITY | PU_BODY); /* Redraw various info */ flag_bool(&p_ptr->redraw, FLAG_PR_WIPE); flag_bool(&p_ptr->redraw, FLAG_PR_BASIC); flag_bool(&p_ptr->redraw, FLAG_PR_EXTRA); flag_bool(&p_ptr->redraw, FLAG_PR_MAP); }
static void print_all(s32b **table, s32b max, s32b table_ab[], s32b max_ab, s32b sel, s32b start) { s32b i, j; s32b wid, hgt; cptr keys; Term_clear(); Term_get_size(&wid, &hgt); c_prt(TERM_WHITE, format("%s Skills and Abilities Screen", game_module), 0, 24); keys = format("#BEnter#W to develop a branch, #Bup#W/#Bdown#W to move, #Bright#W/#Bleft#W to modify, #B?#W for help"); display_message(0, 1, strlen(keys), TERM_WHITE, keys); c_prt((p_ptr->skill_points) ? TERM_L_BLUE : TERM_L_RED, format("Skill points left: %d", p_ptr->skill_points), 2, 0); if (sel == 0) { c_prt(TERM_YELLOW, "Skills represent your level of proficiency in the various fields of mastery", 3, 0); c_prt(TERM_YELLOW, "available to your character.", 4, 0); c_prt(TERM_YELLOW, format("Skills can naturally be raised to %ld.", SKILL_MAX / SKILL_STEP), 5, 0); } else if (sel == max) { c_prt(TERM_YELLOW, "Abilities are various traits your character may acquire. Contrary to skills", 3, 0); c_prt(TERM_YELLOW, "abilities are on/off toggles, you either now them or not, there is no level", 4, 0); c_prt(TERM_YELLOW, "involved.", 5, 0); } else if (sel < max) print_desc_aux(s_info[table[sel-1][0]].desc, 3, 0); else print_desc_aux(ab_info[table_ab[sel-1 - max]].desc, 3, 0); for (j = start; j < start + (hgt - 7); j++) { byte color = TERM_WHITE; char deb = ' ', end = ' '; if ((j == 0) && max) { deb = end = '-'; color = TERM_YELLOW; if (j == sel) { color = TERM_ORANGE; deb = '['; end = ']'; } c_prt(color, format("%c-%c---------------------------------------------------------------------- Skills", deb, end), j + 7 - start, 0); } else if ((j == max) && max_ab) { deb = end = '-'; color = TERM_YELLOW; if (j == sel) { color = TERM_ORANGE; deb = '['; end = ']'; } c_prt(color, format("%c-%c------------------------------------------------------------------- Abilities", deb, end), j + 7 - start, 0); } else if (j < max) { i = table[j-1][0]; if (get_skill(i) == 0) { if (s_info[i].mod == 0) color = TERM_L_DARK; else color = TERM_ORANGE; } else if (get_skill_raw(i) == SKILL_MAX) color = TERM_L_BLUE; if (s_info[i].hidden) color = TERM_L_RED; if (j == sel) { color = TERM_L_GREEN; deb = '['; end = ']'; } if (!has_child(i)) { c_prt(color, format("%c.%c%s", deb, end, s_info[i].name), j + 7 - start, table[j-1][1] * 4); } else if (s_info[i].dev) { c_prt(color, format("%c-%c%s", deb, end, s_info[i].name), j + 7 - start, table[j-1][1] * 4); } else { c_prt(color, format("%c+%c%s", deb, end, s_info[i].name), j + 7 - start, table[j-1][1] * 4); } c_prt(color, format("%c%02ld.%03ld [%01d.%03d]", (get_skill_raw(i) < 0) ? '-' : ' ', abs(get_skill_raw(i)) / SKILL_STEP, abs(get_skill_raw(i)) % SKILL_STEP, s_info[i].mod / 1000, s_info[i].mod % 1000), j + 7 - start, 60); } else { byte color = TERM_WHITE; char deb = ' ', end = ' '; if (j - max >= max_ab) break; i = table_ab[j-1 - max]; if (ab_info[i].acquired) color = TERM_L_BLUE; else if (can_learn_ability(i)) color = TERM_WHITE; else color = TERM_L_DARK; if (j == sel) { color = TERM_L_GREEN; deb = '['; end = ']'; } c_prt(color, format("%c.%c%s", deb, end, ab_info[i].name), j + 7 - start, 0); if (!ab_info[i].acquired) { c_prt(color, format("%d", ab_info[i].cost), j + 7 - start, 61); } else { c_prt(color, "Known", j + 7 - start, 61); } } } }
/** * Display a "tomb-stone" */ static void print_tomb(void) { cptr p; int offset = 12; char tmp[160]; char buf[1024]; ang_file *fp; #ifdef _WIN32_WCE time_t ct = fake_time((time_t) 0); #else time_t ct = time((time_t) 0); #endif bool boat = ((p_ptr->total_winner) && (player_has(PF_ELVEN))); bool tree = ((p_ptr->total_winner) && (player_has(PF_WOODEN) || player_has(PF_DIVINE))); /* Clear screen */ Term_clear(); /* Build the filename */ if (tree) path_build(buf, 1024, ANGBAND_DIR_FILE, "tree.txt"); else if (boat) path_build(buf, 1024, ANGBAND_DIR_FILE, "boat.txt"); else path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt"); /* Open the News file */ fp = file_open(buf, MODE_READ, FTYPE_TEXT); /* Dump */ if (fp) { int i, y, x; byte a = 0; char c = ' '; bool okay = TRUE; int len; /* Load the screen */ for (y = 0; okay; y++) { /* Get a line of data */ if (!file_getl(fp, buf, 1024)) okay = FALSE; /* Stop on blank line */ if (!buf[0]) break; /* Get the width */ len = strlen(buf); /* XXX Restrict to current screen size */ if (len >= Term->wid) len = Term->wid; /* Show each row */ for (x = 0; x < len; x++) { /* Put the attr/char */ Term_draw(x, y, TERM_WHITE, buf[x]); } } /* Get the blank line */ /* if (my_fgets(fp, buf, 1024)) okay = FALSE; */ /* Load the screen */ for (y = 0; okay; y++) { /* Get a line of data */ if (!file_getl(fp, buf, 1024)) okay = FALSE; /* Stop on blank line */ if (!buf[0]) break; /* Get the width */ len = strlen(buf); /* XXX Restrict to current screen size */ if (len >= Term->wid) len = Term->wid; /* Show each row */ for (x = 0; x < len; x++) { /* Get the attr/char */ (void) (Term_what(x, y, &a, &c)); /* Look up the attr */ for (i = 0; i < 16; i++) { /* Use attr matches */ if (hack[i] == buf[x]) a = i; } /* Put the attr/char */ Term_draw(x, y, a, c); } /* Place the cursor */ Term_gotoxy(x, y); } /* Get the blank line */ /* if (my_fgets(fp, buf, 1024)) okay = FALSE; */ /* Close it */ file_close(fp); } /* King or Queen */ if (p_ptr->total_winner || (p_ptr->lev > PY_MAX_LEVEL)) { p = "Magnificent"; } /* Normal */ else { p = cp_ptr->title[(p_ptr->lev - 1) / 5]; } /* Set offset */ offset = 11; center_string(buf, op_ptr->full_name); put_str(buf, 6, offset); center_string(buf, "the"); put_str(buf, 7, offset); center_string(buf, p); put_str(buf, 8, offset); center_string(buf, cp_ptr->name); put_str(buf, 10, offset); sprintf(tmp, "Level: %d", (int) p_ptr->lev); center_string(buf, tmp); put_str(buf, 11, offset); sprintf(tmp, "Exp: %ld", (long) p_ptr->exp); center_string(buf, tmp); put_str(buf, 12, offset); sprintf(tmp, "AU: %ld", (long) p_ptr->au); center_string(buf, tmp); put_str(buf, 13, offset); if (p_ptr->depth) sprintf(tmp, "Killed in %s level %d", locality_name[stage_map[p_ptr->stage][LOCALITY]], p_ptr->depth); else if (boat) sprintf(tmp, "Sailed victorious to Aman."); else if (tree) sprintf(tmp, "Retired to Fangorn Forest."); else sprintf(tmp, "Killed in %s town", locality_name[stage_map[p_ptr->stage][LOCALITY]]); center_string(buf, tmp); put_str(buf, 14, offset); if (!(boat || tree)) { sprintf(tmp, "by %s.", p_ptr->died_from); center_string(buf, tmp); put_str(buf, 15, offset); } #ifdef _WIN32_WCE { char *fake_ctime(const unsigned long *fake_time_t); sprintf(tmp, "%-.24s", fake_ctime(&ct)); } #else sprintf(tmp, "%-.24s", ctime(&ct)); #endif center_string(buf, tmp); put_str(buf, 17, offset); }
/** * Display some character info */ static void death_info(const char *title, int row) { int i, j, k, which = 0; object_type *o_ptr; store_type *st_ptr; ui_event_data ke; bool done = FALSE; /* Get the store number of the home */ if (OPT(adult_dungeon)) which = NUM_TOWNS_SMALL * 4 + STORE_HOME; else { for (i = 0; i < NUM_TOWNS; i++) { /* Found the town */ if (p_ptr->home == towns[i]) { which += (i < NUM_TOWNS_SMALL ? 3 : STORE_HOME); break; } /* Next town */ else which += (i < NUM_TOWNS_SMALL ? MAX_STORES_SMALL : MAX_STORES_BIG); } } /* Activate the store */ st_ptr = &store[which]; screen_save(); /* Display player */ display_player(0); /* Prompt for inventory */ prt("Hit any key to see more information (ESC to abort): ", 0, 0); /* Buttons */ button_backup_all(); button_kill_all(); button_add("ESC", ESCAPE); button_add("Continue", 'q'); /* Allow abort at this point */ ke = inkey_ex(); if (ke.key == ESCAPE) done = TRUE; /* Show equipment and inventory */ /* Equipment -- if any */ if ((p_ptr->equip_cnt) && !done) { Term_clear(); item_tester_full = TRUE; show_equip(OLIST_WEIGHT); prt("You are using: -more-", 0, 0); ke = inkey_ex(); if (ke.key == ESCAPE) done = TRUE; } /* Inventory -- if any */ if ((p_ptr->inven_cnt) && !done) { Term_clear(); item_tester_full = TRUE; show_inven(OLIST_WEIGHT); prt("You are carrying: -more-", 0, 0); ke = inkey_ex(); if (ke.key == ESCAPE) done = TRUE; } /* Home -- if anything there */ if ((st_ptr->stock_num) && !done) { /* Display contents of the home */ for (k = 0, i = 0; i < st_ptr->stock_num; k++) { /* Clear screen */ Term_clear(); /* Show 12 items */ for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++) { byte attr; char o_name[80]; char tmp_val[80]; /* Get the object */ o_ptr = &st_ptr->stock[i]; /* Print header, clear line */ sprintf(tmp_val, "%c) ", I2A(j)); prt(tmp_val, j + 2, 4); /* Get the object description */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Get the inventory color */ attr = tval_to_attr[o_ptr->tval & 0x7F]; /* Display the object */ c_put_str(attr, o_name, j + 2, 7); } /* Caption */ prt(format("Your home contains (page %d): -more-", k + 1), 0, 0); /* Wait for it */ ke = inkey_ex(); if (ke.key == ESCAPE) done = TRUE; } } screen_load(); }
/** * Save a "bones" file for a dead character. Now activated and (slightly) * altered. Allows the inclusion of personalized strings. */ static void make_bones(void) { ang_file *fp; char str[1024]; ui_event_data answer; byte choice = 0; int i; /* Ignore wizards and borgs */ if (!(p_ptr->noscore & 0x00FF)) { /* Ignore people who die in town */ if (p_ptr->depth) { int level; char tmp[128]; /* Slightly more tenacious saving routine. */ for (i = 0; i < 5; i++) { /* Ghost hovers near level of death. */ if (i == 0) level = p_ptr->depth; else level = p_ptr->depth + 5 - damroll(2, 4); if (level < 1) level = randint1(4); /* XXX XXX XXX "Bones" name */ sprintf(tmp, "bone.%03d", level); /* Build the filename */ path_build(str, 1024, ANGBAND_DIR_BONE, tmp); /* Attempt to open the bones file */ fp = file_open(str, MODE_READ, FTYPE_TEXT); /* Close it right away */ if (fp) file_close(fp); /* Do not over-write a previous ghost */ if (fp) continue; /* If no file by that name exists, we can make a new one. */ if (!(fp)) break; } /* Failure */ if (fp) return; /* Try to write a new "Bones File" */ fp = file_open(str, MODE_WRITE, FTYPE_TEXT); /* Not allowed to write it? Weird. */ if (!fp) return; /* Save the info */ if (op_ptr->full_name[0] != '\0') file_putf(fp, "%s\n", op_ptr->full_name); else file_putf(fp, "Anonymous\n"); file_putf(fp, "%d\n", p_ptr->psex); file_putf(fp, "%d\n", p_ptr->prace); file_putf(fp, "%d\n", p_ptr->pclass); /* Clear screen */ Term_clear(); while (1) { /* Ask the player if he wants to add a personalized string. */ prt("Information about your character has been saved", 15, 0); prt("in a bones file. Would you like to give the", 16, 0); prt("ghost a special message or description? (yes/no)", 17, 0); button_add("Yes", 'y'); button_add("No", 'n'); answer = inkey_ex(); /* Clear last line */ clear_from(15); clear_from(16); /* Determine what the personalized string will be used for. */ if ((answer.key == 'Y') || (answer.key == 'y')) { prt("Will you add something for your ghost to say,", 15, 0); prt("or add to the monster description?", 16, 0); prt("((M)essage/(D)escription)", 17, 0); /* Buttons */ button_kill('y'); button_kill('n'); button_add("M", 'M'); button_add("D", 'D'); button_add("ESC", ESCAPE); while (1) { answer = inkey_ex(); clear_from(15); clear_from(16); if ((answer.key == 'M') || (answer.key == 'm')) { choice = 1; break; } else if ((answer.key == 'D') || (answer.key == 'd')) { choice = 2; break; } else { choice = 0; break; } } } else if ((answer.key == 'N') || (answer.key == 'n') || (answer.key == ESCAPE)) { choice = 0; break; } button_kill_all(); /* If requested, get the personalized string, and write it and * info on how it should be used in the bones file. Otherwise, * indicate the absence of such a string. */ if (choice) file_putf(fp, "%d:%s\n", choice, get_personalized_string(choice)); else file_putf(fp, "0: \n"); /* Close and save the Bones file */ file_close(fp); return; } } } }
/* * Recursive file perusal. * * Return FALSE on "ESCAPE", otherwise TRUE. * * Process various special text in the input file, including the "menu" * structures used by the "help file" system. * * This function could be made much more efficient with the use of "seek" * functionality, especially when moving backwards through a file, or * forwards through a file by less than a page at a time. XXX XXX XXX * * Consider using a temporary file, in which special lines do not appear, * and which could be pre-padded to 80 characters per line, to allow the * use of perfect seeking. XXX XXX XXX * * Allow the user to "save" the current file. XXX XXX XXX */ bool show_file(cptr name, cptr what, int line, int mode) { int i, k, n; char ch; /* Number of "real" lines passed by */ int next = 0; /* Number of "real" lines in the file */ int size; /* Backup value for "line" */ int back = 0; /* This screen has sub-screens */ bool menu = FALSE; /* Case sensitive search */ bool case_sensitive = FALSE; /* Current help file */ FILE *fff = NULL; /* Find this string (if any) */ char *find = NULL; /* Jump to this tag */ cptr tag = NULL; /* Hold a string to find */ char finder[80]; /* Hold a string to show */ char shower[80]; /* Filename */ char filename[1024]; /* Describe this thing */ char caption[128]; /* Path buffer */ char path[1024]; /* General buffer */ char buf[1024]; /* Lower case version of the buffer, for searching */ char lc_buf[1024]; /* Sub-menu information */ char hook[10][32]; int wid, hgt; /* Wipe finder */ strcpy(finder, ""); /* Wipe shower */ strcpy(shower, ""); /* Wipe caption */ strcpy(caption, ""); /* Wipe the hooks */ for (i = 0; i < 10; i++) hook[i][0] = '\0'; /* Get size */ Term_get_size(&wid, &hgt); /* Copy the filename */ my_strcpy(filename, name, sizeof(filename)); n = strlen(filename); /* Extract the tag from the filename */ for (i = 0; i < n; i++) { if (filename[i] == '#') { filename[i] = '\0'; tag = filename + i + 1; break; } } /* Redirect the name */ name = filename; /* Hack XXX XXX XXX */ if (what) { /* Caption */ my_strcpy(caption, what, sizeof(caption)); /* Get the filename */ my_strcpy(path, name, sizeof(path)); /* Open */ fff = my_fopen(path, "r"); } /* Look in "help" */ if (!fff) { /* Caption */ strnfmt(caption, sizeof(caption), "Help file '%s'", name); /* Build the filename */ path_build(path, sizeof(path), ANGBAND_DIR_HELP, name); /* Open the file */ fff = my_fopen(path, "r"); } /* Look in "info" */ if (!fff) { /* Caption */ strnfmt(caption, sizeof(caption), "Info file '%s'", name); /* Build the filename */ path_build(path, sizeof(path), ANGBAND_DIR_INFO, name); /* Open the file */ fff = my_fopen(path, "r"); } /* Oops */ if (!fff) { /* Message */ msg_format("Cannot open '%s'.", name); message_flush(); /* Oops */ return (TRUE); } /* Pre-Parse the file */ while (TRUE) { /* Read a line or stop */ if (my_fgets(fff, buf, sizeof(buf))) break; /* XXX Parse "menu" items */ if (prefix(buf, "***** ")) { char b1 = '[', b2 = ']'; /* Notice "menu" requests */ if ((buf[6] == b1) && isdigit((unsigned char)buf[7]) && (buf[8] == b2) && (buf[9] == ' ')) { /* This is a menu file */ menu = TRUE; /* Extract the menu item */ k = D2I(buf[7]); /* Extract the menu item */ my_strcpy(hook[k], buf + 10, sizeof(hook[0])); } /* Notice "tag" requests */ else if (buf[6] == '<') { if (tag) { /* Remove the closing '>' of the tag */ buf[strlen(buf) - 1] = '\0'; /* Compare with the requested tag */ if (streq(buf + 7, tag)) { /* Remember the tagged line */ line = next; } } } /* Skip this */ continue; } /* Count the "real" lines */ next++; } /* Save the number of "real" lines */ size = next; /* Display the file */ while (TRUE) { /* Clear screen */ Term_clear(); /* Restart when necessary */ if (line >= size) line = 0; /* Re-open the file if needed */ if (next > line) { /* Close it */ my_fclose(fff); /* Hack -- Re-Open the file */ fff = my_fopen(path, "r"); /* Oops */ if (!fff) return (TRUE); /* File has been restarted */ next = 0; } /* Goto the selected line */ while (next < line) { /* Get a line */ if (my_fgets(fff, buf, sizeof(buf))) break; /* Skip tags/links */ if (prefix(buf, "***** ")) continue; /* Count the lines */ next++; } /* Dump the next lines of the file */ for (i = 0; i < hgt - 4; ) { /* Hack -- track the "first" line */ if (!i) line = next; /* Get a line of the file or stop */ if (my_fgets(fff, buf, sizeof(buf))) break; /* Hack -- skip "special" lines */ if (prefix(buf, "***** ")) continue; /* Count the "real" lines */ next++; /* Make a copy of the current line for searching */ my_strcpy(lc_buf, buf, sizeof(lc_buf)); /* Make the line lower case */ if (!case_sensitive) string_lower(lc_buf); /* Hack -- keep searching */ if (find && !i && !strstr(lc_buf, find)) continue; /* Hack -- stop searching */ find = NULL; /* Dump the line */ Term_putstr(0, i+2, -1, TERM_WHITE, buf); /* Hilite "shower" */ if (shower[0]) { cptr str = lc_buf; /* Display matches */ while ((str = strstr(str, shower)) != NULL) { int len = strlen(shower); /* Display the match */ Term_putstr(str-lc_buf, i+2, len, TERM_YELLOW, &buf[str-lc_buf]); /* Advance */ str += len; } } /* Count the printed lines */ i++; } /* Hack -- failed search */ if (find) { bell("Search string not found!"); line = back; find = NULL; continue; } /* Show a general "title" */ prt(format("[%s %s, %s, Line %d/%d]", VERSION_NAME, VERSION_STRING, caption, line, size), 0, 0); /* Prompt -- menu screen */ if (menu) { /* Wait for it */ prt("[Press a Number, or ESC to exit.]", hgt - 1, 0); } /* Prompt -- small files */ else if (size <= hgt - 4) { /* Wait for it */ prt("[Press ESC to exit.]", hgt - 1, 0); } /* Prompt -- large files */ else { /* Wait for it */ prt("[Press Space to advance, or ESC to exit.]", hgt - 1, 0); } /* Get a keypress */ ch = inkey(); /* Return to last screen */ if (ch == '?') break; /* Toggle case sensitive on/off */ if (ch == '!') { case_sensitive = !case_sensitive; } /* Try showing */ if (ch == '&') { /* Get "shower" */ prt("Show: ", hgt - 1, 0); (void)askfor_aux(shower, sizeof(shower)); /* Make the "shower" lowercase */ if (!case_sensitive) string_lower(shower); } /* Try finding */ if (ch == '/') { /* Get "finder" */ prt("Find: ", hgt - 1, 0); if (askfor_aux(finder, sizeof(finder))) { /* Find it */ find = finder; back = line; line = line + 1; /* Make the "finder" lowercase */ if (!case_sensitive) string_lower(finder); /* Show it */ my_strcpy(shower, finder, sizeof(shower)); } } /* Go to a specific line */ if (ch == '#') { char tmp[80]; prt("Goto Line: ", hgt - 1, 0); strcpy(tmp, "0"); if (askfor_aux(tmp, sizeof(tmp))) { line = atoi(tmp); } } /* Go to a specific file */ if (ch == '%') { char ftmp[80]; prt("Goto File: ", hgt - 1, 0); strcpy(ftmp, "help.hlp"); if (askfor_aux(ftmp, sizeof(ftmp))) { if (!show_file(ftmp, NULL, 0, mode)) ch = ESCAPE; } } /* Back up one line */ if (ch == '=') { line = line - 1; if (line < 0) line = 0; } /* Back up one half page */ if (ch == '_') { line = line - ((hgt - 4) / 2); if (line < 0) line = 0; } /* Back up one full page */ if (ch == '-') { line = line - (hgt - 4); if (line < 0) line = 0; } /* Advance one line */ if ((ch == '\n') || (ch == '\r')) { line = line + 1; } /* Advance one half page */ if (ch == '+') { line = line + ((hgt - 4) / 2); if (line < 0) line = 0; } /* Advance one full page */ if (ch == ' ') { line = line + (hgt - 4); } /* Recurse on numbers */ if (menu && isdigit((unsigned char)ch) && hook[D2I(ch)][0]) { /* Recurse on that file */ if (!show_file(hook[D2I(ch)], NULL, 0, mode)) ch = ESCAPE; } /* Exit on escape */ if (ch == ESCAPE) break; } /* Close the file */ my_fclose(fff); /* Done */ return (ch != ESCAPE); }
static int do_qual_squelch(void) { int i, index; int col, row; char ch; char squelch_str[5] = "NCVGA"; int num=0; int max_num=0; index = 0; while (1) { /* Clear screen */ Term_clear(); /* Print all tval's and their descriptions */ for (num = 0; (num<60) && tvals[num].tval; num++) { row = 2 + (num % 20); col = 30 * (num / 20); prt(format("(%c): %s", squelch_str[squelch_level[num]], tvals[num].desc), row, col); } /* Print out the rest of the screen */ prt("Legend:", 2, 30); prt("N : Squelch Nothing", 4, 30); prt("C : Squelch Cursed Items", 5, 30); prt("V : Squelch Average and Below", 6, 30); prt("G : Squelch Good and Below", 7, 30); prt("A : Squelch All but Artifacts", 8, 30); prt("Commands:", 11, 30); prt("Arrows: Move and adjust settings", 13, 30); prt("ncvga : Change a single setting", 14, 30); prt("NCVGA : Change all settings", 15, 30); prt("ESC : Exit Secondary Menu", 17, 30); prt("Secondary Squelching Menu: Weapons/Armor (Squelch only after identify)", 0,0); /* Need to know maximum index */ max_num=num; /* Place the cursor */ move_cursor(index+ 2, 1); /* Get a key */ ch = inkey(); /* Analyze */ switch (ch) { case ESCAPE: { return 0; } case 'n': { squelch_level[index] = SQUELCH_NONE; break; } case 'N': { for (i=0; i<24; i++) { squelch_level[i] = SQUELCH_NONE; } break; } case 'c': { squelch_level[index] = SQUELCH_CURSED; break; } case 'C': { for (i=0; i<24; i++) { squelch_level[i] = SQUELCH_CURSED; } break; } case 'v': { squelch_level[index] = SQUELCH_AVERAGE; break; } case 'V': { for (i=0; i<24; i++) { squelch_level[i] = SQUELCH_AVERAGE; } break; } case 'g': { squelch_level[index] = SQUELCH_GOOD; break; } case 'G': { for (i=0; i<24; i++) { squelch_level[i] = SQUELCH_GOOD; } break; } case 'a': { squelch_level[index] = SQUELCH_ALL; break; } case 'A': { for (i=0; i<24; i++) { squelch_level[i] = SQUELCH_ALL; } break; } case '-': case '8': { index = (max_num + index - 1) % max_num; break; } case ' ': case '\n': case '\r': case '2': { index = (index + 1) % max_num; break; } case '6': { squelch_level[index] = (squelch_level[index]+1)%(SQUELCH_ALL+1); break; } case '4': { squelch_level[index] = (SQUELCH_ALL+squelch_level[index])%(SQUELCH_ALL+1); break; } default: { bell(""); break; } } } }
/* * Helper function for 'player_birth()'. * * This function allows the player to select a sex, race, and house, and * modify options (including the birth options). */ static bool player_birth_aux_1(void) { int i, j; int phase = 1; /*** Instructions ***/ /* Clear screen */ Term_clear(); /* Display some helpful information */ Term_putstr(QUESTION_COL, HEADER_ROW, -1, TERM_L_BLUE, "Character Creation:"); Term_putstr(QUESTION_COL, INSTRUCT_ROW, -1, TERM_SLATE, "Arrow keys navigate the menu Enter select the current menu item"); Term_putstr(QUESTION_COL, INSTRUCT_ROW + 1, -1, TERM_SLATE, " * random menu item ESC restart the character"); Term_putstr(QUESTION_COL, INSTRUCT_ROW + 2, -1, TERM_SLATE, " = game options q quit"); /* Hack - highlight the key names */ Term_putstr(QUESTION_COL + 0, INSTRUCT_ROW, - 1, TERM_L_WHITE, "Arrow keys"); Term_putstr(QUESTION_COL + 32, INSTRUCT_ROW, - 1, TERM_L_WHITE, "Enter"); Term_putstr(QUESTION_COL + 9, INSTRUCT_ROW + 1, - 1, TERM_L_WHITE, "*"); Term_putstr(QUESTION_COL + 34, INSTRUCT_ROW + 1, - 1, TERM_L_WHITE, "ESC"); Term_putstr(QUESTION_COL + 9, INSTRUCT_ROW + 2, - 1, TERM_L_WHITE, "O"); Term_putstr(QUESTION_COL + 36, INSTRUCT_ROW + 2, - 1, TERM_L_WHITE, "q"); // Set blank sex info for new characters // hack to see whether we are opening an old player file if (!p_ptr->age) { p_ptr->psex = SEX_UNDEFINED; sp_ptr = &sex_info[SEX_UNDEFINED]; } // Or default to previous sex for old characters else { sp_ptr = &sex_info[p_ptr->psex]; } while (phase <= 2) { clear_question(); if (phase == 1) { /* Choose the player's race */ if (!get_player_race()) { continue; } /* Clean up */ clear_question(); phase++; } if (phase == 2) { /* Choose the player's house */ if (!get_player_house()) { phase--; continue; } /* Clean up */ clear_question(); phase++; } } /* Clear the base values of the skills */ for (i = 0; i < A_MAX; i++) p_ptr->skill_base[i] = 0; /* Clear the abilities */ for (i = 0; i < S_MAX; i++) { for (j = 0; j < ABILITIES_MAX; j++) { p_ptr->innate_ability[i][j] = FALSE; p_ptr->active_ability[i][j] = FALSE; } } /* Set adult options from birth options */ for (i = OPT_BIRTH; i < OPT_CHEAT; i++) { op_ptr->opt[OPT_ADULT + (i - OPT_BIRTH)] = op_ptr->opt[i]; } /* Reset score options from cheat options */ for (i = OPT_CHEAT; i < OPT_ADULT; i++) { op_ptr->opt[OPT_SCORE + (i - OPT_CHEAT)] = op_ptr->opt[i]; } // Set a default value for hitpoint warning / delay factor unless this is an old game file if (strlen(op_ptr->full_name) == 0) { op_ptr->hitpoint_warn = 3; op_ptr->delay_factor = 5; } /* reset squelch bits */ for (i = 0; i < z_info->k_max; i++) { k_info[i].squelch = SQUELCH_NEVER; } /*Clear the squelch bytes*/ for (i = 0; i < SQUELCH_BYTES; i++) { squelch_level[i] = SQUELCH_NONE; } /* Clear the special item squelching flags */ for (i = 0; i < z_info->e_max; i++) { e_info[i].aware = FALSE; e_info[i].squelch = FALSE; } /* Clear */ Term_clear(); /* Done */ return (TRUE); }
/* * Interreact with skills */ void do_cmd_skill() { s32b sel = 0, start = 0, max, max_ab = 0; s32b c; s32b **table, *table_ab; s32b i; s32b wid, hgt; s16b skill_points_save; s32b *skill_values_save; s32b *skill_mods_save; s16b *skill_rates_save; s16b *skill_invest; s32b *skill_bonus; bool *ab_learned; recalc_skills(TRUE); /* Save the screen */ screen_save(); /* Allocate arrays to save skill values */ C_MAKE(table, max_s_idx, s32b*); for (i = 0; i < max_s_idx; i++) C_MAKE(table[i], 2, s32b); C_MAKE(skill_values_save, max_s_idx, s32b); C_MAKE(skill_mods_save, max_s_idx, s32b); C_MAKE(skill_rates_save, max_s_idx, s16b); C_MAKE(skill_invest, max_s_idx, s16b); C_MAKE(skill_bonus, max_s_idx, s32b); /* Initialise the abilities list */ C_MAKE(ab_learned, max_ab_idx, s32b); C_MAKE(table_ab, max_ab_idx, s32b); for (i = 0; i < max_ab_idx; i++) { ab_learned[i] = ab_info[i].acquired; if (ab_info[i].name && (wizard || (!ab_info[i].hidden && show_ability(i)))) add_sorted_ability(table_ab, &max_ab, i); } /* Save skill points */ skill_points_save = p_ptr->skill_points; /* Save skill values */ for (i = 0; i < max_s_idx; i++) { skill_type *s_ptr = &s_info[i]; skill_values_save[i] = s_ptr->value; skill_mods_save[i] = s_ptr->mod; skill_rates_save[i] = s_ptr->rate; skill_invest[i] = 0; } /* Clear the screen */ Term_clear(); /* Initialise the skill list */ init_table(table, &max, FALSE); if (max) max++; if (max_ab) max_ab++; if (max > 1) sel = 1; while (TRUE) { Term_get_size(&wid, &hgt); /* Display list of skills */ recalc_skills_theory(skill_invest, skill_values_save, skill_mods_save, skill_bonus); print_all(table, max, table_ab, max_ab, sel, start); /* Wait for user input */ c = inkey(); /* Leave the skill screen */ if (c == ESCAPE) break; /* Expand / collapse list of skills */ else if ((sel < max) && (sel != 0) && (c == '\r')) { if (s_info[table[sel-1][0]].dev) s_info[table[sel-1][0]].dev = FALSE; else s_info[table[sel-1][0]].dev = TRUE; init_table(table, &max, FALSE); max++; } /* Next page */ else if (c == 'n') { sel += (hgt - 7); if (sel >= max + max_ab) sel = max + max_ab - 1; } /* Previous page */ else if (c == 'p') { sel -= (hgt - 7); if (sel < 0) sel = 0; } /* Select / increase a skill */ else { s32b dir; /* Allow use of numpad / arrow keys / roguelike keys */ dir = get_keymap_dir(c); /* Move cursor down */ if (dir == 2) sel++; /* Move cursor up */ if (dir == 8) sel--; if (sel == 0 || sel == max) { // Nothing } else if (sel < max) { /* Increase the current skill */ if (dir == 6) increase_skill(table[sel-1][0], skill_invest); /* Decrease the current skill */ if (dir == 4) decrease_skill(table[sel-1][0], skill_invest); /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ /* Increase the skill */ if (wizard && (c == '+')) skill_bonus[table[sel-1][0]] += SKILL_STEP; /* Decrease the skill */ if (wizard && (c == '-')) skill_bonus[table[sel-1][0]] -= SKILL_STEP; /* Contextual help */ if (c == '?') exec_lua(format("ingame_help('select_context', 'skill', '%s')", s_info[table[sel-1][0]].name)); } else { /* Gain ability */ if (dir == 6) gain_ability(table_ab[sel-1 - max]); if (dir == 4) ungain_ability(table_ab[sel-1 - max], ab_learned[table_ab[sel-1 - max]]); /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ if (wizard && (c == '+')) ab_info[table_ab[sel-1 - max]].acquired = TRUE; if (wizard && (c == '-')) ab_info[table_ab[sel-1 - max]].acquired = FALSE; /* Contextual help */ if (c == '?') exec_lua(format("ingame_help('select_context', 'ability', '%s')", ab_info[table_ab[sel-1 - max]].name)); } /* Handle boundaries and scrolling */ if (sel < 0) sel = max + max_ab - 1; /* Just in case the skill and ability list is empty */ if (sel < 0) sel = 0; if (sel >= max + max_ab) sel = 0; if (sel < start) start = sel; if (sel >= start + (hgt - 7)) start = sel - (hgt - 7) + 1; } } /* Some skill points are spent */ if (p_ptr->skill_points != skill_points_save) { /* Flush input as we ask an important and irreversible question */ flush(); /* Ask we can commit the change */ if (msg_box("Save and use these skill values? (y/n)", (s32b)(hgt / 2), (s32b)(wid / 2)) != 'y') { /* User declines -- restore the skill values before exiting */ /* Restore skill points */ p_ptr->skill_points = skill_points_save; /* Restore skill values */ for (i = 0; i < max_s_idx; i++) { skill_type *s_ptr = &s_info[i]; s_ptr->value = skill_values_save[i]; s_ptr->mod = skill_mods_save[i]; s_ptr->rate = skill_rates_save[i]; } /* Restore abilities */ for (i = 0; i < max_ab_idx; i++) { ab_info[i].acquired = ab_learned[i]; } } } /* Free arrays to save skill values */ C_FREE(skill_values_save, max_s_idx, s32b); C_FREE(skill_mods_save, max_s_idx, s32b); C_FREE(skill_rates_save, max_s_idx, s16b); C_FREE(skill_invest, max_s_idx, s16b); C_FREE(skill_bonus, max_s_idx, s32b); for (i = 0; i < max_s_idx; i++) C_FREE(table[i], 2, s32b); C_FREE(table, max_s_idx, s32b*); C_FREE(ab_learned, max_ab_idx, s32b); C_FREE(table_ab, max_ab_idx, s32b); /* Load the screen */ screen_load(); recalc_skills(FALSE); }
/** * Menu command: view character dump and inventory. */ static void death_info(const char *title, int row) { struct store *home = &stores[STORE_HOME]; screen_save(); /* Display player */ display_player(0); /* Prompt for inventory */ prt("Hit any key to see more information: ", 0, 0); /* Allow abort at this point */ (void)anykey(); /* Show equipment and inventory */ /* Equipment -- if any */ if (player->upkeep->equip_cnt) { Term_clear(); show_equip(OLIST_WEIGHT | OLIST_SEMPTY | OLIST_DEATH, NULL); prt("You are using: -more-", 0, 0); (void)anykey(); } /* Inventory -- if any */ if (player->upkeep->inven_cnt) { Term_clear(); show_inven(OLIST_WEIGHT | OLIST_DEATH, NULL); prt("You are carrying: -more-", 0, 0); (void)anykey(); } /* Quiver -- if any */ if (player->upkeep->quiver_cnt) { Term_clear(); show_quiver(OLIST_WEIGHT | OLIST_DEATH, NULL); prt("Your quiver holds: -more-", 0, 0); (void)anykey(); } /* Home -- if anything there */ if (home->stock) { int page; struct object *obj = home->stock; /* Display contents of the home */ for (page = 1; obj; page++) { int line; /* Clear screen */ Term_clear(); /* Show 12 items */ for (line = 0; obj && line < 12; obj = obj->next, line++) { byte attr; char o_name[80]; char tmp_val[80]; /* Print header, clear line */ strnfmt(tmp_val, sizeof(tmp_val), "%c) ", I2A(line)); prt(tmp_val, line + 2, 4); /* Get the object description */ object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); /* Get the inventory color */ attr = obj->kind->base->attr; /* Display the object */ c_put_str(attr, o_name, line + 2, 7); } /* Caption */ prt(format("Your home contains (page %d): -more-", page), 0, 0); /* Wait for it */ (void)anykey(); } } screen_load(); }
/* * Create a spoiler file for monsters (-SHAWN-) */ static void spoil_mon_info(void) { int n, x, y; bool breath, magic; u32b flags1, flags2, flags3, flags4, flags5, flags6; const bool old_spoil_mon = spoil_mon; byte a; char c, c2; byte old_moncol[MAX_MONCOL]; /* Give full information. */ spoil_mon = TRUE; for (n = 0; n < MAX_MONCOL; n++) old_moncol[n] = moncol[n].gfx.xa; /* Hack - hide some information. */ moncol[0].gfx.xa = moncol[8].gfx.xa = moncol[18].gfx.xa = TERM_DARK; /* Dump the header */ spoil_out("Monster Spoilers for %s Version %s\n", GAME_NAME, GAME_VERSION); spoil_out("------------------------------------------\n\n"); /* * List all monsters in order (except the ghost). */ for (n = 1; n < MAX_R_IDX; n++) { monster_race *r_ptr = &r_info[n]; /* Skip "fake" monsters. */ if (is_fake_monster(r_ptr)) continue; /* Extract the flags */ flags1 = r_ptr->flags1; flags2 = r_ptr->flags2; flags3 = r_ptr->flags3; flags4 = r_ptr->flags4; flags5 = r_ptr->flags5; flags6 = r_ptr->flags6; breath = FALSE; magic = FALSE; /* Prefix */ if (flags1 & (RF1_GUARDIAN)) { spoil_out("[G] "); } else if (flags1 & (RF1_UNIQUE)) { spoil_out("[U] "); } else { spoil_out("The "); } /* Name */ spoil_out("%v (", monster_desc_aux_f3, r_ptr, 1, 0); /* Color */ spoil_out(attr_to_text(r_ptr->gfx.da)); /* Symbol --(-- */ spoil_out(" '%c')\n", r_ptr->gfx.dc); /* Indent */ spoil_out("=== "); /* Number */ spoil_out("Num:%d ", n); /* Level */ spoil_out("Lev:%d ", r_ptr->level); /* Rarity */ spoil_out("Rar:%d ", r_ptr->rarity); /* Speed */ spoil_out("Spd:%+d ", (r_ptr->speed - 110)); /* Hitpoints */ if ((flags1 & (RF1_FORCE_MAXHP)) || (r_ptr->hside == 1)) { spoil_out("Hp:%d ", r_ptr->hdice * r_ptr->hside); } else { spoil_out("Hp:%dd%d ", r_ptr->hdice, r_ptr->hside); } /* Armor Class */ spoil_out("Ac:%d ", r_ptr->ac); /* Power */ spoil_out("Power:%ld\n", (long)(r_ptr->mexp)); /* Clear the screen before every monster. */ Term_clear(); /* Display the monster on screen. */ screen_roff(n); /* Dump the on-screen display (excluding the title). */ for (c2 = 0, y = 1; y < Term->hgt; y++) { for (x = 0; x < Term->wid; x++) { /* Check the character. */ Term_what(x, y, &a, &c); /* Ignore blanked text. */ if (a == TERM_DARK) continue; /* Ignore repeated spaces. */ if (c == ' ' && c2 == ' ') continue; /* Dump the character. */ spoil_out("%c", c); /* Remember the character. */ c2 = c; } /* Put a space at the end of every line. */ if (c2 != ' ') spoil_out(" "); } spoil_out(NULL); } /* Restore spoil_mon. */ spoil_mon = old_spoil_mon; /* Restore moncol[]. */ for (n = 0; n < MAX_MONCOL; n++) moncol[n].gfx.xa = old_moncol[n]; /* Don't leave a monster display lying around. */ Term_clear(); }
/* * Interreact with skills */ void do_cmd_skill() { int sel = 0, start = 0, max; char c; int table[MAX_SKILLS][2]; int i; int wid, hgt; s16b skill_points_save; s32b *skill_values_save; s32b *skill_mods_save; s16b *skill_rates_save; s16b *skill_invest; s32b *skill_bonus; recalc_skills(TRUE); /* Save the screen */ screen_save(); /* Allocate arrays to save skill values */ C_MAKE(skill_values_save, MAX_SKILLS, s32b); C_MAKE(skill_mods_save, MAX_SKILLS, s32b); C_MAKE(skill_rates_save, MAX_SKILLS, s16b); C_MAKE(skill_invest, MAX_SKILLS, s16b); C_MAKE(skill_bonus, MAX_SKILLS, s32b); /* Save skill points */ skill_points_save = p_ptr->skill_points; /* Save skill values */ for (i = 0; i < max_s_idx; i++) { skill_type *s_ptr = &s_info[i]; skill_values_save[i] = s_ptr->value; skill_mods_save[i] = s_ptr->mod; skill_rates_save[i] = s_ptr->rate; skill_invest[i] = 0; } /* Clear the screen */ Term_clear(); /* Initialise the skill list */ init_table(table, &max, FALSE); while (TRUE) { Term_get_size(&wid, &hgt); /* Display list of skills */ recalc_skills_theory(skill_invest, skill_values_save, skill_mods_save, skill_bonus); print_skills(table, max, sel, start); /* Wait for user input */ c = inkey(); /* Leave the skill screen */ if (c == ESCAPE) break; /* Expand / collapse list of skills */ else if (c == '\r') { if (s_info[table[sel][0]].dev) s_info[table[sel][0]].dev = FALSE; else s_info[table[sel][0]].dev = TRUE; init_table(table, &max, FALSE); } /* Next page */ else if (c == 'n') { sel += (hgt - 7); if (sel >= max) sel = max - 1; } /* Previous page */ else if (c == 'p') { sel -= (hgt - 7); if (sel < 0) sel = 0; } /* Select / increase a skill */ else { int dir; /* Allow use of numpad / arrow keys / roguelike keys */ dir = get_keymap_dir(c); /* Move cursor down */ if (dir == 2) sel++; /* Move cursor up */ if (dir == 8) sel--; /* Miscellaneous skills cannot be increased/decreased as a group */ if (table[sel][0] == SKILL_MISC) continue; /* Increase the current skill */ if (dir == 6) increase_skill(table[sel][0], skill_invest); /* Decrease the current skill */ if (dir == 4) decrease_skill(table[sel][0], skill_invest); /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ /* Increase the skill */ if (wizard && (c == '+')) skill_bonus[table[sel][0]] += SKILL_STEP; /* Decrease the skill */ if (wizard && (c == '-')) skill_bonus[table[sel][0]] -= SKILL_STEP; /* Contextual help */ if (c == '?') exec_lua(format("ingame_help('select_context', 'skill', '%s')", s_info[table[sel][0]].name + s_name)); ; /* Handle boundaries and scrolling */ if (sel < 0) sel = max - 1; if (sel >= max) sel = 0; if (sel < start) start = sel; if (sel >= start + (hgt - 7)) start = sel - (hgt - 7) + 1; } } /* Some skill points are spent */ if (p_ptr->skill_points != skill_points_save) { /* Flush input as we ask an important and irreversible question */ flush(); /* Ask we can commit the change */ if (msg_box("Save and use these skill values? (y/n)", (int)(hgt / 2), (int)(wid / 2)) != 'y') { /* User declines -- restore the skill values before exiting */ /* Restore skill points */ p_ptr->skill_points = skill_points_save; /* Restore skill values */ for (i = 0; i < max_s_idx; i++) { skill_type *s_ptr = &s_info[i]; s_ptr->value = skill_values_save[i]; s_ptr->mod = skill_mods_save[i]; s_ptr->rate = skill_rates_save[i]; } } } /* Free arrays to save skill values */ C_FREE(skill_values_save, MAX_SKILLS, s32b); C_FREE(skill_mods_save, MAX_SKILLS, s32b); C_FREE(skill_rates_save, MAX_SKILLS, s16b); C_FREE(skill_invest, MAX_SKILLS, s16b); C_FREE(skill_bonus, MAX_SKILLS, s32b); /* Load the screen */ screen_load(); recalc_skills(FALSE); }
/* * This is called when we receive a request for a command in the birth * process. * The birth process continues until we send a final character confirmation * command (or quit), so this is effectively called in a loop by the main * game. * * We're imposing a step-based system onto the main game here, so we need * to keep track of where we're up to, where each step moves on to, etc. */ errr get_birth_command(bool wait) { static enum birth_stage current_stage = BIRTH_RESET; static enum birth_stage prev; static enum birth_stage roller = BIRTH_RESET; enum birth_stage next = current_stage; switch (current_stage) { case BIRTH_RESET: { cmd_insert(CMD_BIRTH_RESET, TRUE); roller = BIRTH_RESET; if (quickstart_allowed) next = BIRTH_QUICKSTART; else next = BIRTH_SEX_CHOICE; break; } case BIRTH_QUICKSTART: { display_player(0, TRUE); next = get_quickstart_command(); break; } case BIRTH_SEX_CHOICE: case BIRTH_CLASS_CHOICE: case BIRTH_RACE_CHOICE: case BIRTH_OPTION_CHOICE: case BIRTH_ROLLER_CHOICE: { menu_type *menu = &sex_menu; cmd_code command = CMD_CHOOSE_SEX; Term_clear(); print_menu_instructions(); if (current_stage > BIRTH_SEX_CHOICE) { menu_refresh(&sex_menu); menu = &race_menu; command = CMD_CHOOSE_RACE; } if (current_stage > BIRTH_RACE_CHOICE) { menu_refresh(&race_menu); menu = &class_menu; command = CMD_CHOOSE_CLASS; } if (current_stage > BIRTH_CLASS_CHOICE) { menu_refresh(&class_menu); menu = &birth_opt_menu; command = CMD_CHOOSE_OPTIONS; } if (current_stage > BIRTH_OPTION_CHOICE) { menu_refresh(&birth_opt_menu); menu = &roller_menu; command = CMD_NULL; } next = menu_question(current_stage, menu, command); if (next == BIRTH_BACK) next = current_stage - 1; /* Make sure that the character gets reset before quickstarting */ if (next == BIRTH_QUICKSTART) next = BIRTH_RESET; break; } case BIRTH_POINTBASED: { roller = BIRTH_POINTBASED; if (prev > BIRTH_POINTBASED) point_based_start(); next = point_based_command(); if (next == BIRTH_BACK) next = BIRTH_ROLLER_CHOICE; if (next != BIRTH_POINTBASED) point_based_stop(); break; } case BIRTH_ROLLER: { roller = BIRTH_ROLLER; next = roller_command(prev < BIRTH_ROLLER); if (next == BIRTH_BACK) next = BIRTH_ROLLER_CHOICE; break; } case BIRTH_NAME_CHOICE: { if (prev < BIRTH_NAME_CHOICE) display_player(0, TRUE); next = get_name_command(); if (next == BIRTH_BACK) next = roller; break; } case BIRTH_FINAL_CONFIRM: { if (prev < BIRTH_FINAL_CONFIRM) display_player(0, TRUE); next = get_confirm_command(); if (next == BIRTH_BACK) next = BIRTH_NAME_CHOICE; break; } default: { /* Remove dodgy compiler warning, */ } } prev = current_stage; current_stage = next; return 0; }
/* * Display an item's properties */ static void wiz_display_item(const object_type *o_ptr, bool all) { int j = 0; bitflag f[OF_SIZE]; char buf[256]; /* Extract the flags */ if (all) object_flags(o_ptr, f); else object_flags_known(o_ptr, f); /* Clear screen */ Term_clear(); /* Describe fully */ object_desc(buf, sizeof(buf), o_ptr, ODESC_PREFIX | ODESC_FULL | ODESC_SPOIL); prt(buf, 2, j); prt(format("combat = (%dd%d) (%+d,%+d) [%d,%+d]", o_ptr->dd, o_ptr->ds, o_ptr->to_h, o_ptr->to_d, o_ptr->ac, o_ptr->to_a), 4, j); prt(format("kind = %-5d tval = %-5d sval = %-5d wgt = %-3d timeout = %-d", o_ptr->k_idx, o_ptr->tval, o_ptr->sval, o_ptr->weight, o_ptr->timeout), 5, j); prt(format("number = %-3d pval = %-5d name1 = %-4d name2 = %-4d cost = %ld", o_ptr->number, o_ptr->pval, o_ptr->name1, o_ptr->name2, (long)object_value(o_ptr, 1, FALSE)), 6, j); prt("+------------FLAGS0------------+", 8, j); prt("AFFECT..........SLAY.......BRAND", 9, j); prt(" ae xxxpaefc", 10, j); prt("siwdcc ssidsasmnvudotgddduoclio", 11, j); prt("tnieoh trnipthgiinmrrnrrmniierl", 12, j); prt("rtsxna..lcfgdkttmldncltggndsdced", 13, j); prt_binary(f, 0, 14, j, '*', 32); prt_binary(o_ptr->known_flags, 0, 15, j, '+', 32); prt("+------------FLAGS1------------+", 16, j); prt("SUST........IMM.RESIST.........", 17, j); prt(" afecaefcpfldbc s n ", 18, j); prt("siwdcc cilocliooeialoshnecd", 19, j); prt("tnieoh irelierliatrnnnrethi", 20, j); prt("rtsxna......decddcedsrekdfddxhss", 21, j); prt_binary(f, 32, 22, j, '*', 32); prt_binary(o_ptr->known_flags, 32, 23, j, '+', 32); prt("+------------FLAGS2------------+", 8, j+34); prt("s ts hn tadiiii aiehs hp", 9, j+34); prt("lf eefoo egrgggg bcnaih vr", 10, j+34); prt("we lerlf ilgannnn ltssdo ym", 11, j+34); prt("da reiedu merirrrr eityew ccc", 12, j+34); prt("itlepnele ppanaefc svaktm uuu", 13, j+34); prt("ghigavail aoveclio saanyo rrr", 14, j+34); prt("seteticf craxierl etropd sss", 15, j+34); prt("trenhste tttpdced detwes eee", 16, j+34); prt_binary(f, 64, 17, j + 34, '*', 32); prt_binary(o_ptr->known_flags, 64, 18, j + 34, '+', 32); prt("o_ptr->ident:", 20, j+34); prt(format("sense %c worn %c empty %c known %c", (o_ptr->ident & IDENT_SENSE) ? '+' : ' ', (o_ptr->ident & IDENT_WORN) ? '+' : ' ', (o_ptr->ident & IDENT_EMPTY) ? '+' : ' ', (o_ptr->ident & IDENT_KNOWN) ? '+' : ' '), 21, j+34); prt(format("store %c attack %c defence %c effect %c", (o_ptr->ident & IDENT_STORE) ? '+' : ' ', (o_ptr->ident & IDENT_ATTACK) ? '+' : ' ', (o_ptr->ident & IDENT_DEFENCE) ? '+' : ' ', (o_ptr->ident & IDENT_EFFECT) ? '+' : ' '), 22, j+34); prt(format("indest %c ego %c", (o_ptr->ident & IDENT_INDESTRUCT) ? '+' : ' ', (o_ptr->ident & IDENT_NAME) ? '+' : ' '), 23, j+34); }
/* * Display an item's properties */ static void wiz_display_item(const object_type *o_ptr) { int j = 0; u32b f1, f2, f3; char buf[256]; /* Extract the flags */ object_flags(o_ptr, &f1, &f2, &f3); /* Clear screen */ Term_clear(); /* Describe fully */ object_desc_spoil(buf, sizeof(buf), o_ptr, TRUE, 3); prt(buf, 2, j); prt(format("kind = %-5d level = %-4d tval = %-5d sval = %-5d", o_ptr->k_idx, k_info[o_ptr->k_idx].level, o_ptr->tval, o_ptr->sval), 4, j); prt(format("number = %-3d wgt = %-6d prt = %dd%d damage = %dd%d", o_ptr->number, o_ptr->weight, o_ptr->pd, o_ptr->ps, o_ptr->dd, o_ptr->ds), 5, j); prt(format("pval = %-5d toev = %-5d tohit = %-4d", o_ptr->pval, o_ptr->evn, o_ptr->att), 6, j); prt(format("name1 = %-4d name2 = %-4d cost = %ld", o_ptr->name1, o_ptr->name2, (long)object_value(o_ptr)), 7, j); prt(format("ident = %04x timeout = %-d", o_ptr->ident, o_ptr->timeout), 8, j); prt("+------------FLAGS1------------+", 10, j); prt("AFFECT..........SLAY.......BRAND", 11, j); prt(" ae xxxaefcp", 12, j); prt("siwdcc ssitsasmnvudotgddduclioo", 13, j); prt("tnieoh trnupthgiinmrrnrrmnierli", 14, j); prt("rtsxna..lcfndkttmldncltggnddceds", 15, j); prt_binary(f1, 16, j); prt("+------------FLAGS2------------+", 17, j); prt("SUST.......IMM..RESIST.........", 18, j); prt(" afecpaefcpfldbc s n ", 19, j); prt("siwdcc ciloocliooeialoshnecd", 20, j); prt("tnieoh ireliierliatrnnnrethi", 21, j); prt("rtsxna.....decdsdcedsrekdfddxhss", 22, j); prt_binary(f2, 23, j); prt("+------------FLAGS3------------+", 10, j+32); prt("s ts h tadiiii aiehs hp", 11, j+32); prt("lf eefoni egrgggg bcnaih vr", 12, j+32); prt("we lerler ilgannnn ltssdo ym", 13, j+32); prt("da reiedvo merirrrr eityew ccc", 14, j+32); prt("itlepnelpn ppanaefc svaktm uuu", 15, j+32); prt("ghigavaiim aoveclio saanyo rrr", 16, j+32); prt("seteticfca craxierl etropd sss", 17, j+32); prt("trenhstekn tttpdced detwes eee", 18, j+32); prt_binary(f3, 19, j+32); }
/* * Display the scores in a given range. * Assumes the high score list is already open. * Only five entries per line, too much info. * * Mega-Hack -- allow "fake" entry at the given position. */ void display_scores_aux(int from, int to, int note, high_score *score) { int i, j, k, n, place; byte attr; high_score the_score; char out_val[256]; char tmp_val[160]; int wid, hgt, per_screen; Term_get_size(&wid, &hgt); per_screen = (hgt - 4) / 4; /* Paranoia -- it may not have opened */ if (highscore_fd < 0) return; /* Assume we will show the first 10 */ if (from < 0) from = 0; if (to < 0) to = 10; if (to > MAX_HISCORES) to = MAX_HISCORES; /* Seek to the beginning */ if (highscore_seek(0)) return; /* Hack -- Count the high scores */ for (i = 0; i < MAX_HISCORES; i++) { if (highscore_read(&the_score)) break; } /* Hack -- allow "fake" entry to be last */ if ((note == i) && score) i++; /* Forget about the last entries */ if (i > to) i = to; /* Show per_screen per page, until "done" */ for (k = from, place = k+1; k < i; k += per_screen) { /* Clear screen */ Term_clear(); /* Title */ put_str(" PosChengband Hall of Fame", 0, 0); /* Indicate non-top scores */ if (k > 0) { sprintf(tmp_val, "(from position %d)", k + 1); put_str(tmp_val, 0, 40); } /* Dump per_screen entries */ for (j = k, n = 0; j < i && n < per_screen; place++, j++, n++) { int pr, pc, pa, clev, mlev, cdun, mdun; cptr user, gold, when, aged; /* Hack -- indicate death in yellow */ attr = (j == note) ? TERM_YELLOW : TERM_WHITE; /* Mega-Hack -- insert a "fake" record */ if ((note == j) && score) { the_score = (*score); attr = TERM_L_GREEN; score = NULL; note = -1; j--; } /* Read a normal record */ else { /* Read the proper record */ if (highscore_seek(j)) break; if (highscore_read(&the_score)) break; } /* Extract the race/class */ pr = atoi(the_score.p_r); pc = atoi(the_score.p_c); pa = atoi(the_score.p_a); /* Extract the level info */ clev = atoi(the_score.cur_lev); mlev = atoi(the_score.max_lev); cdun = atoi(the_score.cur_dun); mdun = atoi(the_score.max_dun); /* Hack -- extract the gold and such */ for (user = the_score.uid; isspace(*user); user++) /* loop */; for (when = the_score.day; isspace(*when); when++) /* loop */; for (gold = the_score.gold; isspace(*gold); gold++) /* loop */; for (aged = the_score.turns; isspace(*aged); aged++) /* loop */; /* Clean up standard encoded form of "when" */ if ((*when == '@') && strlen(when) == 9) { sprintf(tmp_val, "%.4s-%.2s-%.2s", when + 1, when + 5, when + 7); when = tmp_val; } /* Dump some info */ sprintf(out_val, "%3d.%9s %s %s the %s %s, Level %d", place, the_score.pts, seikaku_info[pa].title, the_score.who, get_race_t_aux(pr, 0)->name, get_class_t_aux(pc, 0)->name, clev); /* Append a "maximum level" */ if (mlev > clev) strcat(out_val, format(" (Max %d)", mlev)); /* Dump the first line */ c_put_str(attr, out_val, n*4 + 2, 0); /* Another line of info */ /* Some people die outside of the dungeon */ if (!cdun) sprintf(out_val, " Killed by %s on the surface", the_score.how); else sprintf(out_val, " Killed by %s on %s %d", the_score.how, "Dungeon Level", cdun); /* Append a "maximum level" */ if (mdun > cdun) strcat(out_val, format(" (Max %d)", mdun)); /* Dump the info */ c_put_str(attr, out_val, n*4 + 3, 0); /* And still another line of info */ sprintf(out_val, " (User %s, Date %s, Gold %s, Turn %s).", user, when, gold, aged); c_put_str(attr, out_val, n*4 + 4, 0); } /* Wait for response */ prt("[Press ESC to quit, any other key to continue.]", hgt - 1, 17); j = inkey(); prt("", hgt - 1, 0); /* Hack -- notice Escape */ if (j == ESCAPE) break; } }
/* * Get an object kind for creation (or zero) * * List up to 60 choices in three columns */ static int wiz_create_itemtype(void) { int i, num, max_num; int col, row; int tval; cptr tval_desc; char ch; int choice[60]; static const char choice_name[] = "abcdefghijklmnopqrst" "ABCDEFGHIJKLMNOPQRST" "0123456789:;<=>?@%&*"; const char *cp; char buf[160]; /* Clear screen */ Term_clear(); /* Print all tval's and their descriptions */ for (num = 0; (num < 60) && tvals[num].tval; num++) { row = 2 + (num % 20); col = 30 * (num / 20); ch = choice_name[num]; prt(format("[%c] %s", ch, tvals[num].desc), row, col); } /* We need to know the maximal possible tval_index */ max_num = num; /* Choose! */ if (!get_com("Create what type of object? ", &ch)) return (0); /* Analyze choice */ num = -1; if ((cp = strchr(choice_name, ch)) != NULL) num = cp - choice_name; /* Bail out if choice is illegal */ if ((num < 0) || (num >= max_num)) return (0); /* Base object type chosen, fill in tval */ tval = tvals[num].tval; tval_desc = tvals[num].desc; /*** And now we go for k_idx ***/ /* Clear screen */ Term_clear(); /* We have to search the whole itemlist. */ for (num = 0, i = 1; (num < 60) && (i < z_info->k_max); i++) { object_kind *k_ptr = &k_info[i]; /* Analyze matching items */ if (k_ptr->tval == tval) { /* Hack -- Skip instant artefacts */ if (k_ptr->flags3 & (TR3_INSTA_ART)) continue; /* Prepare it */ row = 2 + (num % 20); col = 30 * (num / 20); ch = choice_name[num]; /* Get the "name" of object "i" */ strip_name(buf, i); /* Print it */ prt(format("[%c] %s", ch, buf), row, col); /* Remember the object index */ choice[num++] = i; } } /* Me need to know the maximal possible remembered object_index */ max_num = num; /* Choose! */ if (!get_com(format("What Kind of %s? ", tval_desc), &ch)) return (0); /* Analyze choice */ num = -1; if ((cp = strchr(choice_name, ch)) != NULL) num = cp - choice_name; /* Bail out if choice is "illegal" */ if ((num < 0) || (num >= max_num)) return (0); /* And return successful */ return (choice[num]); }
/* * Display the scores in a given range. */ static void display_scores_aux(const high_score scores[], int from, int to, int highlight) { struct keypress ch; int j, k, n, place; int count; /* Assume we will show the first 10 */ if (from < 0) from = 0; if (to < 0) to = 10; if (to > MAX_HISCORES) to = MAX_HISCORES; /* Hack -- Count the high scores */ for (count = 0; count < MAX_HISCORES; count++) { if (!scores[count].what[0]) break; } /* Forget about the last entries */ if (count > to) count = to; /* Show 5 per page, until "done" */ for (k = from, j = from, place = k+1; k < count; k += 5) { char out_val[160]; char tmp_val[160]; /* Clear screen */ Term_clear(); /* Title */ if (k > 0) put_str(format("%s Hall of Fame (from position %d)", VERSION_NAME, place), 0, 21); else put_str(format("%s Hall of Fame", VERSION_NAME), 0, 30); /* Dump 5 entries */ for (n = 0; j < count && n < 5; place++, j++, n++) { const high_score *score = &scores[j]; byte attr; int clev, mlev, cdun, mdun; const char *user, *gold, *when, *aged; struct player_class *c; struct player_race *r; /* Hack -- indicate death in yellow */ attr = (j == highlight) ? TERM_L_GREEN : TERM_WHITE; c = player_id2class(atoi(score->p_c)); r = player_id2race(atoi(score->p_r)); /* Extract the level info */ clev = atoi(score->cur_lev); mlev = atoi(score->max_lev); cdun = atoi(score->cur_dun); mdun = atoi(score->max_dun); /* Hack -- extract the gold and such */ for (user = score->uid; isspace((unsigned char)*user); user++) /* loop */; for (when = score->day; isspace((unsigned char)*when); when++) /* loop */; for (gold = score->gold; isspace((unsigned char)*gold); gold++) /* loop */; for (aged = score->turns; isspace((unsigned char)*aged); aged++) /* loop */; /* Dump some info */ strnfmt(out_val, sizeof(out_val), "%3d.%9s %s the %s %s, Level %d", place, score->pts, score->who, r ? r->name : "<none>", c ? c->name : "<none>", clev); /* Append a "maximum level" */ if (mlev > clev) my_strcat(out_val, format(" (Max %d)", mlev), sizeof(out_val)); /* Dump the first line */ c_put_str(attr, out_val, n*4 + 2, 0); /* Died where? */ if (!cdun) strnfmt(out_val, sizeof(out_val), "Killed by %s in the town", score->how); else strnfmt(out_val, sizeof(out_val), "Killed by %s on dungeon level %d", score->how, cdun); /* Append a "maximum level" */ if (mdun > cdun) my_strcat(out_val, format(" (Max %d)", mdun), sizeof(out_val)); /* Dump the info */ c_put_str(attr, out_val, n*4 + 3, 15); /* Clean up standard encoded form of "when" */ if ((*when == '@') && strlen(when) == 9) { strnfmt(tmp_val, sizeof(tmp_val), "%.4s-%.2s-%.2s", when + 1, when + 5, when + 7); when = tmp_val; } /* And still another line of info */ strnfmt(out_val, sizeof(out_val), "(User %s, Date %s, Gold %s, Turn %s).", user, when, gold, aged); c_put_str(attr, out_val, n*4 + 4, 15); } /* Wait for response */ prt("[Press ESC to exit, any other key to continue.]", 23, 17); ch = inkey(); prt("", 23, 0); /* Hack -- notice Escape */ if (ch.code == ESCAPE) break; } return; }
/* * Attempt to Load a "savefile" * * On multi-user systems, you may only "read" a savefile if you will be * allowed to "write" it later, this prevents painful situations in which * the player loads a savefile belonging to someone else, and then is not * allowed to save his game when he quits. * * We return "TRUE" if the savefile was usable, and we set the global * flag "character_loaded" if a real, living, character was loaded. * * Note that we always try to load the "current" savefile, even if * there is no such file, so we must check for "empty" savefile names. */ bool load_player(void) { int fd = -1; errr err = 0; byte vvv[4]; #ifdef VERIFY_TIMESTAMP struct stat statbuf; #endif /* VERIFY_TIMESTAMP */ cptr what = "generic"; /* Paranoia */ turn = 0; /* Paranoia */ p_ptr->is_dead = FALSE; // Set a flag to show that we are restoring a game p_ptr->restoring = TRUE; /* Allow empty savefile name */ if (!savefile[0]) return (TRUE); /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) { /* Give a message */ msg_format("Savefile \"%s\" does not exist.", savefile); message_flush(); /* Allow this */ p_ptr->restoring = FALSE; return (FALSE);//// } /* Close the file */ fd_close(fd); #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (!err) { FILE *fkk; char temp[1024]; /* Extract name of lock file */ my_strcpy(temp, savefile, sizeof(temp)); my_strcat(temp, ".lok", sizeof(temp)); /* Grab permissions */ safe_setuid_grab(); /* Check for lock */ fkk = my_fopen(temp, "r"); /* Drop permissions */ safe_setuid_drop(); /* Oops, lock exists */ if (fkk) { /* Close the file */ my_fclose(fkk); /* Message */ msg_print("Savefile is currently in use."); message_flush(); /* Oops */ return (FALSE); } /* Grab permissions */ safe_setuid_grab(); /* Create a lock file */ fkk = my_fopen(temp, "w"); /* Drop permissions */ safe_setuid_drop(); /* Dump a line of info */ fprintf(fkk, "Lock file for savefile '%s'\n", savefile); /* Close the lock file */ my_fclose(fkk); } #endif /* VERIFY_SAVEFILE */ /* Okay */ if (!err) { /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) err = -1; /* Message (below) */ if (err) what = "Cannot open savefile"; } /* Process file */ if (!err) { #ifdef VERIFY_TIMESTAMP /* Grab permissions */ safe_setuid_grab(); /* Get the timestamp */ (void)fstat(fd, &statbuf); /* Drop permissions */ safe_setuid_drop(); #endif /* VERIFY_TIMESTAMP */ /* Read the first four bytes */ if (fd_read(fd, (char*)(vvv), sizeof(vvv))) err = -1; /* What */ if (err) what = "Cannot read savefile"; /* Close the file */ fd_close(fd); } /* Process file */ if (!err) { /* Extract version */ sf_major = vvv[0]; sf_minor = vvv[1]; sf_patch = vvv[2]; sf_extra = vvv[3]; /* Clear screen */ Term_clear(); if (older_than(OLD_VERSION_MAJOR, OLD_VERSION_MINOR, OLD_VERSION_PATCH)) { err = -1; what = "Savefile is too old"; } else if (!older_than(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 1)) { err = -1; what = "Savefile is from the future"; } else { /* Attempt to load */ err = rd_savefile(); /* Message (below) */ if (err) what = "Cannot parse savefile"; } } /* Paranoia */ if (!err) { /* Invalid turn */ if (!turn) err = -1; /* Message (below) */ if (err) what = "Broken savefile"; } #ifdef VERIFY_TIMESTAMP /* Verify timestamp */ if (!err && !arg_wizard) { /* Hack -- Verify the timestamp */ if (sf_when > (statbuf.st_ctime + 100) || sf_when < (statbuf.st_ctime - 100)) { /* Message */ what = "Invalid timestamp"; /* Oops */ err = -1; } } #endif /* VERIFY_TIMESTAMP */ /* Okay */ if (!err) { /* Give a conversion warning */ if ((version_major != sf_major) || (version_minor != sf_minor) || (version_patch != sf_patch)) { /* Message */ msg_format("Converted a %d.%d.%d savefile.", sf_major, sf_minor, sf_patch); message_flush(); } // if Morgoth has lost his crown... if ((&a_info[ART_MORGOTH_3])->cur_num == 1) { // lower Morgoth's protection, remove his light source, increase his will and perception (&r_info[R_IDX_MORGOTH])->pd -= 1; (&r_info[R_IDX_MORGOTH])->light = 0; (&r_info[R_IDX_MORGOTH])->wil += 5; (&r_info[R_IDX_MORGOTH])->per += 5; } /* Player is dead */ if (p_ptr->is_dead) { /* Cheat death (unless the character retired) */ if (arg_wizard) { /*heal the player*/ hp_player(100, TRUE, TRUE); /* Forget death */ p_ptr->is_dead = FALSE; /* A character was loaded */ character_loaded = TRUE; // put the character somewhere sensible p_ptr->depth = min_depth(); // Mark savefile p_ptr->noscore |= 0x0001; /* Done */ return (TRUE); } /* Forget death */ p_ptr->is_dead = FALSE; /* Count lives */ sf_lives++; /* Forget turns */ turn = 0; playerturn = 0; /* A dead character was loaded */ character_loaded_dead = TRUE;//// /* Done */ return (TRUE); } /* A character was loaded */ character_loaded = TRUE; /* Still alive */ if (p_ptr->chp >= 0) { /* Reset cause of death */ my_strcpy(p_ptr->died_from, "(alive and well)", sizeof (p_ptr->died_from)); } // count the artefacts seen for the player p_ptr->artefacts = artefact_count(); /* Success */ return (TRUE); } #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (TRUE) { char temp[1024]; /* Extract name of lock file */ my_strcpy(temp, savefile, sizeof(temp)); my_strcat(temp, ".lok", sizeof(temp)); /* Grab permissions */ safe_setuid_grab(); /* Remove lock */ fd_kill(temp); /* Drop permissions */ safe_setuid_drop(); } #endif /* VERIFY_SAVEFILE */ /* Message */ msg_format("Error (%s) reading %d.%d.%d savefile.", what, sf_major, sf_minor, sf_patch); message_flush(); /* Oops */ return (FALSE); }
/*! * @brief スコア転送処理のメインルーチン * @return エラーコード */ errr report_score(void) { #ifdef MACINTOSH OSStatus err; #else errr err = 0; #endif #ifdef WINDOWS WSADATA wsaData; WORD wVersionRequested =(WORD) (( 1) | ( 1 << 8)); #endif BUF *score; int sd; char seikakutmp[128]; score = buf_new(); #ifdef JP sprintf(seikakutmp, "%s%s", ap_ptr->title, (ap_ptr->no ? "の" : "")); #else sprintf(seikakutmp, "%s ", ap_ptr->title); #endif buf_sprintf(score, "name: %s\n", p_ptr->name); #ifdef JP buf_sprintf(score, "version: 変愚蛮怒 %d.%d.%d\n", FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH); #else buf_sprintf(score, "version: Hengband %d.%d.%d\n", FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH); #endif buf_sprintf(score, "score: %d\n", total_points()); buf_sprintf(score, "level: %d\n", p_ptr->lev); buf_sprintf(score, "depth: %d\n", dun_level); buf_sprintf(score, "maxlv: %d\n", p_ptr->max_plv); buf_sprintf(score, "maxdp: %d\n", max_dlv[DUNGEON_ANGBAND]); buf_sprintf(score, "au: %d\n", p_ptr->au); buf_sprintf(score, "turns: %d\n", turn_real(turn)); buf_sprintf(score, "sex: %d\n", p_ptr->psex); buf_sprintf(score, "race: %s\n", rp_ptr->title); buf_sprintf(score, "class: %s\n", cp_ptr->title); buf_sprintf(score, "seikaku: %s\n", seikakutmp); buf_sprintf(score, "realm1: %s\n", realm_names[p_ptr->realm1]); buf_sprintf(score, "realm2: %s\n", realm_names[p_ptr->realm2]); buf_sprintf(score, "killer: %s\n", p_ptr->died_from); buf_sprintf(score, "-----charcter dump-----\n"); make_dump(score); if (screen_dump) { buf_sprintf(score, "-----screen shot-----\n"); buf_append(score, screen_dump, strlen(screen_dump)); } #ifdef WINDOWS if (WSAStartup(wVersionRequested, &wsaData)) { msg_print("Report: WSAStartup failed."); goto report_end; } #endif #ifdef MACINTOSH #if TARGET_API_MAC_CARBON err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL); #else err = InitOpenTransport(); #endif if (err != noErr) { msg_print("Report: OpenTransport failed."); return 1; } #endif Term_clear(); while (1) { char buff[160]; #ifdef JP prt("接続中...", 0, 0); #else prt("connecting...", 0, 0); #endif Term_fresh(); /* プロキシを設定する */ set_proxy(HTTP_PROXY, HTTP_PROXY_PORT); /* Connect to the score server */ sd = connect_server(HTTP_TIMEOUT, SCORE_SERVER, SCORE_PORT); if (!(sd < 0)) break; #ifdef JP sprintf(buff, "スコア・サーバへの接続に失敗しました。(%s)", soc_err()); #else sprintf(buff, "Failed to connect to the score server.(%s)", soc_err()); #endif prt(buff, 0, 0); (void)inkey(); #ifdef JP if (!get_check_strict("もう一度接続を試みますか? ", CHECK_NO_HISTORY)) #else if (!get_check_strict("Try again? ", CHECK_NO_HISTORY)) #endif { err = 1; goto report_end; } } #ifdef JP prt("スコア送信中...", 0, 0); #else prt("Sending the score...", 0, 0); #endif Term_fresh(); http_post(sd, SCORE_PATH, score); disconnect_server(sd); report_end: #ifdef WINDOWS WSACleanup(); #endif #ifdef MACINTOSH #if TARGET_API_MAC_CARBON CloseOpenTransportInContext(NULL); #else CloseOpenTransport(); #endif #endif return err; }
/* Display possible modules and select one */ bool select_module() { s32b k, sel, max; /* Hack */ use_color = TRUE; /* Init some lua */ init_lua(); /* Some ports need to separate the module scripts from the installed mods, so we need to check for these in two different places */ if(!tome_dofile_anywhere(ANGBAND_DIR_CORE, "mods_aux.lua", FALSE)) tome_dofile_anywhere(ANGBAND_DIR_MODULES, "mods_aux.lua", TRUE); if(!tome_dofile_anywhere(ANGBAND_DIR_CORE, "modules.lua", FALSE)) tome_dofile_anywhere(ANGBAND_DIR_MODULES, "modules.lua", TRUE); /* Grab the savefiles */ call_lua("max_modules", "()", "d", &max); /* No need to bother the player if there is only one module */ sel = -1; if (force_module) call_lua("find_module", "(s)", "d", force_module, &sel); if (max == 1) sel = 0; if (sel != -1) { cptr tmp; /* Process the module */ call_lua("init_module", "(d)", "", sel); call_lua("get_module_name", "(d)", "s", sel, &tmp); game_module = string_make(tmp); activate_module(); return FALSE; } sel = 0; /* Preprocess the basic prefs, we need them to have movement keys */ process_pref_file("pref.prf"); while (TRUE) { /* Clear screen */ Term_clear(); /* Let the user choose */ c_put_str(TERM_YELLOW, "Welcome to ToME, you must select a module to play,", 1, 12); c_put_str(TERM_YELLOW, "either ToME official module or third party ones.", 2, 13); put_str("Press 8/2/4/6 to move, Return to select and Esc to quit.", 4, 3); dump_modules(sel, max); k = inkey(); if (k == ESCAPE) { quit(NULL); } if (k == '6') { sel++; if (sel >= max) sel = 0; continue; } else if (k == '4') { sel--; if (sel < 0) sel = max - 1; continue; } else if (k == '2') { sel += 4; if (sel >= max) sel = sel % max; continue; } else if (k == '8') { sel -= 4; if (sel < 0) sel = (sel + max - 1) % max; continue; } else if (k == '\r') { if (sel < 26) k = I2A(sel); else k = toupper(I2A(sel)); } { int x; cptr tmp; if (islower(k)) x = A2I(k); else x = A2I(tolower(k)) + 26; if ((x < 0) || (x >= max)) continue; /* Process the module */ call_lua("init_module", "(d)", "", x); call_lua("get_module_name", "(d)", "s", x, &tmp); game_module = string_make(tmp); activate_module(); return (FALSE); } } /* Shouldnt happen */ return (FALSE); }
/*! * @brief ベースアイテムのウィザード生成のために大項目IDと小項目IDを取得する / * Specify tval and sval (type and subtype of object) originally * @return ベースアイテムID * @details * by RAK, heavily modified by -Bernd- * This function returns the k_idx of an object type, or zero if failed * List up to 50 choices in three columns */ static int wiz_create_itemtype(void) { int i, num, max_num; int col, row; int tval; cptr tval_desc; char ch; int choice[80]; char buf[160]; /* Clear screen */ Term_clear(); /* Print all tval's and their descriptions */ for (num = 0; (num < 80) && tvals[num].tval; num++) { row = 2 + (num % 20); col = 20 * (num / 20); ch = listsym[num]; prt(format("[%c] %s", ch, tvals[num].desc), row, col); } /* Me need to know the maximal possible tval_index */ max_num = num; /* Choose! */ if (!get_com("Get what type of object? ", &ch, FALSE)) return (0); /* Analyze choice */ for (num = 0; num < max_num; num++) { if (listsym[num] == ch) break; } /* Bail out if choice is illegal */ if ((num < 0) || (num >= max_num)) return (0); /* Base object type chosen, fill in tval */ tval = tvals[num].tval; tval_desc = tvals[num].desc; /*** And now we go for k_idx ***/ /* Clear screen */ Term_clear(); /* We have to search the whole itemlist. */ for (num = 0, i = 1; (num < 80) && (i < max_k_idx); i++) { object_kind *k_ptr = &k_info[i]; /* Analyze matching items */ if (k_ptr->tval == tval) { /* Prepare it */ row = 2 + (num % 20); col = 20 * (num / 20); ch = listsym[num]; strcpy(buf," "); /* Acquire the "name" of object "i" */ strip_name(buf, i); /* Print it */ prt(format("[%c] %s", ch, buf), row, col); /* Remember the object index */ choice[num++] = i; } } /* Me need to know the maximal possible remembered object_index */ max_num = num; /* Choose! */ if (!get_com(format("What Kind of %s? ", tval_desc), &ch, FALSE)) return (0); /* Analyze choice */ for (num = 0; num < max_num; num++) { if (listsym[num] == ch) break; } /* Bail out if choice is "illegal" */ if ((num < 0) || (num >= max_num)) return (0); /* And return successful */ return (choice[num]); }
/* * Handle "target" and "look". * * Note that this code can be called from "get_aim_dir()". * * Currently, when "flag" is true, that is, when * "interesting" grids are being used, and a directional key is used, we * only scroll by a single panel, in the direction requested, and check * for any interesting grids on that panel. The "correct" solution would * actually involve scanning a larger set of grids, including ones in * panels which are adjacent to the one currently scanned, but this is * overkill for this function. XXX XXX * * Hack -- targetting/observing an "outer border grid" may induce * problems, so this is not currently allowed. * * The player can use the direction keys to move among "interesting" * grids in a heuristic manner, or the "space", "+", and "-" keys to * move through the "interesting" grids in a sequential manner, or * can enter "location" mode, and use the direction keys to move one * grid at a time in any direction. The "t" (set target) command will * only target a monster (as opposed to a location) if the monster is * target_able and the "interesting" mode is being used. * * The current grid is described using the "look" method above, and * a new command may be entered at any time, but note that if the * "TARGET_LOOK" bit flag is set (or if we are in "location" mode, * where "space" has no obvious meaning) then "space" will scan * through the description of the current grid until done, instead * of immediately jumping to the next "interesting" grid. This * allows the "target" command to retain its old semantics. * * The "*", "+", and "-" keys may always be used to jump immediately * to the next (or previous) interesting grid, in the proper mode. * * The "return" key may always be used to scan through a complete * grid description (forever). * * This command will cancel any old target, even if used from * inside the "look" command. * * * 'mode' is one of TARGET_LOOK or TARGET_KILL. * 'x' and 'y' are the initial position of the target to be highlighted, * or -1 if no location is specified. * Returns TRUE if a target has been successfully set, FALSE otherwise. */ bool target_set_interactive(int mode, int x, int y) { int py = p_ptr->py; int px = p_ptr->px; int path_n; u16b path_g[256]; int i, d, m, t, bd; int wid, hgt, help_prompt_loc; bool done = FALSE; bool flag = TRUE; bool help = FALSE; struct keypress query; /* These are used for displaying the path to the target */ char path_char[MAX_RANGE]; byte path_attr[MAX_RANGE]; /* If we haven't been given an initial location, start on the player. */ if (x == -1 || y == -1) { x = p_ptr->px; y = p_ptr->py; } /* If we /have/ been given an initial location, make sure we honour it by going into "free targetting" mode. */ else { flag = FALSE; } /* Cancel target */ target_set_monster(0); /* Cancel tracking */ /* health_track(0); */ /* Calculate the window location for the help prompt */ Term_get_size(&wid, &hgt); help_prompt_loc = hgt - 1; /* Display the help prompt */ prt("Press '?' for help.", help_prompt_loc, 0); /* Prepare the "temp" array */ target_set_interactive_prepare(mode); /* Start near the player */ m = 0; /* Interact */ while (!done) { bool path_drawn = FALSE; /* Interesting grids */ if (flag && temp_n) { y = temp_y[m]; x = temp_x[m]; /* Adjust panel if needed */ if (adjust_panel_help(y, x, help)) handle_stuff(); /* Update help */ if (help) { bool good_target = (cave->m_idx[y][x] > 0) && target_able(cave->m_idx[y][x]); target_display_help(good_target, !(flag && temp_n)); } /* Find the path. */ path_n = project_path(path_g, MAX_RANGE, py, px, y, x, PROJECT_THRU); /* Draw the path in "target" mode. If there is one */ if (mode & (TARGET_KILL)) path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px); /* Describe and Prompt */ query = target_set_interactive_aux(y, x, mode); /* Remove the path */ if (path_drawn) load_path(path_n, path_g, path_char, path_attr); /* Cancel tracking */ /* health_track(0); */ /* Assume no "direction" */ d = 0; /* Analyze */ switch (query.code) { case ESCAPE: case 'q': { done = TRUE; break; } case ' ': case '*': case '+': { if (++m == temp_n) m = 0; break; } case '-': { if (m-- == 0) m = temp_n - 1; break; } case 'p': { /* Recenter around player */ verify_panel(); /* Handle stuff */ handle_stuff(); y = p_ptr->py; x = p_ptr->px; } case 'o': { flag = FALSE; break; } case 'm': { break; } case 't': case '5': case '0': case '.': { int m_idx = cave->m_idx[y][x]; if ((m_idx > 0) && target_able(m_idx)) { health_track(p_ptr, m_idx); target_set_monster(m_idx); done = TRUE; } else { bell("Illegal target!"); } break; } case 'g': { cmd_insert(CMD_PATHFIND); cmd_set_arg_point(cmd_get_top(), 0, y, x); done = TRUE; break; } case '?': { help = !help; /* Redraw main window */ p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); handle_stuff(); if (!help) prt("Press '?' for help.", help_prompt_loc, 0); break; } default: { /* Extract direction */ d = target_dir(query); /* Oops */ if (!d) bell("Illegal command for target mode!"); break; } } /* Hack -- move around */ if (d) { int old_y = temp_y[m]; int old_x = temp_x[m]; /* Find a new monster */ i = target_pick(old_y, old_x, ddy[d], ddx[d]); /* Scroll to find interesting grid */ if (i < 0) { int old_wy = Term->offset_y; int old_wx = Term->offset_x; /* Change if legal */ if (change_panel(d)) { /* Recalculate interesting grids */ target_set_interactive_prepare(mode); /* Find a new monster */ i = target_pick(old_y, old_x, ddy[d], ddx[d]); /* Restore panel if needed */ if ((i < 0) && modify_panel(Term, old_wy, old_wx)) { /* Recalculate interesting grids */ target_set_interactive_prepare(mode); } /* Handle stuff */ handle_stuff(); } } /* Use interesting grid if found */ if (i >= 0) m = i; } } /* Arbitrary grids */ else { /* Update help */ if (help) { bool good_target = ((cave->m_idx[y][x] > 0) && target_able(cave->m_idx[y][x])); target_display_help(good_target, !(flag && temp_n)); } /* Find the path. */ path_n = project_path(path_g, MAX_RANGE, py, px, y, x, PROJECT_THRU); /* Draw the path in "target" mode. If there is one */ if (mode & (TARGET_KILL)) path_drawn = draw_path (path_n, path_g, path_char, path_attr, py, px); /* Describe and Prompt (enable "TARGET_LOOK") */ query = target_set_interactive_aux(y, x, mode | TARGET_LOOK); /* Remove the path */ if (path_drawn) load_path(path_n, path_g, path_char, path_attr); /* Cancel tracking */ /* health_track(0); */ /* Assume no direction */ d = 0; /* Analyze the keypress */ switch (query.code) { case ESCAPE: case 'q': { done = TRUE; break; } case ' ': case '*': case '+': case '-': { break; } case 'p': { /* Recenter around player */ verify_panel(); /* Handle stuff */ handle_stuff(); y = p_ptr->py; x = p_ptr->px; } case 'o': { break; } case 'm': { flag = TRUE; m = 0; bd = 999; /* Pick a nearby monster */ for (i = 0; i < temp_n; i++) { t = distance(y, x, temp_y[i], temp_x[i]); /* Pick closest */ if (t < bd) { m = i; bd = t; } } /* Nothing interesting */ if (bd == 999) flag = FALSE; break; } case 't': case '5': case '0': case '.': { target_set_location(y, x); done = TRUE; break; } case 'g': { cmd_insert(CMD_PATHFIND); cmd_set_arg_point(cmd_get_top(), 0, y, x); done = TRUE; break; } case '?': { help = !help; /* Redraw main window */ p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); handle_stuff(); if (!help) prt("Press '?' for help.", help_prompt_loc, 0); break; } default: { /* Extract a direction */ d = target_dir(query); /* Oops */ if (!d) bell("Illegal command for target mode!"); break; } } /* Handle "direction" */ if (d) { int dungeon_hgt = (p_ptr->depth == 0) ? TOWN_HGT : DUNGEON_HGT; int dungeon_wid = (p_ptr->depth == 0) ? TOWN_WID : DUNGEON_WID; /* Move */ x += ddx[d]; y += ddy[d]; /* Slide into legality */ if (x >= dungeon_wid - 1) x--; else if (x <= 0) x++; /* Slide into legality */ if (y >= dungeon_hgt - 1) y--; else if (y <= 0) y++; /* Adjust panel if needed */ if (adjust_panel_help(y, x, help)) { /* Handle stuff */ handle_stuff(); /* Recalculate interesting grids */ target_set_interactive_prepare(mode); } } } } /* Forget */ temp_n = 0; /* Redraw as necessary */ if (help) { p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); } else { prt("", 0, 0); prt("", help_prompt_loc, 0); p_ptr->redraw |= (PR_DEPTH | PR_STATUS); } /* Recenter around player */ verify_panel(); /* Handle stuff */ handle_stuff(); /* Failure to set target */ if (!target_set) return (FALSE); /* Success */ return (TRUE); }