/* * 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); 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, TERM_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, 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, 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 != '?'); }
/** * Let the user select an object, save its address * * Return TRUE only if an acceptable item was chosen by the user. * * The user is allowed to choose acceptable items from the equipment, * inventory, quiver, or floor, respectively, if the proper flag was given, * and there are any acceptable items in that location. * * The equipment, inventory or quiver are displayed (even if no acceptable * items are in that location) if the proper flag was given. * * If there are no acceptable items available anywhere, and "str" is * not NULL, then it will be used as the text of a warning message * before the function returns. * * If a legal item is selected , we save it in "choice" and return TRUE. * * If no item is available, we do nothing to "choice", and we display a * warning message, using "str" if available, and return FALSE. * * If no item is selected, we do nothing to "choice", and return FALSE. * * Global "player->upkeep->command_wrk" is used to choose between * equip/inven/quiver/floor listings. It is equal to USE_INVEN or USE_EQUIP or * USE_QUIVER or USE_FLOOR, except when this function is first called, when it * is equal to zero, which will cause it to be set to USE_INVEN. * * We always erase the prompt when we are done, leaving a blank line, * or a warning message, if appropriate, if no items are available. * * Note that only "acceptable" floor objects get indexes, so between two * commands, the indexes of floor objects may change. XXX XXX XXX */ bool textui_get_item(struct object **choice, const char *pmt, const char *str, cmd_code cmd, item_tester tester, int mode) { int py = player->py; int px = player->px; bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE); bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE); bool use_quiver = ((mode & USE_QUIVER) ? TRUE : FALSE); bool use_floor = ((mode & USE_FLOOR) ? TRUE : FALSE); bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE); bool allow_inven = FALSE; bool allow_equip = FALSE; bool allow_quiver = FALSE; bool allow_floor = FALSE; bool toggle = FALSE; int floor_max = z_info->floor_size; int floor_num; floor_list = mem_zalloc(floor_max * sizeof(*floor_list)); olist_mode = 0; item_mode = mode; item_cmd = cmd; tester_m = tester; prompt = pmt; allow_all = str ? FALSE : TRUE; /* Object list display modes */ if (mode & SHOW_FAIL) olist_mode |= OLIST_FAIL; else olist_mode |= OLIST_WEIGHT; if (mode & SHOW_PRICES) olist_mode |= OLIST_PRICE; if (mode & SHOW_EMPTY) olist_mode |= OLIST_SEMPTY; if (mode & SHOW_QUIVER) olist_mode |= OLIST_QUIVER; /* Paranoia XXX XXX XXX */ event_signal(EVENT_MESSAGE_FLUSH); /* Full inventory */ i1 = 0; i2 = z_info->pack_size - 1; /* Forbid inventory */ if (!use_inven) i2 = -1; /* Restrict inventory indexes */ while ((i1 <= i2) && (!object_test(tester, player->upkeep->inven[i1]))) i1++; while ((i1 <= i2) && (!object_test(tester, player->upkeep->inven[i2]))) i2--; /* Accept inventory */ if ((i1 <= i2) || allow_all) allow_inven = TRUE; /* Full equipment */ e1 = 0; e2 = player->body.count - 1; /* Forbid equipment */ if (!use_equip) e2 = -1; /* Restrict equipment indexes unless starting with no command */ if ((cmd != CMD_NULL) || (tester != NULL)) { while ((e1 <= e2) && (!object_test(tester, slot_object(player, e1)))) e1++; while ((e1 <= e2) && (!object_test(tester, slot_object(player, e2)))) e2--; } /* Accept equipment */ if ((e1 <= e2) || allow_all) allow_equip = TRUE; /* Restrict quiver indexes */ q1 = 0; q2 = z_info->quiver_size - 1; /* Forbid quiver */ if (!use_quiver) q2 = -1; /* Restrict quiver indexes */ while ((q1 <= q2) && (!object_test(tester, player->upkeep->quiver[q1]))) q1++; while ((q1 <= q2) && (!object_test(tester, player->upkeep->quiver[q2]))) q2--; /* Accept quiver */ if ((q1 <= q2) || allow_all) allow_quiver = TRUE; /* Scan all non-gold objects in the grid */ floor_num = scan_floor(floor_list, floor_max, py, px, 0x0B, tester); /* Full floor */ f1 = 0; f2 = floor_num - 1; /* Forbid floor */ if (!use_floor) f2 = -1; /* Restrict floor indexes */ while ((f1 <= f2) && (!object_test(tester, floor_list[f1]))) f1++; while ((f1 <= f2) && (!object_test(tester, floor_list[f2]))) f2--; /* Accept floor */ if ((f1 <= f2) || allow_all) allow_floor = TRUE; /* Require at least one legal choice */ if (allow_inven || allow_equip || allow_quiver || allow_floor) { /* Start where requested if possible */ if ((player->upkeep->command_wrk == USE_EQUIP) && allow_equip) player->upkeep->command_wrk = USE_EQUIP; else if ((player->upkeep->command_wrk == USE_INVEN) && allow_inven) player->upkeep->command_wrk = USE_INVEN; else if ((player->upkeep->command_wrk == USE_QUIVER) && allow_quiver) player->upkeep->command_wrk = USE_QUIVER; else if ((player->upkeep->command_wrk == USE_FLOOR) && allow_floor) player->upkeep->command_wrk = USE_FLOOR; /* If we are obviously using the quiver then start on quiver */ else if (quiver_tags && allow_quiver) player->upkeep->command_wrk = USE_QUIVER; /* Otherwise choose whatever is allowed */ else if (use_inven && allow_inven) player->upkeep->command_wrk = USE_INVEN; else if (use_equip && allow_equip) player->upkeep->command_wrk = USE_EQUIP; else if (use_quiver && allow_quiver) player->upkeep->command_wrk = USE_QUIVER; else if (use_floor && allow_floor) player->upkeep->command_wrk = USE_FLOOR; /* If nothing to choose, use (empty) inventory */ else player->upkeep->command_wrk = USE_INVEN; while (TRUE) { int j; int ni = 0; int ne = 0; /* If inven or equip is on the main screen, and only one of them * is slated for a subwindow, we should show the opposite there */ for (j = 0; j < ANGBAND_TERM_MAX; j++) { /* Unused */ if (!angband_term[j]) continue; /* Count windows displaying inven */ if (window_flag[j] & (PW_INVEN)) ni++; /* Count windows displaying equip */ if (window_flag[j] & (PW_EQUIP)) ne++; } /* Are we in the situation where toggling makes sense? */ if ((ni && !ne) || (!ni && ne)) { if (player->upkeep->command_wrk == USE_EQUIP) { if ((ne && !toggle) || (ni && toggle)) { /* Main screen is equipment, so is subwindow */ toggle_inven_equip(); toggle = !toggle; } } else if (player->upkeep->command_wrk == USE_INVEN) { if ((ni && !toggle) || (ne && toggle)) { /* Main screen is inventory, so is subwindow */ toggle_inven_equip(); toggle = !toggle; } } else { /* Quiver or floor, go back to the original */ if (toggle) { toggle_inven_equip(); toggle = !toggle; } } } /* Redraw */ player->upkeep->redraw |= (PR_INVEN | PR_EQUIP); /* Redraw windows */ redraw_stuff(player); /* Save screen */ screen_save(); /* Build object list */ wipe_obj_list(); if (player->upkeep->command_wrk == USE_INVEN) build_obj_list(i2, player->upkeep->inven, tester_m, olist_mode); else if (player->upkeep->command_wrk == USE_EQUIP) build_obj_list(e2, NULL, tester_m, olist_mode); else if (player->upkeep->command_wrk == USE_QUIVER) build_obj_list(q2, player->upkeep->quiver, tester_m,olist_mode); else if (player->upkeep->command_wrk == USE_FLOOR) build_obj_list(f2, floor_list, tester_m, olist_mode); /* Show the prompt */ menu_header(); if (pmt) { prt(pmt, 0, 0); prt(header, 0, strlen(pmt) + 1); } /* No menu change request */ newmenu = FALSE; /* Get an item choice */ *choice = item_menu(cmd, MAX(strlen(pmt), 15), mode); /* Fix the screen */ screen_load(); /* Update */ player->upkeep->redraw |= (PR_INVEN | PR_EQUIP); redraw_stuff(player); /* Clear the prompt line */ prt("", 0, 0); /* We have a selection, or are backing out */ if (*choice || !newmenu) { if (toggle) toggle_inven_equip(); break; } } } else { /* Warning if needed */ if (str) msg("%s", str); *choice = NULL; } /* Clean up */ player->upkeep->command_wrk = 0; mem_free(floor_list); /* Result */ return (*choice != NULL) ? TRUE : FALSE; }
/** * Display an object. Each object may be prefixed with a label. * Used by show_inven(), show_equip(), show_quiver() and show_floor(). * Mode flags are documented in object.h */ static void show_obj(int obj_num, int row, int col, bool cursor, olist_detail_t mode) { int attr; int label_attr = cursor ? COLOUR_L_BLUE : COLOUR_WHITE; int ex_offset_ctr; char buf[80]; struct object *obj = items[obj_num].object; bool show_label = (mode & OLIST_WINDOW || player->is_dead) ? TRUE : FALSE; int label_size = show_label ? strlen(items[obj_num].label) : 0; int equip_label_size = strlen(items[obj_num].equip_label); /* Clear the line */ prt("", row + obj_num, MAX(col - 1, 0)); /* If we have no label then we won't display anything */ if (!strlen(items[obj_num].label)) return; /* Print the label */ if (show_label) c_put_str(label_attr, items[obj_num].label, row + obj_num, col); /* Print the equipment label */ c_put_str(label_attr, items[obj_num].equip_label, row + obj_num, col + label_size); /* Limit object name */ if (label_size + equip_label_size + strlen(items[obj_num].o_name) > (size_t)ex_offset) { int truncate = ex_offset - label_size - equip_label_size; if (truncate < 0) truncate = 0; if ((size_t)truncate > sizeof(items[obj_num].o_name) - 1) truncate = sizeof(items[obj_num].o_name) - 1; items[obj_num].o_name[truncate] = '\0'; } /* Item kind determines the color of the output */ if (obj) attr = obj->kind->base->attr; else attr = COLOUR_SLATE; /* Object name */ c_put_str(attr, items[obj_num].o_name, row + obj_num, col + label_size + equip_label_size); /* If we don't have an object, we can skip the rest of the output */ if (!obj) return; /* Extra fields */ ex_offset_ctr = ex_offset; /* Price */ if (mode & OLIST_PRICE) { struct store *store = store_at(cave, player->py, player->px); if (store) { int price = price_item(store, obj, TRUE, obj->number); strnfmt(buf, sizeof(buf), "%6d au", price); put_str(buf, row + obj_num, col + ex_offset_ctr); ex_offset_ctr += 9; } } /* Failure chance for magic devices and activations */ if (mode & OLIST_FAIL && obj_can_fail(obj)) { int fail = (9 + get_use_device_chance(obj)) / 10; if (object_effect_is_known(obj)) strnfmt(buf, sizeof(buf), "%4d%% fail", fail); else my_strcpy(buf, " ? fail", sizeof(buf)); put_str(buf, row + obj_num, col + ex_offset_ctr); ex_offset_ctr += 10; } /* Weight */ if (mode & OLIST_WEIGHT) { int weight = obj->weight * obj->number; strnfmt(buf, sizeof(buf), "%4d.%1d lb", weight / 10, weight % 10); put_str(buf, row + obj_num, col + ex_offset_ctr); ex_offset_ctr += 9; } }
/** * Display an item's properties */ static void wiz_display_item(object_type * o_ptr) { int j = 0; char buf[256]; /* 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 ("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 ac = %-5d damage = %dd%d", o_ptr->number, o_ptr->weight, o_ptr->ac, o_ptr->dd, o_ptr->ds), 5, j); prt(format ("pval = %-5d toac = %-5d tohit = %-4d todam = %-4d", o_ptr->pval, o_ptr->to_a, o_ptr->to_h, o_ptr->to_d), 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("+------------FLAGS_------------+", 10, j); prt("..SUST..POWERS....OTHER.........", 11, j); prt(" ", 12, j); prt("tbsiwdcc re s ttbiaefc f..", 13, j); prt("hatnieohsfessfhefphhlmcliosspr..", 14, j); prt("rlrtsxnadfgpialerlrdspppppmcca..", 15, j); prt_binary(o_ptr->flags_obj, 0, 16, j, '*', 32); prt("+------------CURSES------------+", 17, j); prt(" n r b b b ", 18, j); prt("ttaasahppcuhdaassppdddd.........", 19, j); prt("eeggrfuooutawduttaaxssc.........", 20, j); prt("llggerniitrlemncwrrppth.........", 21, j); prt_binary(o_ptr->flags_curse, 0, 22, j, '*', 32); prt("Resists, bonuses and slays coming soon...", 23, j); }
/** * 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, NULL); prt("You are using: -more-", 0, 0); (void)anykey(); } /* Inventory -- if any */ if (player->upkeep->inven_cnt) { Term_clear(); show_inven(OLIST_WEIGHT, NULL); prt("You are carrying: -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(); }
/* * Allow user to choose a power (racial / mutation) to activate */ void do_cmd_racial_power(void) { power_desc_type power_desc[36]; int num, ask, i = 0; bool flag, redraw; char choice; char out_val[160]; const mutation_type *mut_ptr; /* Wipe desc */ for (num = 0; num < 36; num++) { strcpy(power_desc[num].name, ""); power_desc[num].number = 0; } /* Reset num */ num = 0; /* Not when we're confused */ if (p_ptr->confused) { msg_print("You are too confused to use any powers!"); p_ptr->energy_use = 0; return; } /* Look for racial powers */ for (i = 0; i < MAX_RACE_POWERS; i++) { mut_ptr = &race_powers[i]; if (mut_ptr->which == p_ptr->prace) { strcpy(power_desc[num].name, mut_ptr->name); power_desc[num].level = mut_ptr->level; power_desc[num].cost = mut_ptr->cost; power_desc[num].fail = 100 - racial_chance(mut_ptr->level, mut_ptr->stat, mut_ptr->diff); power_desc[num].number = -1; power_desc[num++].power = mut_ptr; } } /* Not if we don't have any */ if (num == 0 && !p_ptr->muta1) { msg_print("You have no powers to activate."); p_ptr->energy_use = 0; return; } /* Look for appropriate mutations */ if (p_ptr->muta1) { for (i = 0; i < MUT_PER_SET; i++) { mut_ptr = &mutations[i]; if (p_ptr->muta1 & mut_ptr->which) { strcpy(power_desc[num].name, mut_ptr->name); power_desc[num].level = mut_ptr->level; power_desc[num].cost = mut_ptr->cost; power_desc[num].fail = 100 - racial_chance(mut_ptr->level, mut_ptr->stat, mut_ptr->diff); power_desc[num].number = mut_ptr->which; power_desc[num++].power = mut_ptr; } } } /* Nothing chosen yet */ flag = FALSE; /* No redraw yet */ redraw = FALSE; /* Build a prompt */ (void)strnfmt(out_val, 78, "(Powers %c-%c, *=List, ESC=exit) Use which power? ", I2A(0), (num <= 26) ? I2A(num - 1) : '0' + num - 27); if (!repeat_pull(&i) || i<0 || i>=num) { /* Get a spell from the user */ while (!flag && get_com(out_val, &choice)) { /* Request redraw */ if ((choice == ' ') || (choice == '*') || (choice == '?')) { /* Show the list */ if (!redraw) { byte y = 1, x = 0; int ctr = 0; char dummy[80]; char letter; int x1, y1; strcpy(dummy, ""); /* Show list */ redraw = TRUE; /* Save the screen */ screen_save(); /* Print header(s) */ if (num < 17) prt(" Lv Cost Fail", y++, x); else prt(" Lv Cost Fail Lv Cost Fail", y++, x); /* Print list */ while (ctr < num) { /* letter/number for power selection */ if (ctr < 26) letter = I2A(ctr); else letter = '0' + ctr - 26; x1 = ((ctr < 17) ? x : x + 40); y1 = ((ctr < 17) ? y + ctr : y + ctr - 17); sprintf(dummy, " %c) %-23.23s %2d %4d %3d%%", letter, power_desc[ctr].name, power_desc[ctr].level, power_desc[ctr].cost, power_desc[ctr].fail); prt(dummy, y1, x1); ctr++; } } /* Hide the list */ else { /* Hide list */ redraw = FALSE; /* Restore the screen */ screen_load(); } /* Redo asking */ continue; } if (choice == '\r' && num == 1) { choice = 'a'; } if (isalpha(choice)) { /* Note verify */ ask = (isupper(choice)); /* Lowercase */ if (ask) choice = tolower(choice); /* Extract request */ i = (islower(choice) ? A2I(choice) : -1); } else { ask = FALSE; /* Can't uppercase digits */ i = choice - '0' + 26; } /* Totally Illegal */ if ((i < 0) || (i >= num)) { bell(); continue; } /* Verify it */ if (ask) { char tmp_val[160]; /* Prompt */ (void)strnfmt(tmp_val, 78, "Use %s? ", power_desc[i].name); /* Belay that order */ if (!get_check(tmp_val)) continue; } /* Stop the loop */ flag = TRUE; } /* Restore the screen */ if (redraw) screen_load(); /* Abort if needed */ if (!flag) { p_ptr->energy_use = 0; return; } repeat_push(i); } if (power_desc[i].number == -1) { cmd_racial_power_aux(power_desc[i].power); } else { mutation_power_aux(power_desc[i].power); } /* Success */ return; }
/** * Try to create an item again. Output some statistics. -Bernd- * * The statistics are correct now. We acquire a clean grid, and then * repeatedly place an object in this grid, copying it into an item * holder, and then deleting the object. We fiddle with the artifact * counter flags to prevent weirdness. We use the items to collect * statistics on item creation relative to the initial item. */ static void wiz_statistics(object_type * o_ptr) { long i, matches, better, worse, other; struct keypress ch; char *quality; bool good, great; object_type *i_ptr; object_type object_type_body; const char *q = "Rolls: %ld, Matches: %ld, Better: %ld, Worse: %ld, Other: %ld"; /* Mega-Hack -- allow multiple artifacts XXX XXX XXX */ if (artifact_p(o_ptr)) a_info[o_ptr->name1].created = FALSE; /* Interact */ while (TRUE) { const char *pmt = "Roll for [n]ormal, [g]ood, or [e]xcellent treasure? "; /* Display item */ wiz_display_item(o_ptr); /* Get choices */ if (!get_com(pmt, &ch)) break; if (ch.code == 'n' || ch.code == 'N') { good = FALSE; great = FALSE; quality = "normal"; } else if (ch.code == 'g' || ch.code == 'G') { good = TRUE; great = FALSE; quality = "good"; } else if (ch.code == 'e' || ch.code == 'E') { good = TRUE; great = TRUE; quality = "excellent"; } else { good = FALSE; great = FALSE; break; } /* Let us know what we are doing */ msg("Creating a lot of %s items. Base level = %d.", quality, p_ptr->danger); message_flush(); /* Set counters to zero */ matches = better = worse = other = 0; /* Let's rock and roll */ for (i = 0; i <= TEST_ROLL; i++) { /* Output every few rolls */ if ((i < 100) || (i % 100 == 0)) { struct keypress kp; /* Do not wait */ inkey_scan = SCAN_INSTANT; /* Allow interupt */ kp = inkey(); if (kp.type != EVT_NONE) { flush(); break; } /* Dump the stats */ prt(format(q, i, matches, better, worse, other), 0, 0); Term_fresh(); } /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* Create an object */ make_object(i_ptr, good, great, FALSE); /* Mega-Hack -- allow multiple artifacts XXX XXX XXX */ if (artifact_p(i_ptr)) a_info[i_ptr->name1].created = FALSE; /* Test for the same tval and sval. */ if ((o_ptr->tval) != (i_ptr->tval)) continue; if ((o_ptr->sval) != (i_ptr->sval)) continue; /* Check for match */ if ((i_ptr->pval == o_ptr->pval) && (i_ptr->to_a == o_ptr->to_a) && (i_ptr->to_h == o_ptr->to_h) && (i_ptr->to_d == o_ptr->to_d)) { matches++; } /* Check for better */ else if ((i_ptr->pval >= o_ptr->pval) && (i_ptr->to_a >= o_ptr->to_a) && (i_ptr->to_h >= o_ptr->to_h) && (i_ptr->to_d >= o_ptr->to_d)) { better++; } /* Check for worse */ else if ((i_ptr->pval <= o_ptr->pval) && (i_ptr->to_a <= o_ptr->to_a) && (i_ptr->to_h <= o_ptr->to_h) && (i_ptr->to_d <= o_ptr->to_d)) { worse++; } /* Assume different */ else { other++; } } /* Final dump */ msg(q, i, matches, better, worse, other); message_flush(); } /* Hack -- Normally only make a single artifact */ if (artifact_p(o_ptr)) a_info[o_ptr->name1].created = TRUE; }
void prterr(char *prefix) { prt("%s%s%s\n", prefix, prefix ? ": " : "", strerror(errno)); }
void prterrcode(char *prefix, int code) { prt("%s%s%s\n", prefix, prefix ? ": " : "", strerror(-code)); }
void check_clone(int clonenum) { char filename[128]; char imagename[128]; int ret, fd; struct rbd_ctx cur_ctx = RBD_CTX_INIT; struct stat file_info; char *good_buf, *temp_buf; clone_imagename(imagename, sizeof(imagename), clonenum); if ((ret = ops->open(imagename, &cur_ctx)) < 0) { prterrcode("check_clone: ops->open", ret); exit(167); } clone_filename(filename, sizeof(filename), clonenum + 1); if ((fd = open(filename, O_RDONLY)) < 0) { simple_err("check_clone: open", -errno); exit(168); } prt("checking clone #%d, image %s against file %s\n", clonenum, imagename, filename); if ((ret = fstat(fd, &file_info)) < 0) { simple_err("check_clone: fstat", -errno); exit(169); } good_buf = NULL; ret = posix_memalign((void **)&good_buf, MAX(writebdy, (int)sizeof(void *)), file_info.st_size); if (ret > 0) { prterrcode("check_clone: posix_memalign(good_buf)", -ret); exit(96); } temp_buf = NULL; ret = posix_memalign((void **)&temp_buf, MAX(readbdy, (int)sizeof(void *)), file_info.st_size); if (ret > 0) { prterrcode("check_clone: posix_memalign(temp_buf)", -ret); exit(97); } if ((ret = pread(fd, good_buf, file_info.st_size, 0)) < 0) { simple_err("check_clone: pread", -errno); exit(170); } if ((ret = ops->read(&cur_ctx, 0, file_info.st_size, temp_buf)) < 0) { prterrcode("check_clone: ops->read", ret); exit(171); } close(fd); if ((ret = ops->close(&cur_ctx)) < 0) { prterrcode("check_clone: ops->close", ret); exit(174); } check_buffers(good_buf, temp_buf, 0, file_info.st_size); unlink(filename); free(good_buf); free(temp_buf); }
void test(void) { unsigned long offset; unsigned long size = maxoplen; unsigned long rv = get_random(); unsigned long op; if (simulatedopcount > 0 && testcalls == simulatedopcount) writefileimage(); testcalls++; if (closeprob) closeopen = (rv >> 3) < (1u << 28) / (unsigned)closeprob; if (debugstart > 0 && testcalls >= debugstart) debug = 1; if (!quiet && testcalls < simulatedopcount && testcalls % 100000 == 0) prt("%lu...\n", testcalls); offset = get_random(); if (randomoplen) size = get_random() % (maxoplen + 1); /* calculate appropriate op to run */ if (lite) op = rv % OP_MAX_LITE; else op = rv % OP_MAX_FULL; switch (op) { case OP_MAPREAD: if (!mapped_reads) op = OP_READ; break; case OP_MAPWRITE: if (!mapped_writes) op = OP_WRITE; break; case OP_FALLOCATE: if (!fallocate_calls) { log4(OP_SKIPPED, OP_FALLOCATE, offset, size); goto out; } break; case OP_PUNCH_HOLE: if (!punch_hole_calls) { log4(OP_SKIPPED, OP_PUNCH_HOLE, offset, size); goto out; } break; case OP_CLONE: /* clone, 8% chance */ if (!clone_calls || file_size == 0 || get_random() % 100 >= 8) { log4(OP_SKIPPED, OP_CLONE, 0, 0); goto out; } break; case OP_FLATTEN: /* flatten four times as rarely as clone, 2% chance */ if (get_random() % 100 >= 2) { log4(OP_SKIPPED, OP_FLATTEN, 0, 0); goto out; } break; } switch (op) { case OP_READ: TRIM_OFF_LEN(offset, size, file_size); doread(offset, size); break; case OP_WRITE: TRIM_OFF_LEN(offset, size, maxfilelen); dowrite(offset, size); break; case OP_MAPREAD: TRIM_OFF_LEN(offset, size, file_size); exit(183); break; case OP_MAPWRITE: TRIM_OFF_LEN(offset, size, maxfilelen); exit(182); break; case OP_TRUNCATE: if (!style) size = get_random() % maxfilelen; dotruncate(size); break; case OP_PUNCH_HOLE: TRIM_OFF_LEN(offset, size, file_size); do_punch_hole(offset, size); break; case OP_CLONE: do_clone(); break; case OP_FLATTEN: do_flatten(); break; default: prterr("test: unknown operation"); report_failure(42); break; } out: if (sizechecks && testcalls > simulatedopcount) check_size(); if (closeopen) docloseopen(); }
void do_clone() { char filename[1024]; char imagename[1024]; char lastimagename[1024]; int ret, fd; int order = 0, stripe_unit = 0, stripe_count = 0; uint64_t newsize = file_size; log4(OP_CLONE, 0, 0, 0); ++num_clones; if (randomize_striping) { order = 18 + get_random() % 8; stripe_unit = 1ull << (order - 1 - (get_random() % 8)); stripe_count = 2 + get_random() % 14; } prt("%lu clone\t%d order %d su %d sc %d\n", testcalls, num_clones, order, stripe_unit, stripe_count); clone_imagename(imagename, sizeof(imagename), num_clones); clone_imagename(lastimagename, sizeof(lastimagename), num_clones - 1); assert(strcmp(lastimagename, ctx.name) == 0); ret = ops->clone(&ctx, "snap", imagename, &order, stripe_unit, stripe_count); if (ret < 0) { prterrcode("do_clone: ops->clone", ret); exit(165); } if (randomize_parent_overlap && rbd_image_has_parent(&ctx)) { int rand = get_random() % 16 + 1; // [1..16] if (rand < 13) { uint64_t overlap; ret = rbd_get_overlap(ctx.image, &overlap); if (ret < 0) { prterrcode("do_clone: rbd_get_overlap", ret); exit(1); } if (rand < 10) { // 9/16 newsize = overlap * ((double)rand / 10); newsize -= newsize % truncbdy; } else { // 3/16 newsize = 0; } assert(newsize != (uint64_t)file_size); prt("truncating image %s from 0x%llx (overlap 0x%llx) to 0x%llx\n", ctx.name, file_size, overlap, newsize); ret = ops->resize(&ctx, newsize); if (ret < 0) { prterrcode("do_clone: ops->resize", ret); exit(1); } } else if (rand < 15) { // 2/16 prt("flattening image %s\n", ctx.name); ret = ops->flatten(&ctx); if (ret < 0) { prterrcode("do_clone: ops->flatten", ret); exit(1); } } else { // 2/16 prt("leaving image %s intact\n", ctx.name); } } clone_filename(filename, sizeof(filename), num_clones); if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { simple_err("do_clone: open", -errno); exit(162); } save_buffer(good_buf, newsize, fd); if ((ret = close(fd)) < 0) { simple_err("do_clone: close", -errno); exit(163); } /* * Close parent. */ if ((ret = ops->close(&ctx)) < 0) { prterrcode("do_clone: ops->close", ret); exit(174); } /* * Open freshly made clone. */ if ((ret = ops->open(imagename, &ctx)) < 0) { prterrcode("do_clone: ops->open", ret); exit(166); } if (num_clones > 1) check_clone(num_clones - 2); }
void Prop2D::render(Camera *cam, DrawBatchList *bl ) { if( debug_id ) { assertmsg(deck || grid_used_num > 0 || children_num > 0 || prim_drawer , "no deck/grid/prim_drawer is set. deck:%p grid:%d child:%d prim:%p", deck, grid_used_num, children_num, prim_drawer ); } float camx=0.0f; float camy=0.0f; if(cam){ camx = cam->loc.x; camy = cam->loc.y; } if( children_num > 0 && render_children_first ){ for(int i=0;i<children_num;i++){ Prop2D *p = (Prop2D*) children[i]; if( p->visible ) { if( !p->parent_group ) { p->parent_group = parent_group; } p->render( cam, bl ); } } } if( grid_used_num > 0 ){ glEnable(GL_TEXTURE_2D); glColor4f(color.r,color.g,color.b,color.a); for(int i=0;i<grid_used_num;i++){ Grid *grid = grids[i]; if(!grid)break; if(!grid->visible)continue; if(!grid->index_table)continue; Deck *draw_deck = deck; if( grid->deck ) draw_deck = grid->deck; if( grid->fragment_shader ){ #if !(TARGET_IPHONE_SIMULATOR ||TARGET_OS_IPHONE || defined(__linux__) ) glUseProgram(grid->fragment_shader->program ); #endif grid->fragment_shader->updateUniforms(); } if(!grid->mesh) { // print("new grid mesh! wh:%d,%d", grid->width, grid->height ); grid->mesh = new Mesh(); VertexFormat *vf = DrawBatch::getVertexFormat( VFTYPE_COORD_COLOR_UV ); IndexBuffer *ib = new IndexBuffer(); VertexBuffer *vb = new VertexBuffer(); vb->setFormat(vf); /* 3+--+--+--+--+ | | | | | 2+--+--+--+--+ | | | | | 1+--+--+--+--+ | | | | | 0+--+--+--+--+ 0 1 2 3 4 */ int quad_num = grid->width * grid->height; int triangle_num = quad_num * 2; int vert_num = quad_num * 4; // Can't share vertices because each vert has different UVs vb->reserve( vert_num); ib->reserve( triangle_num*3 ); grid->mesh->setVertexBuffer(vb); grid->mesh->setIndexBuffer(ib); grid->mesh->setPrimType( GL_TRIANGLES ); grid->uv_changed = true; grid->color_changed = true; } if( grid->uv_changed || grid->color_changed ) { if(grid->debug) { print("debug:%d Grid changed: uv:%d col:%d", grid->debug, grid->uv_changed, grid->color_changed ); } grid->uv_changed = false; grid->color_changed = false; VertexBuffer *vb = grid->mesh->vb; IndexBuffer *ib = grid->mesh->ib; vb->unbless(); ib->unbless(); int quad_cnt=0; for(int y=0;y<grid->height;y++) { for(int x=0;x<grid->width;x++) { int ind = x+y*grid->width; if(grid->debug) { if(grid->texofs_table) { prt("%.2f,%.2f ", grid->texofs_table[ind].x, grid->texofs_table[ind].y ); } else if( grid->index_table ) { prt("%3d ", grid->index_table[ind] ); } } if( grid->index_table[ind] == Grid::GRID_NOT_USED ) continue; Vec2 left_bottom, right_top; float u0,v0,u1,v1; draw_deck->getUVFromIndex( grid->index_table[ind], &u0,&v0,&u1,&v1,0,0,grid->uv_margin); if(grid->texofs_table) { float u_per_cell = draw_deck->getUperCell(); float v_per_cell = draw_deck->getVperCell(); u0 += grid->texofs_table[ind].x * u_per_cell; v0 += grid->texofs_table[ind].y * v_per_cell; u1 += grid->texofs_table[ind].x * u_per_cell; v1 += grid->texofs_table[ind].y * v_per_cell; } // // Q (u0,v0) - R (u1,v0) top-bottom upside down. // | | // | | // P (u0,v1) - S (u1,v1) // if(grid->xflip_table && grid->xflip_table[ind]) { swapf( &u0, &u1 ); } if(grid->yflip_table && grid->yflip_table[ind]) { swapf( &v0, &v1 ); } Vec2 uv_p(u0,v1), uv_q(u0,v0), uv_r(u1,v0), uv_s(u1,v1); // left bottom const float d = 1; int vi = quad_cnt * 4; vb->setCoord(vi,Vec3(d*x-enfat_epsilon,d*y-enfat_epsilon,0)); if(grid->rot_table && grid->rot_table[ind]) vb->setUV(vi,uv_s); else vb->setUV(vi,uv_p); if(grid->color_table) vb->setColor(vi, grid->color_table[ind]); else vb->setColor(vi, Color(1,1,1,1)); // right bottom vb->setCoord(vi+1,Vec3(d*(x+1)+enfat_epsilon,d*y-enfat_epsilon,0)); if(grid->rot_table && grid->rot_table[ind]) vb->setUV(vi+1,uv_r); else vb->setUV(vi+1,uv_s); if(grid->color_table) vb->setColor(vi+1,grid->color_table[ind]); else vb->setColor(vi+1, Color(1,1,1,1)); // left top vb->setCoord(vi+2,Vec3(d*x-enfat_epsilon,d*(y+1)+enfat_epsilon,0)); if(grid->rot_table && grid->rot_table[ind]) vb->setUV(vi+2,uv_p); else vb->setUV(vi+2,uv_q); if(grid->color_table) vb->setColor(vi+2,grid->color_table[ind]); else vb->setColor(vi+2, Color(1,1,1,1)); // right top vb->setCoord(vi+3,Vec3(d*(x+1)+enfat_epsilon,d*(y+1)+enfat_epsilon,0)); if(grid->rot_table && grid->rot_table[ind]) vb->setUV(vi+3,uv_q); else vb->setUV(vi+3,uv_r); if(grid->color_table) vb->setColor(vi+3,grid->color_table[ind]); else vb->setColor(vi+3, Color(1,1,1,1)); // TODO: no need to update index every time it changes. int indi = quad_cnt * 6; // 2 triangles = 6 verts per quad ib->setIndex(indi++, quad_cnt*4+0 ); ib->setIndex(indi++, quad_cnt*4+2 ); ib->setIndex(indi++, quad_cnt*4+1 ); ib->setIndex(indi++, quad_cnt*4+1 ); ib->setIndex(indi++, quad_cnt*4+2 ); ib->setIndex(indi++, quad_cnt*4+3 ); quad_cnt++; // next quad! } if(grid->debug) print(""); } ib->setRenderLen(quad_cnt*6); } // draw if(!draw_deck) { print("no tex? (grid)"); continue; } if( grid->mesh == NULL || grid->mesh->hasIndexesToRender() == false ) { continue; } FragmentShader *fs = fragment_shader; if( grid->fragment_shader ) fs = grid->fragment_shader; // print("appendMesh, tex:%d vn:%d rn:%d", draw_deck->tex->tex, grid->mesh->vb->array_len, grid->mesh->ib->render_len ); Vec2 finloc(loc.x+grid->rel_loc.x, loc.y+grid->rel_loc.y); Vec2 finscl(scl.x*grid->rel_scl.x, scl.y*grid->rel_scl.y); if(!fs)fs=default_fs; bl->appendMesh( getViewport(), fs, getBlendType(), draw_deck->tex->tex, finloc - Vec2(camx,camy), finscl, rot, grid->mesh, copy_mesh_at_draw ); } } if(deck && index >= 0 ){ float u0,v0,u1,v1; deck->getUVFromIndex( index, &u0,&v0,&u1,&v1,0,0,uv_margin); if(xflip) { swapf(&u0,&u1); } if(yflip) { swapf(&v0,&v1); } // Q (u0,v0) - R (u1,v0) top-bottom upside down. // | | // | | // P (u0,v1) - S (u1,v1) Vec2 uv_p(u0,v1), uv_q(u0,v0), uv_r(u1,v0), uv_s(u1,v1); if(uvrot) { Vec2 tmp = uv_p; uv_p = uv_s; uv_s = uv_r; uv_r = uv_q; uv_q = tmp; } if(!fragment_shader)fragment_shader=default_fs; bl->appendSprite1( getViewport(), fragment_shader, getBlendType(), deck->tex->tex, color, loc - Vec2(camx,camy) + draw_offset, scl, rot, uv_p, uv_q, uv_r, uv_s ); } if( children_num > 0 && (render_children_first == false) ){ for(int i=0;i<children_num;i++){ Prop2D *p = (Prop2D*) children[i]; if(p->visible) { if( !p->parent_group ) { p->parent_group = parent_group; } p->render( cam, bl ); } } } // primitives should go over image sprites if( prim_drawer ){ prim_drawer->drawAll( bl, getViewport(), loc - Vec2(camx,camy),scl,rot); } }
struct ccnl_lambdaTerm_s* ccnl_lambdaStrToTerm(int lev, char **cp, int (*prt)(char* fmt, ...)) { /* t = (v, m, n) var: v!=0, m=0, n=0 app: v=0, m=f, n=arg lambda: v!=0, m=body, n=0 */ struct ccnl_lambdaTerm_s *t = 0, *s, *u; while (**cp) { while (isspace(**cp)) *cp += 1; // myprintf(stderr, "parseKRIVINE %d %s\n", lev, *cp); if (**cp == ')') return t; if (**cp == '(') { *cp += 1; s = ccnl_lambdaStrToTerm(lev+1, cp, prt); if (!s) return 0; if (**cp != ')') { if (prt) { prt("parseKRIVINE error: missing )\n"); } return 0; } else { *cp += 1; } } else if (**cp == LAMBDACHAR) { *cp += 1; s = ccnl_calloc(1, sizeof(*s)); s->v = ccnl_lambdaParseVar(cp); s->m = ccnl_lambdaStrToTerm(lev+1, cp, prt); // printKRIVINE(dummybuf, s->m, 0); // printf(" after lambda: /%s %s --> <%s>\n", s->v, dummybuf, *cp); } else { s = ccnl_calloc(1, sizeof(*s)); s->v = ccnl_lambdaParseVar(cp); // printf(" var: <%s>\n", s->v); } if (t) { // printKRIVINE(dummybuf, t, 0); // printf(" old term: <%s>\n", dummybuf); u = ccnl_calloc(1, sizeof(*u)); u->m = t; u->n = s; t = u; } else { t = s; } // printKRIVINE(dummybuf, t, 0); // printf(" new term: <%s>\n", dummybuf); } // printKRIVINE(dummybuf, t, 0); // printf(" we return <%s>\n", dummybuf); return t; }
/* * Specify tval and sval (type and subtype of object) originally * 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]); }
void logdump(void) { int i, count, down; struct log_entry *lp; char *falloc_type[3] = {"PAST_EOF", "EXTENDING", "INTERIOR"}; prt("LOG DUMP (%d total operations):\n", logcount); if (logcount < LOGSIZE) { i = 0; count = logcount; } else { i = logptr; count = LOGSIZE; } for ( ; count > 0; count--) { int opnum; opnum = i+1 + (logcount/LOGSIZE)*LOGSIZE; prt("%d(%3d mod 256): ", opnum, opnum%256); lp = &oplog[i]; if ((closeopen = lp->operation < 0)) lp->operation = ~ lp->operation; switch (lp->operation) { case OP_MAPREAD: prt("MAPREAD 0x%x thru 0x%x\t(0x%x bytes)", lp->args[0], lp->args[0] + lp->args[1] - 1, lp->args[1]); if (badoff >= lp->args[0] && badoff < lp->args[0] + lp->args[1]) prt("\t***RRRR***"); break; case OP_MAPWRITE: prt("MAPWRITE 0x%x thru 0x%x\t(0x%x bytes)", lp->args[0], lp->args[0] + lp->args[1] - 1, lp->args[1]); if (badoff >= lp->args[0] && badoff < lp->args[0] + lp->args[1]) prt("\t******WWWW"); break; case OP_READ: prt("READ 0x%x thru 0x%x\t(0x%x bytes)", lp->args[0], lp->args[0] + lp->args[1] - 1, lp->args[1]); if (badoff >= lp->args[0] && badoff < lp->args[0] + lp->args[1]) prt("\t***RRRR***"); break; case OP_WRITE: prt("WRITE 0x%x thru 0x%x\t(0x%x bytes)", lp->args[0], lp->args[0] + lp->args[1] - 1, lp->args[1]); if (lp->args[0] > lp->args[2]) prt(" HOLE"); else if (lp->args[0] + lp->args[1] > lp->args[2]) prt(" EXTEND"); if ((badoff >= lp->args[0] || badoff >=lp->args[2]) && badoff < lp->args[0] + lp->args[1]) prt("\t***WWWW"); break; case OP_TRUNCATE: down = lp->args[0] < lp->args[1]; prt("TRUNCATE %s\tfrom 0x%x to 0x%x", down ? "DOWN" : "UP", lp->args[1], lp->args[0]); if (badoff >= lp->args[!down] && badoff < lp->args[!!down]) prt("\t******WWWW"); break; case OP_FALLOCATE: /* 0: offset 1: length 2: where alloced */ prt("FALLOC 0x%x thru 0x%x\t(0x%x bytes) %s", lp->args[0], lp->args[0] + lp->args[1], lp->args[1], falloc_type[lp->args[2]]); if (badoff >= lp->args[0] && badoff < lp->args[0] + lp->args[1]) prt("\t******FFFF"); break; case OP_PUNCH_HOLE: prt("PUNCH 0x%x thru 0x%x\t(0x%x bytes)", lp->args[0], lp->args[0] + lp->args[1] - 1, lp->args[1]); if (badoff >= lp->args[0] && badoff < lp->args[0] + lp->args[1]) prt("\t******PPPP"); break; case OP_CLONE: prt("CLONE"); break; case OP_FLATTEN: prt("FLATTEN"); break; case OP_SKIPPED: prt("SKIPPED (no operation)"); break; default: prt("BOGUS LOG ENTRY (operation code = %d)!", lp->operation); } if (closeopen) prt("\n\t\tCLOSE/OPEN"); prt("\n"); i++; if (i == LOGSIZE) i = 0; } }
/* * Try to create an item again. Output some statistics. -Bernd- * * The statistics are correct now. We acquire a clean grid, and then * repeatedly place an object in this grid, copying it into an item * holder, and then deleting the object. We fiddle with the artifact * counter flags to prevent weirdness. We use the items to collect * statistics on item creation relative to the initial item. */ static void wiz_statistics(object_type *o_ptr) { u32b i, matches, better, worse, other, correct; u32b test_roll = 1000000; char ch; cptr quality; u32b mode; object_type forge; object_type *q_ptr; cptr q = "Rolls: %ld Correct: %ld Matches: %ld Better: %ld Worse: %ld Other: %ld"; cptr p = "Enter number of items to roll: "; char tmp_val[80]; /* XXX XXX XXX Mega-Hack -- allow multiple artifacts */ if (object_is_fixed_artifact(o_ptr)) a_info[o_ptr->name1].cur_num = 0; /* Interact */ while (TRUE) { cptr pmt = "Roll for [n]ormal, [g]ood, or [e]xcellent treasure? "; /* Display item */ wiz_display_item(o_ptr); /* Get choices */ if (!get_com(pmt, &ch, FALSE)) break; if (ch == 'n' || ch == 'N') { mode = 0L; quality = "normal"; } else if (ch == 'g' || ch == 'G') { mode = AM_GOOD; quality = "good"; } else if (ch == 'e' || ch == 'E') { mode = AM_GOOD | AM_GREAT; quality = "excellent"; } else { break; } sprintf(tmp_val, "%ld", (long int)test_roll); if (get_string(p, tmp_val, 10)) test_roll = atol(tmp_val); test_roll = MAX(1, test_roll); /* Let us know what we are doing */ msg_format("Creating a lot of %s items. Base level = %d.", quality, dun_level); msg_print(NULL); /* Set counters to zero */ correct = matches = better = worse = other = 0; /* Let's rock and roll */ for (i = 0; i <= test_roll; i++) { /* Output every few rolls */ if ((i < 100) || (i % 100 == 0)) { /* Do not wait */ inkey_scan = TRUE; /* Allow interupt */ if (inkey()) { /* Flush */ flush(); /* Stop rolling */ break; } /* Dump the stats */ prt(format(q, i, correct, matches, better, worse, other), 0, 0); Term_fresh(); } /* Get local object */ q_ptr = &forge; /* Wipe the object */ object_wipe(q_ptr); /* Create an object */ make_object(q_ptr, mode); /* XXX XXX XXX Mega-Hack -- allow multiple artifacts */ if (object_is_fixed_artifact(q_ptr)) a_info[q_ptr->name1].cur_num = 0; /* Test for the same tval and sval. */ if ((o_ptr->tval) != (q_ptr->tval)) continue; if ((o_ptr->sval) != (q_ptr->sval)) continue; /* One more correct item */ correct++; /* Check for match */ if ((q_ptr->pval == o_ptr->pval) && (q_ptr->to_a == o_ptr->to_a) && (q_ptr->to_h == o_ptr->to_h) && (q_ptr->to_d == o_ptr->to_d) && (q_ptr->name1 == o_ptr->name1)) { matches++; } /* Check for better */ else if ((q_ptr->pval >= o_ptr->pval) && (q_ptr->to_a >= o_ptr->to_a) && (q_ptr->to_h >= o_ptr->to_h) && (q_ptr->to_d >= o_ptr->to_d)) { better++; } /* Check for worse */ else if ((q_ptr->pval <= o_ptr->pval) && (q_ptr->to_a <= o_ptr->to_a) && (q_ptr->to_h <= o_ptr->to_h) && (q_ptr->to_d <= o_ptr->to_d)) { worse++; } /* Assume different */ else { other++; } } /* Final dump */ msg_format(q, i, correct, matches, better, worse, other); msg_print(NULL); } /* Hack -- Normally only make a single artifact */ if (object_is_fixed_artifact(o_ptr)) a_info[o_ptr->name1].cur_num = 1; }
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", player_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; }
static _slot_info_ptr _choose(cptr verb, int options) { _slot_info_ptr result = NULL; int slot = 0; int cmd; rect_t r = _menu_rect(); string_ptr prompt = NULL; bool done = FALSE; bool exchange = FALSE; int slot1 = _INVALID_SLOT, slot2 = _INVALID_SLOT; if (REPEAT_PULL(&cmd)) { slot = A2I(cmd); if (0 <= slot && slot < _MAX_SLOTS) return &_spells[slot]; } prompt = string_alloc(); screen_save(); while (!done) { string_clear(prompt); if (exchange) { if (slot1 == _INVALID_SLOT) string_append_s(prompt, "Select the first spell:"); else string_append_s(prompt, "Select the second spell:"); } else { string_printf(prompt, "%s which spell", verb); if (options & _ALLOW_EXCHANGE) string_append_s(prompt, " [Press 'X' to Exchange]"); string_append_c(prompt, ':'); } prt(string_buffer(prompt), 0, 0); _display(r, options); cmd = inkey_special(FALSE); if (cmd == ESCAPE || cmd == 'q' || cmd == 'Q') done = TRUE; if (options & _ALLOW_EXCHANGE) { if (!exchange && (cmd == 'x' || cmd == 'X')) { exchange = TRUE; slot1 = slot2 = _INVALID_SLOT; } } if ('a' <= cmd && cmd < 'a' + _MAX_SLOTS) { slot = A2I(cmd); if (exchange) { if (slot1 == _INVALID_SLOT) slot1 = slot; else { slot2 = slot; if (slot1 != slot2) { _slot_info_t tmp = _spells[slot1]; _spells[slot1] = _spells[slot2]; _spells[slot2] = tmp; } exchange = FALSE; slot1 = slot2 = _INVALID_SLOT; } } else { if (_spells[slot].realm != REALM_NONE || (options & _ALLOW_EMPTY)) { result = &_spells[slot]; done = TRUE; } } } } if (result) { REPEAT_PUSH(I2A(slot)); } screen_load(); string_free(prompt); return result; }
/* * Request a command from the user. * * Note that "caret" ("^") is treated specially, and is used to * allow manual input of control characters. This can be used * on many machines to request repeated tunneling (Ctrl-H) and * on the Macintosh to request "Control-Caret". * * Note that "backslash" is treated specially, and is used to bypass any * keymap entry for the following character. This is useful for macros. */ static ui_event_data textui_get_command(void) { int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; char tmp[2] = { '\0', '\0' }; ui_event_data ke = EVENT_EMPTY; cptr act = NULL; /* Get command */ while (1) { /* Hack -- no flush needed */ msg_flag = FALSE; /* Activate "command mode" */ inkey_flag = TRUE; /* Get a command */ ke = inkey_ex(); /* Command Count */ if (ke.key == '0') { int count = textui_get_count(); if (count == -1 || !get_com_ex("Command: ", &ke)) continue; else p_ptr->command_arg = count; } /* Allow "keymaps" to be bypassed */ else if (ke.key == '\\') { /* Get a real command */ (void)get_com("Command: ", &ke.key); /* Hack -- bypass keymaps */ if (!inkey_next) inkey_next = ""; } /* Allow "control chars" to be entered */ else if (ke.key == '^') { /* Get a new command and controlify it */ if (get_com("Control: ", &ke.key)) ke.key = KTRL(ke.key); } /* Special case for the arrow keys */ else if (isarrow(ke.key)) { switch (ke.key) { case ARROW_DOWN: ke.key = '2'; break; case ARROW_LEFT: ke.key = '4'; break; case ARROW_RIGHT: ke.key = '6'; break; case ARROW_UP: ke.key = '8'; break; } } /* Erase the message line */ prt("", 0, 0); if (ke.type == EVT_BUTTON) { /* Buttons are always specified in standard keyset */ act = tmp; tmp[0] = ke.key; } else if (ke.type == EVT_KBRD) { /* Look up applicable keymap */ act = keymap_act[mode][(byte)(ke.key)]; } /* Apply keymap if not inside a keymap already */ if (ke.key && act && !inkey_next) { /* Install the keymap */ my_strcpy(request_command_buffer, act, sizeof(request_command_buffer)); /* Start using the buffer */ inkey_next = request_command_buffer; /* Continue */ continue; } /* Done */ break; } return ke; }
/** * Debug scent trails and noise bursts. */ static void do_cmd_wiz_hack_ben(void) { struct keypress cmd; int py = p_ptr->py; int px = p_ptr->px; int i, y, x, y2, x2; /* Get a "debug command" */ if (!get_com("Press 'S' for scent, 'N' for noise info: ", &cmd)) return; /* Analyze the command */ switch (cmd.code) { case 'S': case 's': { /* Update map */ for (y = Term->offset_y; y <= Term->offset_y + SCREEN_HGT; y++) { for (x = Term->offset_x; x <= Term->offset_x + SCREEN_WID; x++) { byte a; int age = get_scent(y, x); /* Must have scent */ if (age == -1) continue; /* Pretty colors by age */ if (age > SMELL_STRENGTH) a = TERM_L_DARK; else if (age < 10) a = TERM_BLUE; else if (age < 20) a = TERM_L_BLUE; else if (age < 30) a = TERM_GREEN; else if (age < 40) a = TERM_L_GREEN; else if (age < 50) a = TERM_YELLOW; else if (age < 60) a = TERM_ORANGE; else if (age < 70) a = TERM_L_RED; else a = TERM_RED; /* Display player/floors/walls */ if ((y == py) && (x == px)) { print_rel('@', a, y, x); } else { print_rel('0' + (age % 10), a, y, x); } } } /* Prompt */ prt("Scent ages", 0, 0); /* Wait for a keypress */ (void) inkey(); /* Redraw map */ prt_map(); break; } case 'N': case 'n': { /* Get a "debug command" */ if (!get_com ("Press 'D' for direction of flow, 'C' for actual cost values: ", &cmd)) return; if ((cmd.code == 'D') || (cmd.code == 'd')) { /* Update map */ for (y = Term->offset_y; y <= Term->offset_y + SCREEN_HGT; y++) { for (x = Term->offset_x; x <= Term->offset_x + SCREEN_WID; x++) { int lowest_cost = cave_cost[y][x]; int dir = -1; int cost; if (lowest_cost == 0) continue; for (i = 0; i < 8; i++) { /* Get the location */ y2 = y + ddy_ddd[i]; x2 = x + ddx_ddd[i]; cost = cave_cost[y2][x2]; if (!cost) continue; /* If this grid's scent is younger, save it */ if (lowest_cost > cost) lowest_cost = cost; /* If it isn't, look elsewhere */ else continue; /* Save this direction */ dir = i; } /* If we didn't find any younger scent, print a '5' */ if (dir == -1) print_rel('5', TERM_YELLOW, y, x); /* Otherwise, convert to true direction and print */ else { i = ddd[dir]; print_rel('0' + i, TERM_L_BLUE, y, x); } } } /* Prompt */ prt("Directions given to advancing monsters using noise info", 0, 0); /* Wait for a keypress */ (void) inkey(); /* Redraw map */ prt_map(); } /* Actual cost values */ else { int j; struct keypress key; for (i = cost_at_center - 2; i <= 100 + NOISE_STRENGTH; ++i) { /* First show grids with no scent */ if (i == cost_at_center - 2) j = 0; /* Then show specially marked grids (bug-checking) */ else if (i == cost_at_center - 1) j = 255; /* Then show standard grids */ else j = i; /* Update map */ for (y = Term->offset_y; y <= Term->offset_y + SCREEN_HGT; y++) { for (x = Term->offset_x; x <= Term->offset_x + SCREEN_WID; x++) { byte a = TERM_YELLOW; feature_type *f_ptr = &f_info[cave_feat[y][x]]; /* Display proper cost */ if (cave_cost[y][x] != j) continue; /* Display player/floors/walls */ if ((y == py) && (x == px)) { print_rel('@', a, y, x); } else if (!tf_has(f_ptr->flags, TF_NO_SCENT)) { print_rel('*', a, y, x); } else { print_rel('#', a, y, x); } } } /* Prompt */ if (j == 0) { prt("Grids with no scent", 0, 0); } else if (j == 255) { prt("Specially marked grids", 0, 0); } else { prt(format("Depth %d: ", j), 0, 0); } /* Get key */ key = inkey(); if (key.code == ESCAPE) break; /* Redraw map */ prt_map(); } } break; } default: { break; } } /* Done */ prt("", 0, 0); /* Redraw map */ prt_map(); }
/* * Interactive group by. * Recognises inscriptions, graphical symbols, lore */ static void display_knowledge(const char *title, int *obj_list, int o_count, group_funcs g_funcs, member_funcs o_funcs, const char *otherfields) { /* maximum number of groups to display */ int max_group = g_funcs.maxnum < o_count ? g_funcs.maxnum : o_count; /* This could (should?) be (void **) */ int *g_list, *g_offset; const char **g_names; int g_name_len = 8; /* group name length, minumum is 8 */ int grp_cnt = 0; /* total number groups */ int g_cur = 0, grp_old = -1; /* group list positions */ int o_cur = 0; /* object list positions */ int g_o_count = 0; /* object count for group */ int oid = -1; /* object identifiers */ region title_area = { 0, 0, 0, 4 }; region group_region = { 0, 6, MISSING, -2 }; region object_region = { MISSING, 6, 0, -2 }; /* display state variables */ bool visual_list = FALSE; byte attr_top = 0; byte char_left = 0; int delay = 0; menu_type group_menu; menu_type object_menu; menu_iter object_iter = { NULL, NULL, display_group_member, NULL, NULL }; /* Panel state */ /* These are swapped in parallel whenever the actively browsing " */ /* changes */ int *active_cursor = &g_cur, *inactive_cursor = &o_cur; menu_type *active_menu = &group_menu, *inactive_menu = &object_menu; int panel = 0; void *swapspace; bool do_swap = FALSE; bool flag = FALSE; bool redraw = TRUE; int browser_rows; int wid, hgt; int i; int prev_g = -1; int omode = OPT(rogue_like_commands); ui_event_data ke; /* Get size */ Term_get_size(&wid, &hgt); browser_rows = hgt - 8; /* Disable the roguelike commands for the duration */ OPT(rogue_like_commands) = FALSE; if (g_funcs.gcomp) sort(obj_list, o_count, sizeof(*obj_list), g_funcs.gcomp); /* Sort everything into group order */ g_list = C_ZNEW(max_group + 1, int); g_offset = C_ZNEW(max_group + 1, int); for (i = 0; i < o_count; i++) { if (prev_g != g_funcs.group(obj_list[i])) { prev_g = g_funcs.group(obj_list[i]); g_offset[grp_cnt] = i; g_list[grp_cnt++] = prev_g; } } g_offset[grp_cnt] = o_count; g_list[grp_cnt] = -1; /* The compact set of group names, in display order */ g_names = C_ZNEW(grp_cnt, const char *); for (i = 0; i < grp_cnt; i++) { int len; g_names[i] = g_funcs.name(g_list[i]); len = strlen(g_names[i]); if (len > g_name_len) g_name_len = len; } /* Reasonable max group name len */ if (g_name_len >= 20) g_name_len = 20; object_region.col = g_name_len + 3; group_region.width = g_name_len; /* Leave room for the group summary information */ if (g_funcs.summary) object_region.page_rows = -3; /* Set up the two menus */ menu_init(&group_menu, MN_SKIN_SCROLL, menu_find_iter(MN_ITER_STRINGS)); menu_setpriv(&group_menu, grp_cnt, g_names); menu_layout(&group_menu, &group_region); menu_init(&object_menu, MN_SKIN_SCROLL, &object_iter); menu_setpriv(&object_menu, 0, &o_funcs); menu_layout(&object_menu, &object_region); o_funcs.is_visual = FALSE; /* Save screen */ screen_save(); clear_from(0); /* This is the event loop for a multi-region panel */ /* Panels are -- text panels, two menus, and visual browser */ /* with "pop-up menu" for lore */ while ((!flag) && (grp_cnt)) { bool recall = FALSE; if (redraw) { /* Print the title bits */ region_erase(&title_area); prt(format("Knowledge - %s", title), 2, 0); prt("Group", 4, 0); prt("Name", 4, g_name_len + 3); if (otherfields) prt(otherfields, 4, 46); /* Print dividers: horizontal and vertical */ for (i = 0; i < 79; i++) Term_putch(i, 5, TERM_WHITE, '='); for (i = 0; i < browser_rows; i++) Term_putch(g_name_len + 1, 6 + i, TERM_WHITE, '|'); /* Reset redraw flag */ redraw = FALSE; } if (g_cur != grp_old) { grp_old = g_cur; o_cur = 0; g_o_count = g_offset[g_cur + 1] - g_offset[g_cur]; menu_set_filter(&object_menu, obj_list + g_offset[g_cur], g_o_count); group_menu.cursor = g_cur; object_menu.cursor = 0; } /* HACK ... */ if (!visual_list) { /* ... The object menu may be browsing the entire group... */ o_funcs.is_visual = FALSE; menu_set_filter(&object_menu, obj_list + g_offset[g_cur], g_o_count); object_menu.cursor = o_cur; } else { /* ... or just a single element in the group. */ o_funcs.is_visual = TRUE; menu_set_filter(&object_menu, obj_list + o_cur + g_offset[g_cur], 1); object_menu.cursor = 0; } oid = obj_list[g_offset[g_cur] + o_cur]; /* Print prompt */ { const char *pedit = (!o_funcs. xattr) ? "" : (!(attr_idx | char_idx) ? ", 'c' to copy" : ", 'c', 'p' to paste"); const char *xtra = o_funcs.xtra_prompt ? o_funcs.xtra_prompt(oid) : ""; const char *pvs = ""; if (visual_list) pvs = ", ENTER to accept"; else if (o_funcs.xattr) pvs = ", 'v' for visuals"; prt(format("<dir>%s%s%s, ESC", pvs, pedit, xtra), hgt - 1, 0); } if (do_swap) { do_swap = FALSE; swap(active_menu, inactive_menu); swap(active_cursor, inactive_cursor); panel = 1 - panel; } if (g_funcs.summary && !visual_list) { g_funcs.summary(g_cur, obj_list, g_o_count, g_offset[g_cur], object_menu.active.row + object_menu.active.page_rows, object_region.col); } menu_refresh(inactive_menu); menu_refresh(active_menu); handle_stuff(); if (visual_list) { bigcurs = TRUE; display_visual_list(g_name_len + 3, 7, browser_rows - 1, wid - (g_name_len + 3), attr_top, char_left); place_visual_list_cursor(g_name_len + 3, 7, *o_funcs.xattr(oid), *o_funcs.xchar(oid), attr_top, char_left); } if (delay) { /* Force screen update */ Term_fresh(); /* Delay */ Term_xtra(TERM_XTRA_DELAY, delay); delay = 0; } ke = inkey_ex(); if (!visual_list) { ui_event_data ke0 = EVENT_EMPTY; if (ke.type == EVT_MOUSE) menu_handle_mouse(active_menu, &ke, &ke0); else if (ke.type == EVT_KBRD) menu_handle_keypress(active_menu, &ke, &ke0); if (ke0.type != EVT_NONE) ke = ke0; } /* XXX Do visual mode command if needed */ if (o_funcs.xattr && o_funcs.xchar) { if (visual_mode_command (ke, &visual_list, browser_rows - 1, wid - (g_name_len + 3), &attr_top, &char_left, o_funcs.xattr(oid), (byte *) o_funcs.xchar(oid), g_name_len + 3, 7, &delay)) continue; } switch (ke.type) { case EVT_KBRD: { if (ke.key == 'r' || ke.key == 'R') recall = TRUE; else if (o_funcs.xtra_act) o_funcs.xtra_act(ke.key, oid); break; } case EVT_MOUSE: { /* Change active panels */ if (region_inside(&inactive_menu->boundary, &ke)) { swap(active_menu, inactive_menu); swap(active_cursor, inactive_cursor); panel = 1 - panel; } continue; } case EVT_ESCAPE: { if (panel == 1) do_swap = TRUE; else flag = TRUE; break; } case EVT_SELECT: { if (panel == 0) do_swap = TRUE; else if (panel == 1 && oid >= 0 && o_cur == active_menu->cursor) recall = TRUE; break; } case EVT_MOVE: { *active_cursor = active_menu->cursor; break; } default: { break; } } /* Recall on screen */ if (recall) { if (oid >= 0) o_funcs.lore(oid); redraw = TRUE; } } /* Restore roguelike option */ OPT(rogue_like_commands) = omode; /* Prompt */ if (!grp_cnt) prt(format("No %s known.", title), 15, 0); FREE(g_names); FREE(g_offset); FREE(g_list); screen_load(); }
/* * Request a "movement" direction (1,2,3,4,6,7,8,9) from the user. * * Return TRUE if a direction was chosen, otherwise return FALSE. * * This function should be used for all "repeatable" commands, such as * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well * as all commands which must reference a grid adjacent to the player, * and which may not reference the grid under the player. * * Directions "5" and "0" are illegal and will not be accepted. * * This function tracks and uses the "global direction", and uses * that as the "desired direction", if it is set. */ bool get_rep_dir(int *dp) { int dir = 0; ui_event ke; /* Initialize */ (*dp) = 0; /* Get a direction */ while (!dir) { /* Paranoia XXX XXX XXX */ message_flush(); /* Get first keypress - the first test is to avoid displaying the * prompt for direction if there's already a keypress queued up and * waiting - this just avoids a flickering prompt if there is a "lazy" * movement delay. */ inkey_scan = SCAN_INSTANT; ke = inkey_ex(); inkey_scan = SCAN_OFF; if (ke.type == EVT_NONE || (ke.type == EVT_KBRD && target_dir(ke.key) == 0)) { prt("Direction or <click> (Escape to cancel)? ", 0, 0); ke = inkey_ex(); } /* Check mouse coordinates */ if (ke.type == EVT_MOUSE) { /* if (ke.button) */ { int y = KEY_GRID_Y(ke); int x = KEY_GRID_X(ke); /* Calculate approximate angle */ int angle = get_angle_to_target(p_ptr->py, p_ptr->px, y, x, 0); /* Convert angle to direction */ if (angle < 15) dir = 6; else if (angle < 33) dir = 9; else if (angle < 59) dir = 8; else if (angle < 78) dir = 7; else if (angle < 104) dir = 4; else if (angle < 123) dir = 1; else if (angle < 149) dir = 2; else if (angle < 168) dir = 3; else dir = 6; } } /* Get other keypresses until a direction is chosen. */ else { int keypresses_handled = 0; while (ke.type == EVT_KBRD && ke.key.code != 0) { int this_dir; if (ke.key.code == ESCAPE) { /* Clear the prompt */ prt("", 0, 0); return (FALSE); } /* XXX Ideally show and move the cursor here to indicate the * currently "Pending" direction. XXX */ this_dir = target_dir(ke.key); if (this_dir) { dir = dir_transitions[dir][this_dir]; } if (lazymove_delay == 0 || ++keypresses_handled > 1) break; inkey_scan = lazymove_delay; ke = inkey_ex(); } /* 5 is equivalent to "escape" */ if (dir == 5) { /* Clear the prompt */ prt("", 0, 0); return (FALSE); } } /* Oops */ if (!dir) bell("Illegal repeatable direction!"); } /* Clear the prompt */ prt("", 0, 0); /* Save direction */ (*dp) = dir; /* Success */ return (TRUE); }
/** * Pick up objects and treasure on the floor, now also used for telekinesis. * * Called with pickup: * 0 to grab gold and describe non-gold objects. * 1 to pick up objects either with or without displaying a menu. * 2 to pick up objects, forcing a menu for multiple objects. * 3 to pick up objects, forcing a menu for any number of objects. * * Scan the list of objects in that floor grid. Pick up gold automatically. * Pick up objects automatically until pile or backpack space is full if * auto-pickup option is on, carry_query_floor option is not, and menus are * not forced (which the "get" command does). Otherwise, store objects on * floor in an array, and tally both how many there are and can be picked up. * * If the player is not picking up objects, describe a single object or * indicate the presence of a floor stack. If player is picking up objects, * name a single object, or indicate a stack of objects, that cannot go in * the backpack. * * Pick up a single object without menus, unless menus for single items are * forced. Confirm pickup if that option is on. * * Pick up multiple objects (unless using autopickup, no confirm) using Tim * Baker's menu system. Recursively call this function (forcing menus for any * number of objects) until objects are gone, backpack is full, or player is * satisfied. * * Keep track of number of objects picked up (to calculate time spent). */ byte py_pickup(int pickup, int y, int x) { s16b this_o_idx, next_o_idx = 0; char o_name[120]; object_type *o_ptr; /* Objects picked up. Used to determine time cost of command. */ byte objs_picked_up = 0; size_t floor_num = 0; int floor_list[MAX_FLOOR_STACK + 1], floor_o_idx = 0; int can_pickup = 0; bool call_function_again = FALSE; bool blind = ((p_ptr->timed[TMD_BLIND]) || (no_light())); bool domsg = TRUE; bool telekinesis = ((y != p_ptr->py) || (x != p_ptr->px)); /* Always pickup gold, effortlessly */ if (!telekinesis) py_pickup_gold(); /* Nothing to pick up -- return */ if (!cave_o_idx[y][x]) return (objs_picked_up); /* Scan the pile of objects */ for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) { /* Access the object */ o_ptr = &o_list[this_o_idx]; /* Access the next object */ next_o_idx = o_ptr->next_o_idx; /* Ordinary pickup */ if (!telekinesis) { /* Ignore all hidden objects and non-objects */ if (squelch_hide_item(o_ptr) || !o_ptr->k_idx) continue; /* Hack -- disturb */ disturb(0, 0); /* Automatically pick up some items */ if (auto_pickup_okay(o_ptr)) { /* Pick up the object */ py_pickup_aux(this_o_idx, TRUE); objs_picked_up++; /* Check the next object */ continue; } } /* Tally objects and store them in an array. */ /* Remember this object index */ floor_list[floor_num] = this_o_idx; /* Count non-gold objects that remain on the floor. */ floor_num++; /* Tally objects that can be picked up. */ if (inven_carry_okay(o_ptr)) can_pickup++; } /* There are no non-gold objects */ if (!floor_num) return (objs_picked_up); /* Get hold of the last floor index */ floor_o_idx = floor_list[floor_num - 1]; /* Mention the objects if player is not picking them up. */ if (pickup == 0 || !(can_pickup || telekinesis)) { const char *p = "see"; /* One object */ if (floor_num == 1) { if (!can_pickup) p = "have no room for"; else if (blind) p = "feel"; /* Get the object */ o_ptr = &o_list[floor_o_idx]; /* Describe the object. Less detail if blind. */ if (blind) object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_BASE); else object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Message */ message_flush(); msg("You %s %s.", p, o_name); } else { /* Optionally, display more information about floor items */ if (OPT(pickup_detail)) { ui_event e; if (!can_pickup) p = "have no room for the following objects"; else if (blind) p = "feel something on the floor"; /* Scan all marked objects in the grid */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03); /* Save screen */ screen_save(); /* Display objects on the floor */ show_floor(floor_list, floor_num, (OLIST_WEIGHT)); /* Display prompt */ prt(format("You %s: ", p), 0, 0); /* Move cursor back to character, if needed */ if (OPT(highlight_player)) move_cursor_relative(p_ptr->py, p_ptr->px); /* Wait for it. Use key as next command. */ e = inkey_ex(); Term_event_push(&e); /* Restore screen */ screen_load(); } /* Show less detail */ else { message_flush(); if (!can_pickup) msg("You have no room for any of the items on the floor."); else msg("You %s a pile of %d items.", (blind ? "feel" : "see"), floor_num); } } /* Done */ return (objs_picked_up); } /* We can pick up objects. Menus are not requested (yet). */ if (pickup == 1) { /* Scan floor (again) */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03); /* Use a menu interface for multiple objects, or get single objects */ if (floor_num > 1) pickup = 2; else this_o_idx = floor_o_idx; } /* Display a list if requested. */ if (pickup == 2) { const char *q, *s; int item; /* Get an object or exit. */ q = "Get which item?"; s = "You see nothing there."; /* Telekinesis */ if (telekinesis) { item_tester_hook = inven_carry_okay; if (!get_item(&item, q, s, CMD_PICKUP, USE_TARGET)) return (objs_picked_up); this_o_idx = 0 - item; } else { /* Restrict the choices */ item_tester_hook = inven_carry_okay; if (!get_item(&item, q, s, CMD_PICKUP, USE_FLOOR)) return (objs_picked_up); this_o_idx = 0 - item; call_function_again = TRUE; } /* With a list, we do not need explicit pickup messages */ domsg = FALSE; } /* Pick up object, if legal */ if (this_o_idx) { /* Regular pickup or telekinesis with pack not full */ if (can_pickup) { /* Pick up the object */ py_pickup_aux(this_o_idx, domsg); } /* Telekinesis with pack full */ else { /* Access the object */ o_ptr = &o_list[this_o_idx]; /* Drop it */ drop_near(o_ptr, -1, p_ptr->py, p_ptr->px, TRUE); /* Delete the old object */ delete_object_idx(this_o_idx); } } /* Indicate an object picked up. */ objs_picked_up = 1; /* If requested, call this function recursively. Count objects picked up. * Force the display of a menu in all cases. */ if (call_function_again) objs_picked_up += py_pickup(2, y, x); /* Indicate how many objects have been picked up. */ return (objs_picked_up); }
/** * Display list items to choose from */ struct object *item_menu(cmd_code cmd, int prompt_size, int mode) { menu_iter menu_f = { get_item_tag, get_item_validity, get_item_display, get_item_action, 0 }; struct menu *m = menu_new(MN_SKIN_OBJECT, &menu_f); ui_event evt = { 0 }; int ex_offset_ctr = 0; int row, inscrip; struct object *obj = NULL; /* Set up the menu */ menu_setpriv(m, num_obj, items); m->selections = lower_case; m->switch_keys = "/|-"; m->flags = (MN_PVT_TAGS | MN_INSCRIP_TAGS); if (olist_mode & OLIST_QUIVER && player->upkeep->command_wrk == USE_INVEN) m->browse_hook = item_menu_browser; /* Get inscriptions */ m->inscriptions = mem_zalloc(10 * sizeof(char)); for (inscrip = 0; inscrip < 10; inscrip++) { /* Look up the tag */ if (get_tag(&obj, (char)inscrip + '0', item_cmd, item_mode & QUIVER_TAGS)) { int i; for (i = 0; i < num_obj; i++) if (items[i].object == obj) break; if (i < num_obj) m->inscriptions[inscrip] = get_item_tag(m, i); } } /* Set up the item list variables */ selection = NULL; set_obj_names(FALSE); if (mode & OLIST_QUIVER && player->upkeep->quiver[0] != NULL) max_len = MAX(max_len, 24); if (olist_mode & OLIST_WEIGHT) { ex_width += 9; ex_offset_ctr += 9; } if (olist_mode & OLIST_PRICE) { ex_width += 9; ex_offset_ctr += 9; } if (olist_mode & OLIST_FAIL) { ex_width += 10; ex_offset_ctr += 10; } /* Set up the menu region */ area.page_rows = m->count; area.row = 1; area.col = MIN(Term->wid - 1 - (int) max_len - ex_width, prompt_size - 2); if (area.col <= 3) area.col = 0; ex_offset = MIN(max_len, (size_t)(Term->wid - 1 - ex_width - area.col)); while (strlen(header) < max_len + ex_width + ex_offset_ctr) { my_strcat(header, " ", sizeof(header)); if (strlen(header) > sizeof(header) - 2) break; } area.width = MAX(max_len, strlen(header)); for (row = area.row; row < area.row + area.page_rows; row++) prt("", row, MAX(0, area.col - 1)); menu_layout(m, &area); /* Choose */ evt = menu_select(m, 0, TRUE); /* Clean up */ mem_free(m->inscriptions); mem_free(m); /* Deal with menu switch */ if (evt.type == EVT_SWITCH && !newmenu) { bool left = evt.key.code == ARROW_LEFT; if (player->upkeep->command_wrk == USE_EQUIP) { if (left) { if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR; else if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER; else if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN; } else { if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN; else if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER; else if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR; } } else if (player->upkeep->command_wrk == USE_INVEN) { if (left) { if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP; else if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR; else if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER; } else { if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER; else if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR; else if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP; } } else if (player->upkeep->command_wrk == USE_QUIVER) { if (left) { if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN; else if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP; else if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR; } else { if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR; else if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP; else if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN; } } else if (player->upkeep->command_wrk == USE_FLOOR) { if (left) { if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER; else if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN; else if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP; } else { if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP; else if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN; else if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER; } } newmenu = TRUE; } /* Result */ return selection; }
/* * Output a rarity graph for a type of object. */ static void prt_alloc(byte tval, byte sval, int row, int col) { int i, j; int home = 0; u32b rarity[K_MAX_DEPTH]; u32b total[K_MAX_DEPTH]; s32b maxd = 1, display[22]; byte c = TERM_WHITE; cptr r = "+---Rate---+"; object_kind *k_ptr; /* Get the entry */ alloc_entry *table = alloc_kind_table; /* Wipe the tables */ (void)C_WIPE(rarity, K_MAX_DEPTH, u32b); (void)C_WIPE(total, K_MAX_DEPTH, u32b); (void)C_WIPE(display, 22, s32b); /* Scan all entries */ for (i = 0; i < K_MAX_DEPTH; i++) { int total_frac = 0; for (j = 0; j < alloc_kind_size; j++) { int prob = 0; if (table[j].level <= i) { prob = table[j].prob1 * GREAT_OBJ * K_MAX_DEPTH; } else if (table[j].level - 1 > 0) { prob = table[j].prob1 * i * K_MAX_DEPTH / (table[j].level - 1); } /* Acquire this kind */ k_ptr = &k_info[table[j].index]; /* Accumulate probabilities */ total[i] += prob / (GREAT_OBJ * K_MAX_DEPTH); total_frac += prob % (GREAT_OBJ * K_MAX_DEPTH); /* Accumulate probabilities */ if ((k_ptr->tval == tval) && (k_ptr->sval == sval)) { home = k_ptr->level; rarity[i] += prob / (GREAT_OBJ * K_MAX_DEPTH); } } total[i] += total_frac / (GREAT_OBJ * K_MAX_DEPTH); } /* Calculate probabilities for each range */ for (i = 0; i < 22; i++) { /* Shift the values into view */ int possibility = 0; for (j = i * K_MAX_DEPTH / 22; j < (i + 1) * K_MAX_DEPTH / 22; j++) possibility += rarity[j] * 100000 / total[j]; display[i] = possibility / 5; } /* Graph the rarities */ for (i = 0; i < 22; i++) { Term_putch(col, row + i + 1, TERM_WHITE, '|'); prt(format("%2dF", (i * 5)), row + i + 1, col); /* Note the level */ if ((i * K_MAX_DEPTH / 22 <= home) && (home < (i + 1) * K_MAX_DEPTH / 22)) { c_prt(TERM_RED, format("%3d.%04d%%", display[i] / 1000, display[i] % 1000), row + i + 1, col + 3); } else { c_prt(TERM_WHITE, format("%3d.%04d%%", display[i] / 1000, display[i] % 1000), row + i + 1, col + 3); } } /* Make it look nice */ prt(r, row, col); }
void textui_cmd_ignore_menu(struct object *obj) { char out_val[160]; struct menu *m; region r; int selected; if (!obj) return; m = menu_dynamic_new(); m->selections = lower_case; /* Basic ignore option */ if (!obj->ignore) { menu_dynamic_add(m, "This item only", IGNORE_THIS_ITEM); } else { menu_dynamic_add(m, "Unignore this item", UNIGNORE_THIS_ITEM); } /* Flavour-aware ignore */ if (ignore_tval(obj->tval) && (!obj->artifact || !object_flavor_is_aware(obj))) { bool ignored = kind_is_ignored_aware(obj->kind) || kind_is_ignored_unaware(obj->kind); char tmp[70]; object_desc(tmp, sizeof(tmp), obj, ODESC_NOEGO | ODESC_BASE | ODESC_PLURAL); if (!ignored) { strnfmt(out_val, sizeof out_val, "All %s", tmp); menu_dynamic_add(m, out_val, IGNORE_THIS_FLAVOR); } else { strnfmt(out_val, sizeof out_val, "Unignore all %s", tmp); menu_dynamic_add(m, out_val, UNIGNORE_THIS_FLAVOR); } } /* Ego ignoring */ if (object_ego_is_visible(obj)) { ego_desc choice; struct ego_item *ego = obj->ego; char tmp[80] = ""; choice.e_idx = ego->eidx; choice.itype = ignore_type_of(obj); choice.short_name = ""; (void) ego_item_name(tmp, sizeof(tmp), &choice); if (!ego_is_ignored(choice.e_idx, choice.itype)) { strnfmt(out_val, sizeof out_val, "All %s", tmp + 4); menu_dynamic_add(m, out_val, IGNORE_THIS_EGO); } else { strnfmt(out_val, sizeof out_val, "Unignore all %s", tmp + 4); menu_dynamic_add(m, out_val, UNIGNORE_THIS_EGO); } } /* Quality ignoring */ if (object_was_sensed(obj) || object_was_worn(obj) || object_is_known_not_artifact(obj)) { byte value = ignore_level_of(obj); int type = ignore_type_of(obj); if (tval_is_jewelry(obj) && ignore_level_of(obj) != IGNORE_BAD) value = IGNORE_MAX; if (value != IGNORE_MAX && type != ITYPE_MAX) { strnfmt(out_val, sizeof out_val, "All %s %s", quality_values[value].name, ignore_name_for_type(type)); menu_dynamic_add(m, out_val, IGNORE_THIS_QUALITY); } } /* Work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ r.col = 80 - r.width; r.row = 1; r.page_rows = m->count; screen_save(); menu_layout(m, &r); region_erase_bordered(&r); prt("(Enter to select, ESC) Ignore:", 0, 0); selected = menu_dynamic_select(m); screen_load(); if (selected == IGNORE_THIS_ITEM) { obj->ignore = TRUE; } else if (selected == UNIGNORE_THIS_ITEM) { obj->ignore = FALSE; } else if (selected == IGNORE_THIS_FLAVOR) { object_ignore_flavor_of(obj); } else if (selected == UNIGNORE_THIS_FLAVOR) { kind_ignore_clear(obj->kind); } else if (selected == IGNORE_THIS_EGO) { ego_ignore(obj); } else if (selected == UNIGNORE_THIS_EGO) { ego_ignore_clear(obj); } else if (selected == IGNORE_THIS_QUALITY) { byte value = ignore_level_of(obj); int type = ignore_type_of(obj); ignore_level[type] = value; } player->upkeep->notice |= PN_IGNORE; menu_dynamic_free(m); }
/* * Just display an item's properties (debug-info) * Originally by David Reeve Sward <*****@*****.**> * Verbose item flags by -Bernd- */ static void wiz_display_item(object_type *o_ptr) { int i, j = 13; u32b flgs[TR_FLAG_SIZE]; char buf[256]; /* Extract the flags */ object_flags(o_ptr, flgs); /* Clear the screen */ for (i = 1; i <= 23; i++) prt("", i, j - 2); prt_alloc(o_ptr->tval, o_ptr->sval, 1, 0); /* Describe fully */ object_desc(buf, o_ptr, OD_STORE); 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 ac = %-5d damage = %dd%d", o_ptr->number, o_ptr->weight, o_ptr->ac, o_ptr->dd, o_ptr->ds), 5, j); prt(format("pval = %-5d toac = %-5d tohit = %-4d todam = %-4d", o_ptr->pval, o_ptr->to_a, o_ptr->to_h, o_ptr->to_d), 6, j); prt(format("name1 = %-4d name2 = %-4d cost = %ld", o_ptr->name1, o_ptr->name2, (long)object_value_real(o_ptr)), 7, j); prt(format("ident = %04x xtra1 = %-4d xtra2 = %-4d timeout = %-d", o_ptr->ident, o_ptr->xtra1, o_ptr->xtra2, o_ptr->timeout), 8, j); prt(format("xtra3 = %-4d xtra4 = %-4d xtra5 = %-4d cursed = %-d", o_ptr->xtra3, o_ptr->xtra4, o_ptr->xtra5, o_ptr->curse_flags), 9, j); prt("+------------FLAGS1------------+", 10, j); prt("AFFECT........SLAY........BRAND.", 11, j); prt(" mf cvae xsqpaefc", 12, j); prt("siwdccsossidsahanvudotgddhuoclio", 13, j); prt("tnieohtctrnipttmiinmrrnrrraiierl", 14, j); prt("rtsxnarelcfgdkcpmldncltggpksdced", 15, j); prt_binary(flgs[0], 16, j); prt("+------------FLAGS2------------+", 17, j); prt("SUST....IMMUN.RESIST............", 18, j); prt(" reaefctrpsaefcpfldbc sn ", 19, j); prt("siwdcciaclioheatcliooeialoshtncd", 20, j); prt("tnieohdsierlrfraierliatrnnnrhehi", 21, j); prt("rtsxnaeydcedwlatdcedsrekdfddrxss", 22, j); prt_binary(flgs[1], 23, j); prt("+------------FLAGS3------------+", 10, j+32); prt("fe cnn t stdrmsiiii d ab ", 11, j+32); prt("aa aoomywhs lleeieihgggg rtgl ", 12, j+32); prt("uu utmacaih eielgggonnnnaaere ", 13, j+32); prt("rr reanurdo vtieeehtrrrrcilas ", 14, j+32); prt("aa algarnew ienpsntsaefctnevs ", 15, j+32); prt_binary(flgs[2], 16, j+32); prt("+------------FLAGS4------------+", 17, j+32); prt("KILL....ESP......... ", 18, j+32); prt("aeud tghaud tgdhegnu ", 19, j+32); prt("nvneoriunneoriruvoon ", 20, j+32); prt("iidmroamidmroagmionq ", 21, j+32); prt("mlenclnmmenclnnnldlu ", 22, j+32); prt_binary(flgs[3], 23, j+32); }
/** * Display a list of objects. Each object may be prefixed with a label. * Used by show_inven(), show_equip(), and show_floor(). Mode flags are * documented in object.h */ static void show_obj_list(olist_detail_t mode) { int i, row = 0, col = 0; char tmp_val[80]; bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; bool terse = FALSE; /* Initialize */ max_len = 0; ex_width = 0; ex_offset = 0; if (in_term) max_len = 40; if (in_term && Term->wid < 40) mode &= ~(OLIST_WEIGHT); if (Term->wid < 50) terse = TRUE; /* Set the names and get the max length */ set_obj_names(terse); /* Take the quiver message into consideration */ if (mode & OLIST_QUIVER && player->upkeep->quiver[0] != NULL) max_len = MAX(max_len, 24); /* Width of extra fields */ if (mode & OLIST_WEIGHT) ex_width += 9; if (mode & OLIST_PRICE) ex_width += 9; if (mode & OLIST_FAIL) ex_width += 10; /* Determine beginning row and column */ if (in_term) { /* Term window */ row = 0; col = 0; } else { /* Main window */ row = 1; col = Term->wid - 1 - max_len - ex_width; if (col < 3) col = 0; } /* Column offset of the first extra field */ ex_offset = MIN(max_len, (size_t)(Term->wid - 1 - ex_width - col)); /* Output the list */ for (i = 0; i < num_obj; i++) show_obj(i, row, col, FALSE, mode); /* For the inventory: print the quiver count */ if (mode & OLIST_QUIVER) { int count, j; int quiver_slots = (player->upkeep->quiver_cnt + z_info->stack_size - 1) / z_info->stack_size; /* Quiver may take multiple lines */ for (j = 0; j < quiver_slots; j++, i++) { const char *fmt = "in Quiver: %d missile%s"; char letter = I2A(in_term ? i - 1 : i); /* Number of missiles in this "slot" */ if (j == quiver_slots - 1) count = player->upkeep->quiver_cnt - (z_info->stack_size * (quiver_slots - 1)); else count = z_info->stack_size; /* Clear the line */ prt("", row + i, MAX(col - 2, 0)); /* Print the (disabled) label */ strnfmt(tmp_val, sizeof(tmp_val), "%c) ", letter); c_put_str(COLOUR_SLATE, tmp_val, row + i, col); /* Print the count */ strnfmt(tmp_val, sizeof(tmp_val), fmt, count, count == 1 ? "" : "s"); c_put_str(COLOUR_L_UMBER, tmp_val, row + i, col + 3); } } /* Clear term windows */ if (in_term) { for (; i < Term->hgt; i++) prt("", row + i, MAX(col - 2, 0)); } else if (i > 0 && row + i < 24) { /* Print a drop shadow for the main window if necessary */ prt("", row + i, MAX(col - 2, 0)); } }
/* * Special key actions for object inscription. */ static void o_xtra_act(struct keypress ch, int oid) { object_kind *k = objkind_byid(oid); /* Toggle squelch */ if (squelch_tval(k->tval) && (ch.code == 's' || ch.code == 'S')) { if (k->aware) { if (kind_is_squelched_aware(k)) kind_squelch_clear(k); else kind_squelch_when_aware(k); } else { if (kind_is_squelched_unaware(k)) kind_squelch_clear(k); else kind_squelch_when_unaware(k); } return; } /* Forget it if we've never seen the thing */ if (k->flavor && !k->aware) return; /* Uninscribe */ if (ch.code == '}') { if (k->note) remove_autoinscription(oid); } else if (ch.code == '{') { /* Inscribe */ char note_text[80] = ""; /* Avoid the prompt getting in the way */ screen_save(); /* Prompt */ prt("Inscribe with: ", 0, 0); /* Default note */ if (k->note) strnfmt(note_text, sizeof(note_text), "%s", get_autoinscription(k)); /* Get an inscription */ if (askfor_aux(note_text, sizeof(note_text), NULL)) { /* Remove old inscription if existent */ if (k->note) remove_autoinscription(oid); /* Add the autoinscription */ add_autoinscription(oid, note_text); /* Notice stuff (later) */ p_ptr->notice |= (PN_AUTOINSCRIBE); p_ptr->redraw |= (PR_INVEN | PR_EQUIP); } /* Reload the screen */ screen_load(); } }