/** * Determine if an object can be picked up automatically. */ static bool auto_pickup_okay(const struct object *obj) { if (!inven_carry_okay(obj)) return FALSE; if (OPT(pickup_always) || check_for_inscrip(obj, "=g")) return TRUE; if (OPT(pickup_inven) && inven_stack_okay(obj)) return TRUE; return FALSE; }
/* * Determine if the object can be picked up automatically. */ static bool auto_pickup_okay(const object_type *o_ptr) { if (!inven_carry_okay(o_ptr)) return FALSE; if (OPT(pickup_always) || check_for_inscrip(o_ptr, "=g")) return TRUE; if (OPT(pickup_inven) && inven_stack_okay(o_ptr)) return TRUE; return FALSE; }
void _blood_pool_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Blood Pool"); break; case SPELL_DESC: var_set_string(res, "Creates a macabre Potion of Healing made of your own blood."); break; case SPELL_SPOIL_DESC: var_set_string(res, "Create a potion of blood. Player is limited to 30 such potions, and may neither " "drop, throw nor sell them. Quaffing a potion of blood heals 100hp and cures " "blindness, confusion, poison and stuns."); break; case SPELL_CAST: { object_type forge; int ct = _count_blood_potions(); if (ct >= 30) { msg_print("You have too many blood potions at the moment. Why not drink some?"); var_set_bool(res, FALSE); return; } msg_print("You feel light headed."); object_prep(&forge, lookup_kind(TV_POTION, SV_POTION_BLOOD)); /* We can't just drop potions on the ground, or the user can spam the spell! */ if (!inven_carry_okay(&forge)) { msg_print("Your pack is full! The potion goes sour ..."); object_prep(&forge, lookup_kind(TV_POTION, SV_POTION_SALT_WATER)); drop_near(&forge, -1, py, px); } else { inven_carry(&forge); msg_print("You store your blood for future use."); } var_set_bool(res, TRUE); break; } default: default_spell(cmd, res); break; } }
/** * Move an object from a floor pile to the player's gear */ static void player_pickup_aux(struct object *obj, bool domsg) { /* Confirm the object can be picked up*/ if (!inven_carry_okay(obj)) quit_fmt("Failed pickup of %s", obj->kind->name); /* Set ignore status */ player->upkeep->notice |= PN_IGNORE; /* Automatically sense artifacts */ object_sense_artifact(obj); /* Log artifacts if found */ if (obj->artifact) history_add_artifact(obj->artifact, object_is_known(obj), TRUE); /* Carry the object */ square_excise_object(cave, player->py, player->px, obj); inven_carry(player, obj, domsg); }
int context_menu_player(int mx, int my) { menu_type *m; rect_region r; int selected; char *labels; cave_type *c_ptr = area(p_ptr->px,p_ptr->py); pcave_type *pc_ptr = parea(p_ptr->px,p_ptr->py); feature_type *feat; m = menu_dynamic_new(); if (!m) { return 0; } labels = (char*)string_make(lower_case); m->selections = labels; feat = &(f_info[c_ptr->feat]); menu_dynamic_add_label(m, "Use Item", 'u', 1, labels); /* if player can cast, add casting option */ if (player_is_caster()) { if (player_can_cast()) { menu_dynamic_add_label(m, "Cast", 'm', 2, labels); } else { menu_dynamic_add_label(m, "$Cast", 'm', 2, labels); } } /* if player can use racial powers or mutations, add option */ if (player_has_power()) { if (player_can_use_power()) { menu_dynamic_add_label(m, "Use Power", 'U', 16, labels); } else { menu_dynamic_add_label(m, "$Use Power", 'U', 16, labels); } } /* if player is on stairs add option to use them */ if (feat->flags & FF_EXIT_UP) { menu_dynamic_add_label(m, "Go Up", '<', 11, labels); } if (feat->flags & FF_EXIT_DOWN) { menu_dynamic_add_label(m, "Go Down", '>', 12, labels); } menu_dynamic_add_label(m, "Search", 's', 3, labels); menu_dynamic_add_label(m, "Look", 'l', 6, labels); menu_dynamic_add_label(m, "Rest", 'R', 4, labels); menu_dynamic_add_label(m, "Inventory", 'i', 5, labels); /* if object under player add pickup option */ if (c_ptr->o_idx) { object_type *o_ptr = &(o_list[c_ptr->o_idx]); //if (!squelch_item_ok(o_ptr)) { menu_dynamic_add_label(m, "Floor", 'i', 13, labels); if (inven_carry_okay(o_ptr)) { menu_dynamic_add_label(m, "Pickup", 'g', 14, labels); } else { menu_dynamic_add_label(m, "$Pickup", 'g', 14, labels); } //} } menu_dynamic_add_label(m, "Character", 'C', 7, labels); /* XXX Don't show the keymap line until the keymap list is implemented, to * avoid confusion as to what should be there */ /*menu_dynamic_add(m, "Keymaps", 10);*/ if (!OPT(center_player)) { menu_dynamic_add_label(m, "^Center Map", 'L', 15, labels); } menu_dynamic_add_label(m, "Other", ' ', 9, labels); /* work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ if (mx > Term->wid - r.width - 1) { r.col = Term->wid - r.width - 1; } else { r.col = mx + 1; } r.page_rows = m->count; if (my > Term->hgt - r.page_rows - 1) { if (my - r.page_rows - 1 <= 0) { /* menu has too many items, so put in upper right corner */ r.row = 1; r.col = Term->wid - r.width - 1; } else { r.row = Term->hgt - r.page_rows - 1; } } else { r.row = my + 1; } /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); button_backup_all(TRUE); menu_layout(m, &r); rect_region_erase_bordered(&r); prtf(0, 0, "($UEnter to select$Y\n$V, $UESC$Y%c$V) Command:", ESCAPE); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); button_restore(); screen_load(); switch(selected) { case 1: { /* use an item */ p_ptr->cmd.cmd = 'u'; repeat_check(); do_cmd_use(); } break; case 2: { /* Cast a spell */ p_ptr->cmd.cmd = 'm'; repeat_check(); do_cmd_cast_wrapper(); } break; case 3: { /* search */ p_ptr->cmd.cmd = 's'; repeat_check(); do_cmd_search(); } break; case 4: { /* rest */ p_ptr->cmd.cmd = 'R'; repeat_check(); do_cmd_rest(); } break; case 5: { /* show inventory screen */ Term_keypress('i');//,0); } break; case 6: { /* look mode */ if (target_set(TARGET_LOOK)) { //if (target_set_interactive(TARGET_LOOK, p_ptr->px, p_ptr->py)) { msgf("Target Selected."); } } break; case 7: { /* show character screen */ do_cmd_character(); } break; case 9: { /* show another layer of menu options screen */ int res; while ((res = context_menu_player_2(mx,my)) == 3); if (res == 2) return 3; } break; case 10: { /* show the commands */ int res; while ((res = context_menu_command(mx,my)) == 3); if (res == 2) return 3; } break; case 11: { /* go up stairs */ p_ptr->cmd.cmd = '<'; repeat_check(); do_cmd_go_up(); } break; case 12: { /* go down stairs */ p_ptr->cmd.cmd = '>'; repeat_check(); do_cmd_go_down(); } break; case 13: { if (c_ptr->o_idx) { object_type *o_ptr = &(o_list[c_ptr->o_idx]); /* there is an item on the floor, show the inventory screen starting * from the floor */ if (o_ptr->next_o_idx) { do_cmd_inven_floor(); } else { /* if we only have one item, show the context menu directly */ if (o_ptr->k_idx) { /* Track the object kind */ object_kind_track(o_ptr->k_idx); while (context_menu_object(o_ptr) == 2); } } } } break; case 14: { /* pick the item up */ //cmd_insert(CMD_PICKUP); //cmd_set_arg_item(cmd_get_top(), 0, -1); carry(TRUE); } break; case 15: { /* center the map on the player */ /*panel_center(p_ptr->px, p_ptr->py);*/ do_cmd_center_map(); } break; case 16: { /* use character powers */ p_ptr->cmd.cmd = 'U'; repeat_check(); do_cmd_racial_power(); } break; } return 1; }
/* pick the context menu options appropiate for the item */ int context_menu_object(const object_type *o_ptr) { menu_type *m; rect_region r; int selected; int location = 0; char *labels; char header[120]; s16b *list; m = menu_dynamic_new(); if (!m || !o_ptr) { return 0; } object_desc(header, o_ptr, TRUE, 2, sizeof(header)); list = look_up_list((object_type*)o_ptr); if (list) { if (list == &(p_ptr->inventory)) { location = USE_INVEN; } else if (list == &(area(p_ptr->px, p_ptr->py)->o_idx)) { location = USE_FLOOR; } else { /* check if in a container */ location = USE_INVEN; } } else if (GET_ARRAY_INDEX(p_ptr->equipment, o_ptr) >= EQUIP_WIELD) { location = USE_EQUIP; } labels = (char*)string_make(lower_case); m->selections = labels; menu_dynamic_add_label(m, "Inspect", 'I', 1, labels); if (item_tester_hook_is_book(o_ptr)) { if (player_can_cast_from(o_ptr)) { if (player_can_cast()) { menu_dynamic_add_label(m, "Cast", 'm', 8, labels); } else { menu_dynamic_add_label(m, "$Cast", 'm', 8, labels); } if (player_can_study()) { menu_dynamic_add_label(m, "Study", 'G', 10, labels); } else { menu_dynamic_add_label(m, "$Study", 'G', 10, labels); } } if (player_is_caster() && player_can_read()) { menu_dynamic_add_label(m, "Browse", 'b', 9, labels); } } else if (item_tester_hook_useable(o_ptr)) { if (obj_is_wand(o_ptr)) { if (obj_has_charges(o_ptr)) { menu_dynamic_add_label(m, "Aim", 'a', 8, labels); } else { menu_dynamic_add_label(m, "$Aim", 'a', 8, labels); } } else if (obj_is_rod(o_ptr)) { if (obj_can_zap(o_ptr)) { menu_dynamic_add_label(m, "Zap", 'z', 8, labels); } else { menu_dynamic_add_label(m, "$Zap", 'z', 8, labels); } } else if (obj_is_staff(o_ptr)) { if (obj_has_charges(o_ptr)) { menu_dynamic_add_label(m, "Use", 'u', 8, labels); } else { menu_dynamic_add_label(m, "$Use", 'u', 8, labels); } } else if (obj_is_scroll(o_ptr)) { if (player_can_read()) { menu_dynamic_add_label(m, "Read", 'r', 8, labels); } else { menu_dynamic_add_label(m, "$Read", 'r', 8, labels); } } else if (obj_is_potion(o_ptr)) { menu_dynamic_add_label(m, "Quaff", 'q', 8, labels); } else if (obj_is_food(o_ptr)) { menu_dynamic_add_label(m, "Eat", 'E', 8, labels); } else if (item_tester_hook_activate(o_ptr)) { if (obj_is_activatable(o_ptr)) { menu_dynamic_add_label(m, "Activate", 'A', 8, labels); } else { menu_dynamic_add_label(m, "$Activate", 'A', 8, labels); } } else { menu_dynamic_add_label(m, "Use", 'U', 8, labels); } } else if (item_tester_hook_ammo(o_ptr)) { if (obj_can_fire(o_ptr)) { menu_dynamic_add_label(m, "Fire", 'f', 15, labels); } else { menu_dynamic_add_label(m, "$Fire", 'f', 15, labels); } } if (obj_can_refill(o_ptr)) { menu_dynamic_add_label(m, "Refill", 'F', 11, labels); } if (item_tester_hook_wear(o_ptr)) { if (location == USE_EQUIP) { menu_dynamic_add_label(m, "Take off", 't', 3, labels); } else if (location == USE_INVEN) { if (item_tester_hook_armour(o_ptr)) { menu_dynamic_add_label(m, "Wear", 'w', 2, labels); } else { menu_dynamic_add_label(m, "Wield", 'w', 2, labels); } /*menu_dynamic_add_label(m, "Equip", 'w', 2, labels);*/ } } if ((location == USE_INVEN) || (location == USE_EQUIP)) { menu_dynamic_add_label(m, "Drop", 'd', 6, labels); if (o_ptr->number > 1) { menu_dynamic_add_label(m, "Drop All", 'd', 13, labels); } } else if (location == USE_FLOOR) { if (inven_carry_okay(o_ptr)) { menu_dynamic_add_label(m, "Pickup", 'g', 7, labels); } else { menu_dynamic_add_label(m, "$Pickup", 'g', 7, labels); } } menu_dynamic_add_label(m, "Throw", 'v', 12, labels); /*if (obj_has_inscrip(o_ptr)) {*/ if (o_ptr->inscription) { menu_dynamic_add_label(m, "Uninscribe", '}', 5, labels); } else { menu_dynamic_add_label(m, "Inscribe", '{', 4, labels); } menu_dynamic_add_label(m, "Destroy", 'k', 14, labels); #if 0 if (object_is_squelched(o_ptr)) { menu_dynamic_add_label(m, "Unignore", 'k', 14, labels); } else { menu_dynamic_add_label(m, "Ignore", 'k', 14, labels); } #endif /* work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ r.col = Term->wid - r.width - 1; r.row = 1; r.page_rows = m->count; /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); button_backup_all(TRUE); /* Recall object */ roff_set_width(r.col); roff_obj_aux(o_ptr); roff_set_width(0); menu_layout(m, &r); rect_region_erase_bordered(&r); prtf(0, 0, "($UEnter to select$Y\n$V, $UESC$Y%c$V) Command for %s:", ESCAPE, header); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); button_restore(); screen_load(); if (selected == 1) { /* inspect it */ identify_fully_aux(o_ptr); return 2; } else if (selected == 2) { /* wield the item */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = 'w'; do_cmd_wield(); /*cmd_insert(CMD_WIELD); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } else if (selected == 3) { /* take the item off */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = 't'; do_cmd_takeoff(); /*cmd_insert(CMD_TAKEOFF); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } else if (selected == 4) { /* inscribe the item */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = '{'; do_cmd_inscribe(); /*cmd_insert(CMD_INSCRIBE); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } else if (selected == 5) { /* uninscribe the item */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = '}'; do_cmd_uninscribe(); /*cmd_insert(CMD_UNINSCRIBE); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } else if (selected == 6) { /* drop the item */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = 'd'; do_cmd_drop(); /*cmd_insert(CMD_DROP); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } else if (selected == 7) { /* pick the item up */ p_ptr->cmd.cmd = 'g'; if (inven_carry_okay(o_ptr)) { py_pickup_aux((object_type*)o_ptr); } else { carry(TRUE); } /*cmd_insert(CMD_PICKUP); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } else if (selected == 8) { /* use the item */ bool full = item_tester_full; item_tester_full = FALSE; if (player_can_cast_from(o_ptr)) { set_get_item_object(o_ptr); p_ptr->cmd.cmd = 'm'; do_cmd_cast(); } else { set_get_item_object(o_ptr); p_ptr->cmd.cmd = 'u'; repeat_check(); do_cmd_use(); /*cmd_insert(CMD_USE_ANY); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } item_tester_full = full; } else if (selected == 9) { /* browse a spellbook */ p_ptr->cmd.cmd = 'b'; do_cmd_browse_aux(o_ptr); /* copied from textui_spell_browse */ /*textui_book_browse(o_ptr);*/ return 2; } else if (selected == 10) { /* study a spell book */ p_ptr->cmd.cmd = 'G'; do_cmd_study(FALSE, (object_type*)o_ptr); } else if (selected == 11) { /* use the item to refill a light source */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = 'F'; do_cmd_refill(); /*cmd_insert(CMD_REFILL); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } else if (selected == 12) { /* throw the item */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = 'v'; repeat_check(); do_cmd_throw(); /*cmd_insert(CMD_THROW); cmd_set_arg_item(cmd_get_top(), 0, slot);*/ } else if (selected == 13) { /* drop all of the item stack */ if (get_check(format("Drop %s? ", header))) { set_get_item_object(o_ptr); p_ptr->cmd.arg = o_ptr->number; p_ptr->cmd.cmd = 'd'; do_cmd_drop(); /*cmd_insert(CMD_DROP); cmd_set_arg_item(cmd_get_top(), 0, slot); cmd_set_arg_number(cmd_get_top(), 1, o_ptr->number);*/ } } else if (selected == 14) { /* squelch or unsquelch the item */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = 'k'; do_cmd_destroy(); /*textui_cmd_destroy_menu(slot);*/ } else if (selected == 15) { /* fire some ammo */ set_get_item_object(o_ptr); p_ptr->cmd.cmd = 'f'; repeat_check(); do_cmd_fire(); } else if (selected == -1) { /* this menu was canceled, tell whatever called us to display its menu again */ return 3; } return 1; }
/* * Pick up objects and treasure on the floor. -LM- * * Called with pickup: * 0 to act according to the player's settings * 1 to quickly pickup single objects or present a menu for more * 2 to force 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 backpack space is full if * auto-pickup option is on, Otherwise, store objects on * floor in an array, and tally both how many there are and can be picked up. * * If not picking up anything, indicate objects on the floor. Show more * details if the "OPT(pickup_detail)" option is set. Do the same thing if we * don't have room for anything. * * [This paragraph is not true, intentional?] * If we are picking up objects automatically, and have room for at least * one, allow the "OPT(pickup_detail)" option to display information about objects * and prompt the player. Otherwise, automatically pick up a single object * or use a menu for more than one. * * Pick up multiple objects 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. * * We keep track of number of objects picked up to calculate time spent. * This tally is incremented even for automatic pickup, so we are careful * (in "dungeon.c" and elsewhere) to handle pickup as either a separate * automated move or a no-cost part of the stay still or 'g'et command. * * Note the lack of chance for the character to be disturbed by unmarked * objects. They are truly "unknown". */ byte py_pickup(int pickup) { int py = p_ptr->py; int px = p_ptr->px; s16b this_o_idx = 0; size_t floor_num = 0; int floor_list[MAX_FLOOR_STACK + 1]; size_t i; int can_pickup = 0; bool call_function_again = FALSE; bool domsg = TRUE; /* Objects picked up. Used to determine time cost of command. */ byte objs_picked_up = 0; /* Nothing else to pick up -- return */ if (!cave->o_idx[py][px]) return objs_picked_up; /* Tally objects that can be picked up.*/ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x03); for (i = 0; i < floor_num; i++) { can_pickup += inven_carry_okay(object_byid(floor_list[i])); } if (!can_pickup) { /* Can't pick up, but probably want to know what's there. */ event_signal(EVENT_SEEFLOOR); return objs_picked_up; } /* Use a menu interface for multiple objects, or pickup single objects */ if (pickup == 1) { if (floor_num > 1) pickup = 2; else this_o_idx = floor_list[0]; } /* Display a list if requested. */ if (pickup == 2) { const char *q, *s; int item; /* Restrict the choices */ item_tester_hook = inven_carry_okay; /* Get an object or exit. */ q = "Get which item?"; s = "You see nothing there."; 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) { /* Pick up the object */ py_pickup_aux(this_o_idx, domsg); /* 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); /* Indicate how many objects have been picked up. */ return (objs_picked_up); }
/** * Bring up objects to act on */ void do_cmd_show_obj(void) { cptr q, s; int j, item; object_type *o_ptr; char o_name[120]; byte out_color; bool accepted = FALSE; /* No restrictions */ item_tester_tval = 0; item_tester_hook = NULL; /* See what's available */ q = "Pick an item to use:"; s = "You have no items to hand."; if (!get_item(&item, q, s, CMD_NULL, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return; /* Got it */ if (item >= 0) { o_ptr = &p_ptr->inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Is it really an item? */ if (!o_ptr->k_idx) return; /* No commands yet */ poss = 0; /* Describe the object */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_FULL); /* Hack -- enforce max length */ o_name[Term->wid - 3] = '\0'; /* Acquire inventory color. Apply spellbook hack. */ out_color = proc_list_color_hack(o_ptr); /* Wear/wield */ if ((wield_slot(o_ptr) >= INVEN_WIELD) && (!SCHANGE) && (item < INVEN_WIELD)) { comm[poss] = 'w'; comm_code[poss] = CMD_WIELD; comm_descr[poss++] = "Wield"; } /* Take off equipment */ if ((item >= INVEN_WIELD) && (item < INVEN_TOTAL) && (!SCHANGE)) { comm[poss] = 't'; comm_code[poss] = CMD_TAKEOFF; comm_descr[poss++] = "Take off"; } /* Drop an item */ if ((item >= 0) && ((item < INVEN_WIELD) || (!SCHANGE))) { comm[poss] = 'd'; comm_code[poss] = CMD_DROP; comm_descr[poss++] = "Drop"; } /* Destroy an item */ if (item < INVEN_WIELD) { comm[poss] = 'k'; comm_code[poss] = CMD_DESTROY; comm_descr[poss++] = "Destroy"; } /* Identify an object */ comm[poss] = 'I'; comm_code[poss] = CMD_NULL; comm_descr[poss++] = "Inspect"; /* Pick up an object */ if ((item < 0) && inven_carry_okay(o_ptr)) { comm[poss] = 'g'; comm_code[poss] = CMD_PICKUP; comm_descr[poss++] = "Pick up"; } /* Book learnin' */ if (mp_ptr->spell_book == o_ptr->tval) { if (p_ptr->new_spells) { comm[poss] = 'G'; comm_code[poss] = CMD_STUDY_SPELL; comm_descr[poss++] = "Gain a spell"; } comm[poss] = 'b'; comm_code[poss] = CMD_BROWSE_SPELL; comm_descr[poss++] = "Browse"; comm[poss] = 'm'; comm_code[poss] = CMD_CAST; comm_descr[poss++] = "Cast a spell"; } /* Inscribe an object */ comm[poss] = '{'; comm_code[poss] = CMD_INSCRIBE; comm_descr[poss++] = "Inscribe"; /* Uninscribe an object */ if (o_ptr->note) { comm[poss] = '}'; comm_code[poss] = CMD_UNINSCRIBE; comm_descr[poss++] = "Uninscribe"; } /* Activate equipment */ if ((o_ptr->effect) && (item >= INVEN_WIELD)) { comm[poss] = 'A'; comm_code[poss] = CMD_ACTIVATE; comm_descr[poss++] = "Activate"; } /* Eat some food */ if (o_ptr->tval == TV_FOOD) { comm[poss] = 'E'; comm_code[poss] = CMD_EAT; comm_descr[poss++] = "Eat"; } if ((item < INVEN_WIELD) && ((o_ptr->tval == TV_LIGHT) || (o_ptr->tval == TV_FLASK))) { object_type *o1_ptr = &p_ptr->inventory[INVEN_LIGHT]; if (((o1_ptr->sval == SV_LIGHT_LANTERN) && ((o_ptr->tval == TV_FLASK) || ((o_ptr->tval == TV_LIGHT) && (o_ptr->sval == SV_LIGHT_LANTERN)))) || ((o1_ptr->sval == SV_LIGHT_TORCH) && (o_ptr->tval == TV_LIGHT) && (o_ptr->sval == SV_LIGHT_TORCH))) { comm[poss] = 'F'; comm_code[poss] = CMD_REFILL; comm_descr[poss++] = "Refuel"; } } /* Fire an item */ if (p_ptr->state.ammo_tval == o_ptr->tval) { comm[poss] = 'f'; comm_code[poss] = CMD_FIRE; comm_descr[poss++] = "Fire"; } /* Throw an item */ if ((item < INVEN_WIELD) || (!SCHANGE)) { comm[poss] = 'v'; comm_code[poss] = CMD_THROW; comm_descr[poss++] = "Throw"; } /* Aim a wand */ if (o_ptr->tval == TV_WAND) { comm[poss] = 'a'; comm_code[poss] = CMD_USE_WAND; comm_descr[poss++] = "Aim"; } /* Zap a rod */ if (o_ptr->tval == TV_ROD) { comm[poss] = 'z'; comm_code[poss] = CMD_USE_ROD; comm_descr[poss++] = "Zap"; } /* Quaff a potion */ if (o_ptr->tval == TV_POTION) { comm[poss] = 'q'; comm_code[poss] = CMD_QUAFF; comm_descr[poss++] = "Quaff"; } /* Read a scroll */ if (o_ptr->tval == TV_SCROLL) { comm[poss] = 'r'; comm_code[poss] = CMD_READ_SCROLL; comm_descr[poss++] = "Read"; } /* Use a staff */ if (o_ptr->tval == TV_STAFF) { comm[poss] = 'u'; comm_code[poss] = CMD_USE_STAFF; comm_descr[poss++] = "Use"; } /* Set up the screen */ screen_save(); /* Prompt */ put_str("Choose a command, or ESC:", 0, 0); /* Clear the line */ prt("", 1, 0); /* Display the item */ c_put_str(out_color, o_name, 1, 0); /* Hack - delete exact graphics rows */ if (tile_height > 1) { j = poss + 2; while ((j % tile_height) && (j <= SCREEN_ROWS)) prt("", ++j, 0); } /* Get a choice */ accepted = show_cmd_menu(TRUE); /* Load de screen */ screen_load(); /* Now set the item if valid */ if (accepted) cmd_set_arg_item(cmd_get_top(), 0, item); }
/* A special fetch(), that places item in player's inventory */ static bool _whip_fetch(int dir, int rng) { int ty, tx; cave_type *c_ptr; object_type *o_ptr; char o_name[MAX_NLEN]; /* Use a target */ if (dir == 5 && target_okay()) { tx = target_col; ty = target_row; if (distance(py, px, ty, tx) > rng) { msg_print("You can't fetch something that far away!"); return FALSE; } c_ptr = &cave[ty][tx]; /* We need an item to fetch */ if (!c_ptr->o_idx) { msg_print("There is no object at this place."); return TRUE; /* didn't work, but charge the player energy anyway */ } /* Fetching from a vault is OK */ /* Line of sight is required */ if (!player_has_los_bold(ty, tx)) { msg_print("You have no direct line of sight to that location."); return FALSE; } else if (!projectable(py, px, ty, tx)) { msg_print("You have no direct line of sight to that location."); return FALSE; } } else { /* Use a direction */ ty = py; /* Where to drop the item */ tx = px; do { ty += ddy[dir]; tx += ddx[dir]; c_ptr = &cave[ty][tx]; if ((distance(py, px, ty, tx) > MAX_RANGE) || !in_bounds(ty, tx) || !cave_have_flag_bold(ty, tx, FF_PROJECT)) { return TRUE; /* didn't work, but charge the player energy anyway */ } } while (!c_ptr->o_idx); } o_ptr = &o_list[c_ptr->o_idx]; if (o_ptr->weight > p_ptr->lev * 15) { msg_print("The object is too heavy."); return TRUE; /* didn't work, but charge the player energy anyway */ } object_desc(o_name, o_ptr, OD_NAME_ONLY); /* Get the object */ if (!inven_carry_okay(o_ptr)) { cmsg_format(TERM_VIOLET, "You fail to fetch %^s since your pack is full.", o_name); /* Leave the object where it is */ } else { msg_format("You skillfully crack your whip and fetch %^s.", o_name); py_pickup_aux(c_ptr->o_idx); } return TRUE; }
/* pick the context menu options appropiate for the item */ int context_menu_object(const object_type *o_ptr, const int slot) { menu_type *m; region r; int selected; char *labels; char header[120]; textblock *tb; region area = { 0, 0, 0, 0 }; bool allowed = TRUE; int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; unsigned char cmdkey; m = menu_dynamic_new(); if (!m || !o_ptr) { return 0; } object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_BASE); labels = string_make(lower_case); m->selections = labels; /* 'I' is used for inspect in both keymaps. */ menu_dynamic_add_label(m, "Inspect", 'I', MENU_VALUE_INSPECT, labels); if (obj_can_browse(o_ptr)) { if (obj_can_cast_from(o_ptr) && player_can_cast(p_ptr, FALSE)) { ADD_LABEL("Cast", CMD_CAST, MN_ROW_VALID); } if (obj_can_study(o_ptr) && player_can_study(p_ptr, FALSE)) { cmd_code study_cmd = player_has(PF_CHOOSE_SPELLS) ? CMD_STUDY_SPELL : CMD_STUDY_BOOK; /* Hack - Use the STUDY_BOOK command key so that we get the correct command key. */ cmdkey = cmd_lookup_key_unktrl(CMD_STUDY_BOOK, mode); menu_dynamic_add_label(m, "Study", cmdkey, study_cmd, labels); } if (player_can_read(p_ptr, FALSE)) { ADD_LABEL("Browse", CMD_BROWSE_SPELL, MN_ROW_VALID); } } else if (obj_is_useable(o_ptr)) { if (obj_is_wand(o_ptr)) { menu_row_validity_t valid = (obj_has_charges(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Aim", CMD_USE_WAND, valid); } else if (obj_is_rod(o_ptr)) { menu_row_validity_t valid = (obj_can_zap(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Zap", CMD_USE_ROD, valid); } else if (obj_is_staff(o_ptr)) { menu_row_validity_t valid = (obj_has_charges(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Use", CMD_USE_STAFF, valid); } else if (obj_is_scroll(o_ptr)) { menu_row_validity_t valid = (player_can_read(p_ptr, FALSE)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Read", CMD_READ_SCROLL, valid); } else if (obj_is_potion(o_ptr)) { ADD_LABEL("Quaff", CMD_QUAFF, MN_ROW_VALID); } else if (obj_is_food(o_ptr)) { ADD_LABEL("Eat", CMD_EAT, MN_ROW_VALID); } else if (obj_is_activatable(o_ptr)) { menu_row_validity_t valid = (slot >= INVEN_WIELD && obj_can_activate(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Activate", CMD_ACTIVATE, valid); } else if (obj_can_fire(o_ptr)) { ADD_LABEL("Fire", CMD_FIRE, MN_ROW_VALID); } else { ADD_LABEL("Use", CMD_USE_ANY, MN_ROW_VALID); } } if (obj_can_refill(o_ptr)) { ADD_LABEL("Refill", CMD_REFILL, MN_ROW_VALID); } if (slot >= INVEN_WIELD && obj_can_takeoff(o_ptr)) { ADD_LABEL("Take off", CMD_TAKEOFF, MN_ROW_VALID); } else if (slot < INVEN_WIELD && obj_can_wear(o_ptr)) { //if (obj_is_armor(o_ptr)) { // menu_dynamic_add(m, "Wear", 2); //} else { // menu_dynamic_add(m, "Wield", 2); //} ADD_LABEL("Equip", CMD_WIELD, MN_ROW_VALID); } if (slot >= 0) { if (!store_in_store || cave_shopnum(cave, p_ptr->py, p_ptr->px) == STORE_HOME) { ADD_LABEL("Drop", CMD_DROP, MN_ROW_VALID); if (o_ptr->number > 1) { /* 'D' is used for squelch in rogue keymap, so we'll just swap letters. */ cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'D' : 'k'; menu_dynamic_add_label(m, "Drop All", cmdkey, MENU_VALUE_DROP_ALL, labels); } } } else { menu_row_validity_t valid = (inven_carry_okay(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Pick up", CMD_PICKUP, valid); } ADD_LABEL("Throw", CMD_THROW, MN_ROW_VALID); ADD_LABEL("Inscribe", CMD_INSCRIBE, MN_ROW_VALID); if (obj_has_inscrip(o_ptr)) { ADD_LABEL("Uninscribe", CMD_UNINSCRIBE, MN_ROW_VALID); } ADD_LABEL( (object_is_squelched(o_ptr) ? "Unignore" : "Ignore"), CMD_DESTROY, MN_ROW_VALID); /* work out display region */ r.width = (int)menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ r.col = Term->wid - r.width - 1; r.row = 1; r.page_rows = m->count; area.width = -(r.width + 2); /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); /* Display info */ tb = object_info(o_ptr, OINFO_NONE); object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_FULL); textui_textblock_place(tb, area, format("%s", header)); textblock_free(tb); menu_layout(m, &r); region_erase_bordered(&r); prt(format("(Enter to select, ESC) Command for %s:", header), 0, 0); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); screen_load(); cmdkey = cmd_lookup_key(selected, mode); switch (selected) { case -1: /* User cancelled the menu. */ return 3; case MENU_VALUE_INSPECT: /* copied from textui_obj_examine */ /* Display info */ tb = object_info(o_ptr, OINFO_NONE); object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_FULL); textui_textblock_show(tb, area, format("%s", header)); textblock_free(tb); return 2; case MENU_VALUE_DROP_ALL: /* Drop entire stack with confirmation. */ if (get_check(format("Drop %s? ", header))) { cmd_insert(store_in_store ? CMD_STASH : CMD_DROP); cmd_set_arg_item(cmd_get_top(), 0, slot); cmd_set_arg_number(cmd_get_top(), 1, o_ptr->number); } return 1; case CMD_STUDY_SPELL: /* Hack - Use the STUDY_BOOK command key so that get_item_allow() works properly. */ cmdkey = cmd_lookup_key(CMD_STUDY_BOOK, mode); /* Fall through. */ case CMD_BROWSE_SPELL: case CMD_STUDY_BOOK: case CMD_CAST: case CMD_DESTROY: case CMD_WIELD: case CMD_TAKEOFF: case CMD_INSCRIBE: case CMD_UNINSCRIBE: case CMD_PICKUP: case CMD_DROP: case CMD_REFILL: case CMD_THROW: case CMD_USE_WAND: case CMD_USE_ROD: case CMD_USE_STAFF: case CMD_READ_SCROLL: case CMD_QUAFF: case CMD_EAT: case CMD_ACTIVATE: case CMD_FIRE: case CMD_USE_ANY: /* Check for inscriptions that trigger confirmation. */ allowed = key_confirm_command(cmdkey) && get_item_allow(slot, cmdkey, selected, FALSE); break; default: /* Invalid command; prevent anything from happening. */ bell("Invalid context menu command."); allowed = FALSE; break; } if (!allowed) return 1; if (selected == CMD_DESTROY) { /* squelch or unsquelch the item */ textui_cmd_destroy_menu(slot); } else if (selected == CMD_BROWSE_SPELL) { /* browse a spellbook */ /* copied from textui_spell_browse */ textui_book_browse(o_ptr); return 2; } else if (selected == CMD_STUDY_SPELL) { /* study a spell book */ /* copied from textui_obj_study */ int spell = get_spell(o_ptr, "study", spell_okay_to_study); if (spell >= 0) { cmd_insert(CMD_STUDY_SPELL); cmd_set_arg_choice(cmd_get_top(), 0, spell); } } else if (selected == CMD_CAST) { if (obj_can_browse(o_ptr)) { /* copied from textui_obj_cast */ const char *verb = ((p_ptr->class->spell_book == TV_MAGIC_BOOK) ? "cast" : "recite"); int spell = get_spell(o_ptr, verb, spell_okay_to_cast); if (spell >= 0) { cmd_insert(CMD_CAST); cmd_set_arg_choice(cmd_get_top(), 0, spell); } } } else {
int context_menu_player(int mx, int my) { menu_type *m; region r; int selected; char *labels; bool allowed = TRUE; int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; unsigned char cmdkey; m = menu_dynamic_new(); if (!m) { return 0; } labels = string_make(lower_case); m->selections = labels; ADD_LABEL("Use", CMD_USE_ANY, MN_ROW_VALID); /* if player can cast, add casting option */ if (player_can_cast(p_ptr, FALSE)) { ADD_LABEL("Cast", CMD_CAST, MN_ROW_VALID); } /* if player is on stairs add option to use them */ if (cave_isupstairs(cave, p_ptr->py, p_ptr->px)) { ADD_LABEL("Go Up", CMD_GO_UP, MN_ROW_VALID); } else if (cave_isdownstairs(cave, p_ptr->py, p_ptr->px)) { ADD_LABEL("Go Down", CMD_GO_DOWN, MN_ROW_VALID); } ADD_LABEL("Search", CMD_SEARCH, MN_ROW_VALID); /* Looking has different keys, but we don't have a way to look them up (see cmd-process.c). */ cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'l' : 'x'; menu_dynamic_add_label(m, "Look", cmdkey, MENU_VALUE_LOOK, labels); /* 'R' is used for resting in both keymaps. */ menu_dynamic_add_label(m, "Rest", 'R', MENU_VALUE_REST, labels); /* 'i' is used for inventory in both keymaps. */ menu_dynamic_add_label(m, "Inventory", 'i', MENU_VALUE_INVENTORY, labels); /* if object under player add pickup option */ if (cave->o_idx[p_ptr->py][p_ptr->px]) { object_type *o_ptr = object_byid(cave->o_idx[p_ptr->py][p_ptr->px]); if (!squelch_item_ok(o_ptr)) { menu_row_validity_t valid; /* 'f' isn't in rogue keymap, so we can use it here. */ menu_dynamic_add_label(m, "Floor", 'f', MENU_VALUE_FLOOR, labels); valid = (inven_carry_okay(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Pick up", CMD_PICKUP, valid); } } /* 'C' is used for the character sheet in both keymaps. */ menu_dynamic_add_label(m, "Character", 'C', MENU_VALUE_CHARACTER, labels); /* XXX Don't show the keymap line until the keymap list is implemented, to * avoid confusion as to what should be there */ /*menu_dynamic_add(m, "Keymaps", 10);*/ if (!OPT(center_player)) { menu_dynamic_add_label(m, "^Center Map", 'L', MENU_VALUE_CENTER_MAP, labels); } menu_dynamic_add_label(m, "Other", ' ', MENU_VALUE_OTHER, labels); /* work out display region */ r.width = (int)menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ if (mx > Term->wid - r.width - 1) { r.col = Term->wid - r.width - 1; } else { r.col = mx + 1; } r.page_rows = m->count; if (my > Term->hgt - r.page_rows - 1) { if (my - r.page_rows - 1 <= 0) { /* menu has too many items, so put in upper right corner */ r.row = 1; r.col = Term->wid - r.width - 1; } else { r.row = Term->hgt - r.page_rows - 1; } } else { r.row = my + 1; } /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); menu_layout(m, &r); region_erase_bordered(&r); prt("(Enter to select, ESC) Command:", 0, 0); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); screen_load(); cmdkey = cmd_lookup_key(selected, mode); /* Check the command to see if it is allowed. */ switch(selected) { case -1: /* User cancelled the menu. */ return 3; case CMD_USE_ANY: case CMD_CAST: case CMD_SEARCH: case CMD_GO_UP: case CMD_GO_DOWN: case CMD_PICKUP: /* Only check for ^ inscriptions, since we don't have an object selected (if we need one). */ allowed = key_confirm_command(cmdkey); break; case MENU_VALUE_REST: allowed = key_confirm_command('R'); break; case MENU_VALUE_INVENTORY: case MENU_VALUE_LOOK: case MENU_VALUE_CHARACTER: case MENU_VALUE_OTHER: case MENU_VALUE_FLOOR: case MENU_VALUE_CENTER_MAP: allowed = TRUE; break; default: /* Invalid command; prevent anything from happening. */ bell("Invalid context menu command."); allowed = FALSE; break; } if (!allowed) return 1; /* Perform the command. */ switch(selected) { case CMD_USE_ANY: case CMD_CAST: cmdkey = cmd_lookup_key(selected, mode); Term_keypress(cmdkey, 0); break; case CMD_SEARCH: case CMD_GO_UP: case CMD_GO_DOWN: case CMD_PICKUP: cmd_insert(selected); break; case MENU_VALUE_REST: Term_keypress('R', 0); break; case MENU_VALUE_INVENTORY: Term_keypress('i', 0); break; case MENU_VALUE_LOOK: if (target_set_interactive(TARGET_LOOK, p_ptr->px, p_ptr->py)) { msg("Target Selected."); } break; case MENU_VALUE_CHARACTER: Term_keypress('C', 0); break; case MENU_VALUE_OTHER: context_menu_player_2(mx, my); break; case MENU_VALUE_FLOOR: context_menu_player_display_floor(); break; case MENU_VALUE_CENTER_MAP: do_cmd_center_map(); break; default: break; } return 1; }
/** * Pick up objects and treasure on the floor. -LM- * * Scan the list of objects in that floor grid. Pick up gold automatically. * Pick up objects automatically until backpack space is full if * auto-pickup option is on, otherwise, store objects on * floor in an array, and tally both how many there are and can be picked up. * * If not picking up anything, indicate objects on the floor. Do the same * thing if we don't have room for anything. * * Pick up multiple objects 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. * * We keep track of number of objects picked up to calculate time spent. * This tally is incremented even for automatic pickup, so we are careful * (in "dungeon.c" and elsewhere) to handle pickup as either a separate * automated move or a no-cost part of the stay still or 'g'et command. * * Note the lack of chance for the character to be disturbed by unmarked * objects. They are truly "unknown". * * \param obj is the object to pick up. * \param menu is whether to present a menu to the player */ static byte player_pickup_item(struct object *obj, bool menu) { int py = player->py; int px = player->px; struct object *current = NULL; int floor_max = z_info->floor_size + 1; struct object **floor_list = mem_zalloc(floor_max * sizeof(*floor_list)); int floor_num = 0; int i; int can_pickup = 0; bool call_function_again = FALSE; bool domsg = TRUE; /* Objects picked up. Used to determine time cost of command. */ byte objs_picked_up = 0; /* Always pickup gold, effortlessly */ player_pickup_gold(); /* Nothing else to pick up -- return */ if (!square_object(cave, py, px)) { mem_free(floor_list); return objs_picked_up; } /* Tally objects that can be picked up.*/ floor_num = scan_floor(floor_list, floor_max, py, px, 0x08, NULL); for (i = 0; i < floor_num; i++) if (inven_carry_okay(floor_list[i])) can_pickup++; if (!can_pickup) { /* Can't pick up, but probably want to know what's there. */ event_signal(EVENT_SEEFLOOR); mem_free(floor_list); return objs_picked_up; } /* Use the item that we are given, if it is on the floor. */ if (square_holds_object(cave, py, px, obj)) current = obj; /* Use a menu interface for multiple objects, or pickup single objects */ if (!menu && !current) { if (floor_num > 1) menu = TRUE; else current = floor_list[0]; } /* Display a list if requested. */ if (menu && !current) { const char *q, *s; struct object *obj1; /* Get an object or exit. */ q = "Get which item?"; s = "You see nothing there."; if (!get_item(&obj1, q, s, CMD_PICKUP, inven_carry_okay, USE_FLOOR)) { mem_free(floor_list); return (objs_picked_up); } current = obj1; call_function_again = TRUE; /* With a list, we do not need explicit pickup messages */ domsg = FALSE; } /* Pick up object, if legal */ if (current) { /* Pick up the object */ player_pickup_aux(current, domsg); /* 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 += player_pickup_item(NULL, TRUE); mem_free(floor_list); /* Indicate how many objects have been picked up. */ return (objs_picked_up); }
/** * 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 msg = TRUE; bool telekinesis = (!(y == p_ptr->py) || !(x == p_ptr->px)); /* Nothing to pick up -- return */ if (!cave_o_idx[y][x]) return (0); /* Always pickup gold, effortlessly */ if (!telekinesis) py_pickup_gold(); /* 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_format("You %s %s.", p, o_name); } else { /* Optionally, display more information about floor items */ if (OPT(pickup_detail)) { ui_event_data 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_print("You have no room for any of the items on the floor."); else msg_format("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) { cptr 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 */ msg = 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, msg); } /* 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(3, y, x); /* Indicate how many objects have been picked up. */ return (objs_picked_up); }
bool leprechaun_steal(int m_idx) { bool result = FALSE; monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; if ( !mon_save_p(m_ptr->r_idx, A_DEX) || (MON_CSLEEP(m_ptr) && !mon_save_p(m_ptr->r_idx, A_DEX))) { object_type loot = {0}; if (m_ptr->hold_o_idx && one_in_(2)) { object_copy(&loot, &o_list[m_ptr->hold_o_idx]); delete_object_idx(m_ptr->hold_o_idx); loot.held_m_idx = 0; } else if (m_ptr->drop_ct > m_ptr->stolen_ct) { if (get_monster_drop(m_idx, &loot)) { m_ptr->stolen_ct++; if (r_ptr->flags1 & RF1_UNIQUE) r_ptr->stolen_ct++; } } if (!loot.k_idx) { msg_print("There is nothing to steal!"); } else { char o_name[MAX_NLEN]; result = TRUE; object_desc(o_name, &loot, 0); if (mon_save_p(m_ptr->r_idx, A_DEX)) { msg_format("Oops! You drop %s.", o_name); drop_near(&loot, -1, py, px); } else if (loot.tval == TV_GOLD) { msg_format("You steal %d gold pieces worth of %s.", (int)loot.pval, o_name); sound(SOUND_SELL); p_ptr->au += loot.pval; stats_on_gold_find(loot.pval); p_ptr->redraw |= (PR_GOLD); if (prace_is_(RACE_MON_LEPRECHAUN)) p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA); } else if (!inven_carry_okay(&loot)) { msg_format("You have no room for %s.", o_name); drop_near(&loot, -1, py, px); } else { int slot = inven_carry(&loot); msg_format("You steal %s (%c).", o_name, index_to_label(slot)); autopick_alter_item(slot, TRUE); } } } return result; }