/** * Get a list of the objects at the player's location. * * Return the number of objects acquired. */ int scan_floor(struct object **items, int max_size, object_floor_t mode, item_tester tester) { struct object *obj; int py = player->py; int px = player->px; int num = 0; /* Sanity */ if (!square_in_bounds(cave, py, px)) return 0; /* Scan all objects in the grid */ for (obj = square_object(cave, py, px); obj; obj = obj->next) { /* Enforce limit */ if (num >= max_size) break; /* Item tester */ if ((mode & OFLOOR_TEST) && !object_test(tester, obj)) continue; /* Sensed or known */ if ((mode & OFLOOR_SENSE) && (!obj->known)) continue; /* Visible */ if ((mode & OFLOOR_VISIBLE) && !is_unknown(obj) && ignore_item_ok(obj)) continue; /* Accept this item */ items[num++] = obj; /* Only one */ if (mode & OFLOOR_TOP) break; } return num; }
/** * Get the indexes of objects at a given floor location. -TNB- * * Return the number of object indexes acquired. * * Valid flags are any combination of the bits: * 0x01 -- Verify item tester * 0x02 -- Marked items only * 0x04 -- Only the top item * 0x08 -- Visible items only */ int scan_floor(struct object **items, int max_size, int y, int x, int mode, item_tester tester) { struct object *obj; int num = 0; /* Sanity */ if (!square_in_bounds(cave, y, x)) return 0; /* Scan all objects in the grid */ for (obj = square_object(cave, y, x); obj; obj = obj->next) { /* Enforce limit */ if (num >= max_size) break; /* Item tester */ if ((mode & 0x01) && !object_test(tester, obj)) continue; /* Marked */ if ((mode & 0x02) && (!obj->marked)) continue; /* Visible */ if ((mode & 0x08) && !is_unknown(obj) && ignore_item_ok(obj)) continue; /* Accept this item */ items[num++] = obj; /* Only one */ if (mode & 0x04) break; } return num; }
/** * Get a list of "valid" objects. * * Fills item_list[] with items that are "okay" as defined by the * provided tester function, etc. mode determines what combination of * inventory, equipment, quiver and player's floor location should be used * when drawing up the list. * * Returns the number of items placed into the list. * * Maximum space that can be used is * z_info->pack_size + z_info->quiver_size + player->body.count + * z_info->floor_size, * though practically speaking much smaller numbers are likely. */ int scan_items(struct object **item_list, size_t item_max, int mode, item_tester tester) { 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); int floor_max = z_info->floor_size; struct object **floor_list = mem_zalloc(floor_max * sizeof(struct object *)); int floor_num; int i; size_t item_num = 0; if (use_inven) for (i = 0; i < z_info->pack_size && item_num < item_max; i++) { if (object_test(tester, player->upkeep->inven[i])) item_list[item_num++] = player->upkeep->inven[i]; } if (use_equip) for (i = 0; i < player->body.count && item_num < item_max; i++) { if (object_test(tester, slot_object(player, i))) item_list[item_num++] = slot_object(player, i); } if (use_quiver) for (i = 0; i < z_info->quiver_size && item_num < item_max; i++) { if (object_test(tester, player->upkeep->quiver[i])) item_list[item_num++] = player->upkeep->quiver[i]; } /* Scan all non-gold objects in the grid */ if (use_floor) { floor_num = scan_floor(floor_list, floor_max, OFLOOR_TEST | OFLOOR_SENSE | OFLOOR_VISIBLE, tester); for (i = 0; i < floor_num && item_num < item_max; i++) item_list[item_num++] = floor_list[i]; } mem_free(floor_list); return item_num; }
DtCount dtTest() { move(); DtCount count = 0; if (caching) { for (ProxList::iterator i = proxList.begin(); i != proxList.end(); ++i) if (object_test((Encounter &)*i)) ++count; } else { for (ObjectList::const_iterator j = objectList.begin(); j != objectList.end(); ++j) for (ObjectList::const_iterator i = objectList.begin(); i != j; ++i) { Encounter e((*i).second, (*j).second); if (object_test(e)) ++count; } } return count; }
/** * Build the object list. */ static void build_obj_list(int last, struct object **list, item_tester tester, olist_detail_t mode) { int i; bool gold_ok = (mode & OLIST_GOLD) ? true : false; bool in_term = (mode & OLIST_WINDOW) ? true : false; bool dead = (mode & OLIST_DEATH) ? true : false; bool show_empty = (mode & OLIST_SEMPTY) ? true : false; bool equip = list ? false : true; bool quiver = list == player->upkeep->quiver ? true : false; /* Build the object list */ for (i = 0; i <= last; i++) { char buf[80]; struct object *obj = equip ? slot_object(player, i) : list[i]; /* Acceptable items get a label */ if (object_test(tester, obj) || (obj && tval_is_money(obj) && gold_ok)) strnfmt(items[num_obj].label, sizeof(items[num_obj].label), "%c) ", quiver ? I2D(i) : I2A(i)); /* Unacceptable items are still sometimes shown */ else if ((!obj && show_empty) || in_term) my_strcpy(items[num_obj].label, " ", sizeof(items[num_obj].label)); /* Unacceptable items are skipped in the main window */ else continue; /* Show full slot labels for equipment (or quiver in subwindow) */ if (equip) { strnfmt(buf, sizeof(buf), "%-14s: ", equip_mention(player, i)); my_strcpy(items[num_obj].equip_label, buf, sizeof(items[num_obj].equip_label)); } else if ((in_term || dead) && quiver) { strnfmt(buf, sizeof(buf), "Slot %-9d: ", i); my_strcpy(items[num_obj].equip_label, buf, sizeof(items[num_obj].equip_label)); } else { strnfmt(items[num_obj].equip_label, sizeof(items[num_obj].equip_label), ""); } /* Save the object */ items[num_obj].object = obj; items[num_obj].key = (items[num_obj].label)[0]; num_obj++; } }
int main(int argc, char ** argv) { lt_type_init(); array_test(); hash_test(); module_test(); base64_test(); set_test(); object_test(); return 0; }
/** * 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) { 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; if (mode & SHOW_RECHARGE) olist_mode |= OLIST_RECHARGE; /* 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; else if (item_mode & USE_INVEN) item_mode -= USE_INVEN; /* 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; else if (item_mode & USE_EQUIP) item_mode -= USE_EQUIP; /* 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; else if (item_mode & USE_QUIVER) item_mode -= USE_QUIVER; /* Scan all non-gold objects in the grid */ floor_num = scan_floor(floor_list, floor_max, OFLOOR_TEST | OFLOOR_SENSE | OFLOOR_VISIBLE, 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; else if (item_mode & USE_FLOOR) item_mode -= USE_FLOOR; /* 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(pmt ? strlen(pmt) : 0, 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; }