/** * Label an item as an ego item if it has the required flags */ void label_as_ego(object_type * o_ptr, int item) { char o_name[120]; int j; int temp_flag; ego_item_type *e_ptr = &e_info[o_ptr->name2]; /* All ego object flags now known */ of_union(o_ptr->id_obj, e_ptr->flags_obj); /* All shown curses are now known */ if (of_has(e_ptr->flags_obj, OF_SHOW_CURSE)) cf_union(o_ptr->id_curse, e_ptr->flags_curse); /* Know all ego resists */ for (j = 0; j < MAX_P_RES; j++) { temp_flag = OBJECT_ID_BASE_RESIST + j; if (e_ptr->percent_res[j] != RES_LEVEL_BASE) if_on(o_ptr->id_other, temp_flag); } /* Know all ego slays */ for (j = 0; j < MAX_P_SLAY; j++) { temp_flag = OBJECT_ID_BASE_SLAY + j; if (e_ptr->multiple_slay[j] != MULTIPLE_BASE) if_on(o_ptr->id_other, temp_flag); } /* Know all ego brands */ for (j = 0; j < MAX_P_BRAND; j++) { temp_flag = OBJECT_ID_BASE_BRAND + j; if (e_ptr->multiple_brand[j] != MULTIPLE_BASE) if_on(o_ptr->id_other, temp_flag); } /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Redraw stuff */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP | PR_BASIC | PR_EXTRA); /* Handle stuff */ handle_stuff(p_ptr); /* Description */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Describe */ if (item - 1 >= INVEN_WIELD) { char *m = format("%s: %s (%c).", describe_use(item - 1), o_name, index_to_label(item - 1)); my_strcap(m); msg(m); } else if (item - 1 >= 0) { msg("In your pack: %s (%c).", o_name, index_to_label(item)); } }
/* * Display the floor. Builds a list of objects and passes them * off to show_obj_list() for display. Mode flags documented in * object.h */ void show_floor(const int *floor_list, int floor_num, int mode) { int i; object_type *o_ptr; int num_obj = 0; char labels[50][80]; object_type *objects[50]; if (floor_num > MAX_FLOOR_STACK) floor_num = MAX_FLOOR_STACK; /* Build the object list */ for (i = 0; i < floor_num; i++) { o_ptr = object_byid(floor_list[i]); /* Tester always skips gold. When gold should be displayed, * only test items that are not gold. */ if ((o_ptr->tval != TV_GOLD || !(mode & OLIST_GOLD)) && !item_tester_okay(o_ptr)) continue; strnfmt(labels[num_obj], sizeof(labels[num_obj]), "%c) ", index_to_label(i)); /* Save the object */ objects[num_obj] = o_ptr; num_obj++; } /* Display the object list */ show_obj_list(num_obj, 0, labels, objects, mode); }
/* * Carry an object and delete it. */ static void py_pickup_aux(int o_idx, bool domsg) { int slot, quiver_slot = 0; char o_name[80]; object_type *o_ptr = object_byid(o_idx); /* Carry the object */ slot = inven_carry(p_ptr, o_ptr); /* Handle errors (paranoia) */ if (slot < 0) return; /* If we have picked up ammo which matches something in the quiver, note * that it so that we can wield it later (and suppress pick up message) */ if (obj_is_ammo(o_ptr)) { int i; for (i = QUIVER_START; i < QUIVER_END; i++) { if (!p_ptr->inventory[i].kind) continue; if (!object_similar(&p_ptr->inventory[i], o_ptr, OSTACK_QUIVER)) continue; quiver_slot = i; break; } } /* Get the new object */ o_ptr = &p_ptr->inventory[slot]; /* Set squelch status */ p_ptr->notice |= PN_SQUELCH; /* Automatically sense artifacts */ object_notice_artifact(o_ptr); /* Optionally, display a message */ if (domsg && !quiver_slot) { /* Describe the object */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Message */ msg("You have %s (%c).", o_name, index_to_label(slot)); } /* Update object_idx if necessary */ if (p_ptr->object_idx == (0 - o_idx)) { track_object(slot); } /* Delete the object */ delete_object_idx(o_idx); /* If we have a quiver slot that this ammo matches, use it */ if (quiver_slot) wield_item(o_ptr, slot, quiver_slot); }
/* * Display the inventory. Builds a list of objects and passes them * off to show_obj_list() for display. Mode flags documented in * object.h */ void show_inven(olist_detail_t mode) { int i, last_slot = 0; int diff = weight_remaining(); object_type *o_ptr; int num_obj = 0; char labels[50][80]; object_type *objects[50]; bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; /* Include burden for term windows */ if (in_term) { strnfmt(labels[num_obj], sizeof(labels[num_obj]), "Burden %d.%d lb (%d.%d lb %s) ", p_ptr->total_weight / 10, p_ptr->total_weight % 10, abs(diff) / 10, abs(diff) % 10, (diff < 0 ? "overweight" : "remaining")); objects[num_obj] = NULL; num_obj++; } /* Find the last occupied inventory slot */ for (i = 0; i < INVEN_PACK; i++) { o_ptr = &p_ptr->inventory[i]; if (o_ptr->k_idx) last_slot = i; } /* Build the object list */ for (i = 0; i <= last_slot; i++) { o_ptr = &p_ptr->inventory[i]; /* Acceptable items get a label */ if (item_tester_okay(o_ptr)) strnfmt(labels[num_obj], sizeof(labels[num_obj]), "%c) ", index_to_label(i)); /* Unacceptable items are still displayed in term windows */ else if (in_term) my_strcpy(labels[num_obj], " ", sizeof(labels[num_obj])); /* Unacceptable items are skipped in the main window */ else continue; /* Save the object */ objects[num_obj] = o_ptr; num_obj++; } /* Display the object list */ show_obj_list(num_obj, labels, objects, mode); }
/* * Display the equipment. Builds a list of objects and passes them * off to show_obj_list() for display. Mode flags documented in * object.h */ void show_equip(int mode) { int i, last_slot = 0; object_type *o_ptr; int num_obj = 0; char labels[50][80]; object_type *objects[50]; char tmp_val[80]; bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; bool show_empty = (mode & OLIST_SEMPTY) ? TRUE : FALSE; /* Find the last equipment slot to display */ for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++) { o_ptr = &p_ptr->inventory[i]; if (i < INVEN_TOTAL || o_ptr->kind) last_slot = i; } /* Build the object list */ for (i = INVEN_WIELD; i <= last_slot; i++) { o_ptr = &p_ptr->inventory[i]; /* May need a blank line to separate the quiver */ if (i == INVEN_TOTAL) { int j; bool need_spacer = FALSE; /* Scan the rest of the items for acceptable entries */ for (j = i; j < last_slot; j++) { o_ptr = &p_ptr->inventory[j]; if (item_tester_okay(o_ptr)) need_spacer = TRUE; } /* Add a spacer between equipment and quiver */ if (num_obj > 0 && need_spacer) { my_strcpy(labels[num_obj], "", sizeof(labels[num_obj])); objects[num_obj] = NULL; num_obj++; } continue; } /* Acceptable items get a label */ if (item_tester_okay(o_ptr)) strnfmt(labels[num_obj], sizeof(labels[num_obj]), "%c) ", index_to_label(i)); /* Unacceptable items are still sometimes shown */ else if ((!o_ptr->kind && show_empty) || in_term) my_strcpy(labels[num_obj], " ", sizeof(labels[num_obj])); /* Unacceptable items are skipped in the main window */ else continue; /* Show full slot labels */ strnfmt(tmp_val, sizeof(tmp_val), "%-14s: ", mention_use(i)); my_strcat(labels[num_obj], tmp_val, sizeof(labels[num_obj])); /* Save the object */ objects[num_obj] = o_ptr; num_obj++; } /* Display the object list */ show_obj_list(num_obj, 0, labels, objects, mode); }
/* * Attack the player via physical attacks. */ bool make_attack_normal(int m_idx) { monster_type *m_ptr = &mon_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; monster_lore *l_ptr = &l_list[m_ptr->r_idx]; int ap_cnt; int i, k, tmp, ac, rlev; int do_cut, do_stun; s32b gold; object_type *o_ptr; char o_name[80]; char m_name[80]; char ddesc[80]; bool blinked; /* Not allowed to attack */ if (r_ptr->flags1 & (RF1_NEVER_BLOW)) return (FALSE); /* Total armor */ ac = p_ptr->ac + p_ptr->to_a; /* Extract the effective monster level */ rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); /* Get the monster name (or "it") */ monster_desc(m_name, sizeof(m_name), m_ptr, 0); /* Get the "died from" information (i.e. "a kobold") */ monster_desc(ddesc, sizeof(ddesc), m_ptr, 0x88); /* Assume no blink */ blinked = FALSE; /* Scan through all blows */ for (ap_cnt = 0; ap_cnt < MONSTER_BLOW_MAX; ap_cnt++) { bool visible = FALSE; bool obvious = FALSE; int power = 0; int damage = 0; cptr act = NULL; /* Extract the attack infomation */ int effect = r_ptr->blow[ap_cnt].effect; int method = r_ptr->blow[ap_cnt].method; int d_dice = r_ptr->blow[ap_cnt].d_dice; int d_side = r_ptr->blow[ap_cnt].d_side; /* Hack -- no more attacks */ if (!method) break; /* Handle "leaving" */ if (p_ptr->leaving) break; /* Extract visibility (before blink) */ if (m_ptr->ml) visible = TRUE; /* Extract the attack "power" */ switch (effect) { case RBE_HURT: power = 60; break; case RBE_POISON: power = 5; break; case RBE_UN_BONUS: power = 20; break; case RBE_UN_POWER: power = 15; break; case RBE_EAT_GOLD: power = 5; break; case RBE_EAT_ITEM: power = 5; break; case RBE_EAT_FOOD: power = 5; break; case RBE_EAT_LITE: power = 5; break; case RBE_ACID: power = 0; break; case RBE_ELEC: power = 10; break; case RBE_FIRE: power = 10; break; case RBE_COLD: power = 10; break; case RBE_BLIND: power = 2; break; case RBE_CONFUSE: power = 10; break; case RBE_TERRIFY: power = 10; break; case RBE_PARALYZE: power = 2; break; case RBE_LOSE_STR: power = 0; break; case RBE_LOSE_DEX: power = 0; break; case RBE_LOSE_CON: power = 0; break; case RBE_LOSE_INT: power = 0; break; case RBE_LOSE_WIS: power = 0; break; case RBE_LOSE_CHR: power = 0; break; case RBE_LOSE_ALL: power = 2; break; case RBE_SHATTER: power = 60; break; case RBE_EXP_10: power = 5; break; case RBE_EXP_20: power = 5; break; case RBE_EXP_40: power = 5; break; case RBE_EXP_80: power = 5; break; case RBE_HALLU: power = 10; break; } /* Monster hits player */ if (!effect || check_hit(power, rlev)) { /* Always disturbing */ disturb(1, 0); /* Hack -- Apply "protection from evil" */ if ((p_ptr->protevil > 0) && (r_ptr->flags3 & (RF3_EVIL)) && (p_ptr->lev >= rlev) && ((rand_int(100) + p_ptr->lev) > 50)) { /* Remember the Evil-ness */ if (m_ptr->ml) { l_ptr->flags3 |= (RF3_EVIL); } /* Message */ msg_format("%^s is repelled.", m_name); /* Hack -- Next attack */ continue; } /* Assume no cut or stun */ do_cut = do_stun = 0; /* Describe the attack method */ switch (method) { case RBM_HIT: { act = "hits you."; do_cut = do_stun = 1; break; } case RBM_TOUCH: { act = "touches you."; break; } case RBM_PUNCH: { act = "punches you."; do_stun = 1; break; } case RBM_KICK: { act = "kicks you."; do_stun = 1; break; } case RBM_CLAW: { act = "claws you."; do_cut = 1; break; } case RBM_BITE: { act = "bites you."; do_cut = 1; break; } case RBM_STING: { act = "stings you."; break; } case RBM_XXX1: { act = "XXX1's you."; break; } case RBM_BUTT: { act = "butts you."; do_stun = 1; break; } case RBM_CRUSH: { act = "crushes you."; do_stun = 1; break; } case RBM_ENGULF: { act = "engulfs you."; break; } case RBM_XXX2: { act = "XXX2's you."; break; } case RBM_CRAWL: { act = "crawls on you."; break; } case RBM_DROOL: { act = "drools on you."; break; } case RBM_SPIT: { act = "spits on you."; break; } case RBM_XXX3: { act = "XXX3's on you."; break; } case RBM_GAZE: { act = "gazes at you."; break; } case RBM_WAIL: { act = "wails at you."; break; } case RBM_SPORE: { act = "releases spores at you."; break; } case RBM_XXX4: { act = "projects XXX4's at you."; break; } case RBM_BEG: { act = "begs you for money."; break; } case RBM_INSULT: { act = desc_insult[rand_int(MAX_DESC_INSULT)]; break; } case RBM_MOAN: { act = desc_moan[rand_int(MAX_DESC_MOAN)]; break; } case RBM_XXX5: { act = "XXX5's you."; break; } } /* Message */ if (act) msg_format("%^s %s", m_name, act); /* Hack -- assume all attacks are obvious */ obvious = TRUE; /* Roll out the damage */ damage = damroll(d_dice, d_side); /* Apply appropriate damage */ switch (effect) { case 0: { /* Hack -- Assume obvious */ obvious = TRUE; /* Hack -- No damage */ damage = 0; break; } case RBE_HURT: { /* Obvious */ obvious = TRUE; /* Hack -- Player armor reduces total damage */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); /* Take damage */ take_hit(damage, ddesc); break; } case RBE_POISON: { /* Take damage */ take_hit(damage, ddesc); /* Take "poison" effect */ if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_POIS); break; } case RBE_UN_BONUS: { /* Take damage */ take_hit(damage, ddesc); /* Allow complete resist */ if (!p_ptr->resist_disen) { /* Apply disenchantment */ if (apply_disenchant(0)) obvious = TRUE; } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_DISEN); break; } case RBE_UN_POWER: { /* Take damage */ take_hit(damage, ddesc); /* Find an item */ for (k = 0; k < 10; k++) { /* Pick an item */ i = rand_int(INVEN_PACK); /* Obtain the item */ o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Drain charged wands/staffs */ if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)) && (o_ptr->pval > 0)) { /* Calculate healed hitpoints */ int heal = rlev * o_ptr->pval * o_ptr->number; /* Don't heal more than max hp */ heal = MIN(heal, m_ptr->maxhp - m_ptr->hp); /* Message */ msg_print("Energy drains from your pack!"); /* Obvious */ obvious = TRUE; /* Heal */ m_ptr->hp += heal; /* Redraw (later) if needed */ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH); /* Uncharge */ o_ptr->pval = 0; /* Combine / Reorder the pack */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ p_ptr->window |= (PW_INVEN); /* Done */ break; } } break; } case RBE_EAT_GOLD: { /* Take damage */ take_hit(damage, ddesc); /* Obvious */ obvious = TRUE; /* Saving throw (unless paralyzed) based on dex and level */ if (!p_ptr->paralyzed && (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] + p_ptr->lev))) { /* Saving throw message */ msg_print("You quickly protect your money pouch!"); /* Occasional blink anyway */ if (rand_int(3)) blinked = TRUE; } /* Eat gold */ else { gold = (p_ptr->au / 10) + randint(25); if (gold < 2) gold = 2; if (gold > 5000) gold = (p_ptr->au / 20) + randint(3000); if (gold > p_ptr->au) gold = p_ptr->au; p_ptr->au -= gold; if (gold <= 0) { msg_print("Nothing was stolen."); } else if (p_ptr->au) { msg_print("Your purse feels lighter."); msg_format("%ld coins were stolen!", (long)gold); } else { msg_print("Your purse feels lighter."); msg_print("All of your coins were stolen!"); } /* Redraw gold */ p_ptr->redraw |= (PR_GOLD); /* Window stuff */ p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Blink away */ blinked = TRUE; } break; } case RBE_EAT_ITEM: { /* Take damage */ take_hit(damage, ddesc); /* Saving throw (unless paralyzed) based on dex and level */ if (!p_ptr->paralyzed && (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] + p_ptr->lev))) { /* Saving throw message */ msg_print("You grab hold of your backpack!"); /* Occasional "blink" anyway */ blinked = TRUE; /* Obvious */ obvious = TRUE; /* Done */ break; } /* Find an item */ for (k = 0; k < 10; k++) { object_type *i_ptr; object_type object_type_body; /* Pick an item */ i = rand_int(INVEN_PACK); /* Obtain the item */ o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Skip artifacts */ if (artifact_p(o_ptr)) continue; /* Get a description */ object_desc(o_name, sizeof(o_name), o_ptr, FALSE, 3); /* Message */ msg_format("%sour %s (%c) was stolen!", ((o_ptr->number > 1) ? "One of y" : "Y"), o_name, index_to_label(i)); /* Get local object */ i_ptr = &object_type_body; /* Obtain local object */ object_copy(i_ptr, o_ptr); /* Modify number */ i_ptr->number = 1; /* Carry the object */ (void)monster_carry(m_idx, i_ptr); /* Steal the items */ inven_item_increase(i, -1); inven_item_optimize(i); /* Obvious */ obvious = TRUE; /* Blink away */ blinked = TRUE; /* Done */ break; } break; } case RBE_EAT_FOOD: { /* Take damage */ take_hit(damage, ddesc); /* Steal some food */ for (k = 0; k < 10; k++) { /* Pick an item from the pack */ i = rand_int(INVEN_PACK); /* Get the item */ o_ptr = &inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Skip non-food objects */ if (o_ptr->tval != TV_FOOD) continue; /* Get a description */ object_desc(o_name, sizeof(o_name), o_ptr, FALSE, 0); /* Message */ msg_format("%sour %s (%c) was eaten!", ((o_ptr->number > 1) ? "One of y" : "Y"), o_name, index_to_label(i)); /* Steal the items */ inven_item_increase(i, -1); inven_item_optimize(i); /* Obvious */ obvious = TRUE; /* Done */ break; } break; } case RBE_EAT_LITE: { /* Take damage */ take_hit(damage, ddesc); /* Get the lite */ o_ptr = &inventory[INVEN_LITE]; /* Drain fuel */ if ((o_ptr->pval > 0) && (!artifact_p(o_ptr))) { /* Reduce fuel */ o_ptr->pval -= (250 + randint(250)); if (o_ptr->pval < 1) o_ptr->pval = 1; /* Notice */ if (!p_ptr->blind) { msg_print("Your light dims."); obvious = TRUE; } /* Window stuff */ p_ptr->window |= (PW_EQUIP); } break; } case RBE_ACID: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are covered in acid!"); /* Special damage */ acid_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_ACID); break; } case RBE_ELEC: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are struck by electricity!"); /* Take damage (special) */ elec_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_ELEC); break; } case RBE_FIRE: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are enveloped in flames!"); /* Take damage (special) */ fire_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_FIRE); break; } case RBE_COLD: { /* Obvious */ obvious = TRUE; /* Message */ msg_print("You are covered with frost!"); /* Take damage (special) */ cold_dam(damage, ddesc); /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_COLD); break; } case RBE_BLIND: { /* Take damage */ take_hit(damage, ddesc); /* Increase "blind" */ if (!p_ptr->resist_blind) { if (set_blind(p_ptr->blind + 10 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_BLIND); break; } case RBE_CONFUSE: { /* Take damage */ take_hit(damage, ddesc); /* Increase "confused" */ if (!p_ptr->resist_confu) { if (set_confused(p_ptr->confused + 3 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_CONFU); break; } case RBE_TERRIFY: { /* Take damage */ take_hit(damage, ddesc); /* Increase "afraid" */ if (p_ptr->resist_fear) { msg_print("You stand your ground!"); obvious = TRUE; } else if (rand_int(100) < p_ptr->skill_sav) { msg_print("You stand your ground!"); obvious = TRUE; } else { if (set_afraid(p_ptr->afraid + 3 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_FEAR); break; } case RBE_PARALYZE: { /* Hack -- Prevent perma-paralysis via damage */ if (p_ptr->paralyzed && (damage < 1)) damage = 1; /* Take damage */ take_hit(damage, ddesc); /* Increase "paralyzed" */ if (p_ptr->free_act) { msg_print("You are unaffected!"); obvious = TRUE; } else if (rand_int(100) < p_ptr->skill_sav) { msg_print("You resist the effects!"); obvious = TRUE; } else { if (set_paralyzed(p_ptr->paralyzed + 3 + randint(rlev))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_FREE); break; } case RBE_LOSE_STR: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_STR)) obvious = TRUE; break; } case RBE_LOSE_INT: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_INT)) obvious = TRUE; break; } case RBE_LOSE_WIS: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_WIS)) obvious = TRUE; break; } case RBE_LOSE_DEX: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_DEX)) obvious = TRUE; break; } case RBE_LOSE_CON: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_CON)) obvious = TRUE; break; } case RBE_LOSE_CHR: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stat) */ if (do_dec_stat(A_CHR)) obvious = TRUE; break; } case RBE_LOSE_ALL: { /* Take damage */ take_hit(damage, ddesc); /* Damage (stats) */ if (do_dec_stat(A_STR)) obvious = TRUE; if (do_dec_stat(A_DEX)) obvious = TRUE; if (do_dec_stat(A_CON)) obvious = TRUE; if (do_dec_stat(A_INT)) obvious = TRUE; if (do_dec_stat(A_WIS)) obvious = TRUE; if (do_dec_stat(A_CHR)) obvious = TRUE; break; } case RBE_SHATTER: { /* Obvious */ obvious = TRUE; /* Hack -- Reduce damage based on the player armor class */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); /* Take damage */ take_hit(damage, ddesc); /* Radius 8 earthquake centered at the monster */ if (damage > 23) earthquake(m_ptr->fy, m_ptr->fx, 8); break; } case RBE_EXP_10: { /* Obvious */ obvious = TRUE; /* Take damage */ take_hit(damage, ddesc); if (p_ptr->hold_life && (rand_int(100) < 95)) { msg_print("You keep hold of your life force!"); } else { s32b d = damroll(10, 6) + (p_ptr->exp/100) * MON_DRAIN_LIFE; if (p_ptr->hold_life) { msg_print("You feel your life slipping away!"); lose_exp(d/10); } else { msg_print("You feel your life draining away!"); lose_exp(d); } } break; } case RBE_EXP_20: { /* Obvious */ obvious = TRUE; /* Take damage */ take_hit(damage, ddesc); if (p_ptr->hold_life && (rand_int(100) < 90)) { msg_print("You keep hold of your life force!"); } else { s32b d = damroll(20, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; if (p_ptr->hold_life) { msg_print("You feel your life slipping away!"); lose_exp(d / 10); } else { msg_print("You feel your life draining away!"); lose_exp(d); } } break; } case RBE_EXP_40: { /* Obvious */ obvious = TRUE; /* Take damage */ take_hit(damage, ddesc); if (p_ptr->hold_life && (rand_int(100) < 75)) { msg_print("You keep hold of your life force!"); } else { s32b d = damroll(40, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; if (p_ptr->hold_life) { msg_print("You feel your life slipping away!"); lose_exp(d / 10); } else { msg_print("You feel your life draining away!"); lose_exp(d); } } break; } case RBE_EXP_80: { /* Obvious */ obvious = TRUE; /* Take damage */ take_hit(damage, ddesc); if (p_ptr->hold_life && (rand_int(100) < 50)) { msg_print("You keep hold of your life force!"); } else { s32b d = damroll(80, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; if (p_ptr->hold_life) { msg_print("You feel your life slipping away!"); lose_exp(d / 10); } else { msg_print("You feel your life draining away!"); lose_exp(d); } } break; } case RBE_HALLU: { /* Take damage */ take_hit(damage, ddesc); /* Increase "image" */ if (!p_ptr->resist_chaos) { if (set_image(p_ptr->image + 3 + randint(rlev / 2))) { obvious = TRUE; } } /* Learn about the player */ update_smart_learn(m_idx, DRS_RES_CHAOS); break; } } /* Hack -- only one of cut or stun */ if (do_cut && do_stun) { /* Cancel cut */ if (rand_int(100) < 50) { do_cut = 0; } /* Cancel stun */ else { do_stun = 0; } } /* Handle cut */ if (do_cut) { int k; /* Critical hit (zero if non-critical) */ tmp = monster_critical(d_dice, d_side, damage); /* Roll for damage */ switch (tmp) { case 0: k = 0; break; case 1: k = randint(5); break; case 2: k = randint(5) + 5; break; case 3: k = randint(20) + 20; break; case 4: k = randint(50) + 50; break; case 5: k = randint(100) + 100; break; case 6: k = 300; break; default: k = 500; break; } /* Apply the cut */ if (k) (void)set_cut(p_ptr->cut + k); } /* Handle stun */ if (do_stun) { int k; /* Critical hit (zero if non-critical) */ tmp = monster_critical(d_dice, d_side, damage); /* Roll for damage */ switch (tmp) { case 0: k = 0; break; case 1: k = randint(5); break; case 2: k = randint(10) + 10; break; case 3: k = randint(20) + 20; break; case 4: k = randint(30) + 30; break; case 5: k = randint(40) + 40; break; case 6: k = 100; break; default: k = 200; break; } /* Apply the stun */ if (k) (void)set_stun(p_ptr->stun + k); } } /* Monster missed player */ else { /* Analyze failed attacks */ switch (method) { case RBM_HIT: case RBM_TOUCH: case RBM_PUNCH: case RBM_KICK: case RBM_CLAW: case RBM_BITE: case RBM_STING: case RBM_XXX1: case RBM_BUTT: case RBM_CRUSH: case RBM_ENGULF: case RBM_XXX2: /* Visible monsters */ if (m_ptr->ml) { /* Disturbing */ disturb(1, 0); /* Message */ msg_format("%^s misses you.", m_name); } break; } } /* Analyze "visible" monsters only */ if (visible) { /* Count "obvious" attacks (and ones that cause damage) */ if (obvious || damage || (l_ptr->blows[ap_cnt] > 10)) { /* Count attacks of this type */ if (l_ptr->blows[ap_cnt] < MAX_UCHAR) { l_ptr->blows[ap_cnt]++; } } } } /* Blink away */ if (blinked) { msg_print("There is a puff of smoke!"); teleport_away(m_idx, MAX_SIGHT * 2 + 5); } /* Always notice cause of death */ if (p_ptr->is_dead && (l_ptr->deaths < MAX_SHORT)) { l_ptr->deaths++; } /* Assume we attacked */ return (TRUE); }
/* * Wield or wear a single item from the pack or floor */ void wield_item(object_type *o_ptr, int item, int slot) { object_type object_type_body; object_type *i_ptr = &object_type_body; const char *fmt; char o_name[80]; bool combined_ammo = FALSE; bool track_wielded_item = FALSE; int num = 1; /* If we are stacking ammo in the quiver */ if (obj_is_ammo(o_ptr)) { num = o_ptr->number; combined_ammo = object_similar(o_ptr, &p_ptr->inventory[slot], OSTACK_QUIVER); } /* Take a turn */ p_ptr->energy_use = 100; /* Obtain local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = num; /* Update object_idx if necessary, once object is in slot */ if (p_ptr->object_idx == item) { track_wielded_item = TRUE; } /* Decrease the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -num); inven_item_optimize(item); } /* Decrease the item (from the floor) */ else { floor_item_increase(0 - item, -num); floor_item_optimize(0 - item); } /* Get the wield slot */ o_ptr = &p_ptr->inventory[slot]; if (combined_ammo) { /* Add the new ammo to the already-quiver-ed ammo */ object_absorb(o_ptr, i_ptr); } else { /* Take off existing item */ if (o_ptr->kind) (void)inven_takeoff(slot, 255); /* If we are wielding ammo we may need to "open" the slot by shifting * later ammo up the quiver; this is because we already called the * inven_item_optimize() function. */ if (slot >= QUIVER_START) open_quiver_slot(slot); /* Wear the new stuff */ object_copy(o_ptr, i_ptr); /* Increment the equip counter by hand */ p_ptr->equip_cnt++; } /* Increase the weight */ p_ptr->total_weight += i_ptr->weight * num; /* Track object if necessary */ if (track_wielded_item) { track_object(slot); } /* Do any ID-on-wield */ object_notice_on_wield(o_ptr); /* Where is the item now */ if (slot == INVEN_WIELD) fmt = "You are wielding %s (%c)."; else if (slot == INVEN_BOW) fmt = "You are shooting with %s (%c)."; else if (slot == INVEN_LIGHT) fmt = "Your light source is %s (%c)."; else if (combined_ammo) fmt = "You combine %s in your quiver (%c)."; else if (slot >= QUIVER_START && slot < QUIVER_END) fmt = "You add %s to your quiver (%c)."; else fmt = "You are wearing %s (%c)."; /* Describe the result */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Message */ msgt(MSG_WIELD, fmt, o_name, index_to_label(slot)); /* Cursed! */ if (cursed_p(o_ptr->flags)) { /* Warn the player */ msgt(MSG_CURSED, "Oops! It feels deathly cold!"); /* Sense the object */ object_notice_curses(o_ptr); } /* Save quiver size */ save_quiver_size(p_ptr); /* See if we have to overflow the pack */ pack_overflow(); /* Recalculate bonuses, torch, mana */ p_ptr->notice |= PN_SORT_QUIVER; p_ptr->update |= (PU_BONUS | PU_TORCH | PU_MANA); p_ptr->redraw |= (PR_INVEN | PR_EQUIP); }
/* * Sense the inventory */ void sense_inventory(void) { int i; char o_name[80]; unsigned int rate; /* No ID when confused in a bad state */ if (p_ptr->timed[TMD_CONFUSED]) return; /* Notice some things after a while */ if (turn >= (object_last_wield + 3000)) { object_notice_after_time(); object_last_wield = 0; } /* Get improvement rate */ if (player_has(PF_PSEUDO_ID_IMPROV)) rate = cp_ptr->sense_base / (p_ptr->lev * p_ptr->lev + cp_ptr->sense_div); else rate = cp_ptr->sense_base / (p_ptr->lev + cp_ptr->sense_div); if (!one_in_(rate)) return; /* Check everything */ for (i = 0; i < ALL_INVEN_TOTAL; i++) { const char *text = NULL; object_type *o_ptr = &p_ptr->inventory[i]; obj_pseudo_t feel; bool cursed; bool okay = FALSE; /* Skip empty slots */ if (!o_ptr->k_idx) continue; /* Valid "tval" codes */ switch (o_ptr->tval) { case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_BOW: case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_BOOTS: case TV_GLOVES: case TV_HELM: case TV_CROWN: case TV_SHIELD: case TV_CLOAK: case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR: { okay = TRUE; break; } } /* Skip non-sense machines */ if (!okay) continue; /* It is known, no information needed */ if (object_is_known(o_ptr)) continue; /* It has already been sensed, do not sense it again */ if (object_was_sensed(o_ptr)) { /* Small chance of wielded, sensed items getting complete ID */ if (!o_ptr->name1 && (i >= INVEN_WIELD) && one_in_(1000)) do_ident_item(i, o_ptr); continue; } /* Occasional failure on inventory items */ if ((i < INVEN_WIELD) && one_in_(5)) continue; /* Sense the object */ object_notice_sensing(o_ptr); cursed = object_notice_curses(o_ptr); /* Get the feeling */ feel = object_pseudo(o_ptr); /* Stop everything */ disturb(0, 0); if (cursed) text = "cursed"; else text = inscrip_text[feel]; object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE); /* Average pseudo-ID means full ID */ if (feel == INSCRIP_AVERAGE) { object_notice_everything(o_ptr); message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) %s %s average...", o_name, index_to_label(i),((i >= INVEN_WIELD) ? "you are using" : "in your pack"), ((o_ptr->number == 1) ? "is" : "are")); } else { if (i >= INVEN_WIELD) { message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) you are %s %s %s...", o_name, index_to_label(i), describe_use(i), ((o_ptr->number == 1) ? "is" : "are"), text); } else { message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) in your pack %s %s...", o_name, index_to_label(i), ((o_ptr->number == 1) ? "is" : "are"), text); } } /* Set squelch flag as appropriate */ if (i < INVEN_WIELD) p_ptr->notice |= PN_SQUELCH; /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER); /* Redraw stuff */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); } }
/** * Carry an object and delete it. */ extern void py_pickup_aux(int o_idx, bool msg) { int slot, quiver_slot = 0; char o_name[120]; object_type *o_ptr = &o_list[o_idx]; object_type *i_ptr = &p_ptr->inventory[INVEN_LIGHT]; bitflag f[OF_SIZE], obvious_mask[OF_SIZE]; flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END); of_copy(f, o_ptr->flags_obj); /* Carry the object */ slot = inven_carry(p_ptr, o_ptr); /* Handle errors (paranoia) */ if (slot < 0) return; /* If we have picked up ammo which matches something in the quiver, note * that it so that we can wield it later (and suppress pick up message) */ if (obj_is_quiver_obj(o_ptr)) { int i; for (i = QUIVER_START; i < QUIVER_END; i++) { if (!p_ptr->inventory[i].k_idx) continue; if (!object_similar(&p_ptr->inventory[i], o_ptr, OSTACK_QUIVER)) continue; quiver_slot = i; break; } } /* Get the object again */ o_ptr = &p_ptr->inventory[slot]; /* Set squelch status */ p_ptr->notice |= PN_SQUELCH; /* Stone of Lore gives id on pickup */ if (!object_known_p(o_ptr)) { if (i_ptr->sval == SV_STONE_LORE) identify_object(o_ptr); /* Otherwise pseudo-ID */ else { bool heavy = FALSE; int feel; /* Heavy sensing */ heavy = (player_has(PF_PSEUDO_ID_HEAVY)); /* Type of feeling */ feel = (heavy ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr)); /* We have "felt" it */ o_ptr->ident |= (IDENT_SENSE); /* Inscribe it textually */ o_ptr->feel = feel; /* Set squelch flag as appropriate */ p_ptr->notice |= PN_SQUELCH; } } /* Log artifacts if found */ if (artifact_p(o_ptr)) history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE); /* Notice dice and other obvious stuff */ notice_other(IF_DD_DS, slot + 1); (void) of_inter(f, obvious_mask); of_union(o_ptr->id_obj, f); /* Average things are average */ if ((o_ptr->feel == FEEL_AVERAGE) && (is_weapon(o_ptr) || is_armour(o_ptr))){ notice_other(IF_AC, slot + 1); notice_other(IF_TO_A, slot + 1); notice_other(IF_TO_H, slot + 1); notice_other(IF_TO_D, slot + 1); } /* Recalculate the bonuses */ p_ptr->update |= (PU_BONUS); /* Optionally, display a message */ if (msg && !quiver_slot) { /* Describe the object */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Message */ msg_format("You have %s (%c).", o_name, index_to_label(slot)); } /* Delete the object */ delete_object_idx(o_idx); /* If we have a quiver slot that this item matches, use it */ if (quiver_slot) wield_item(o_ptr, slot, quiver_slot); }
/* * Wield or wear a single item from the pack or floor */ void do_cmd_wield(void) { int i, item, slot; object_type forge; object_type *q_ptr; object_type *o_ptr; cptr act; char o_name[MAX_NLEN]; cptr q, s; bool newrace = FALSE; /* Restrict the choices */ item_tester_hook = item_tester_hook_wear; /* Get an item */ #ifdef JP q = "どれを装備しますか? "; s = "装備可能なアイテムがない。"; #else q = "Wear/Wield which item? "; s = "You have nothing you can wear or wield."; #endif if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Check the slot */ slot = wield_slot(o_ptr); /* Where is the item now */ if (slot == INVEN_WIELD) { #ifdef JP act = "を打撃用に装備した"; #else act = "You are wielding"; #endif } else if (slot == INVEN_BOW) { #ifdef JP act = "を射撃用に装備した"; #else act = "You are shooting with"; #endif } else if (slot == INVEN_LITE) { #ifdef JP act = "を光源にした"; #else act = "Your light source is"; #endif } else { #ifdef JP act = "を装備した"; #else act = "You are wearing"; #endif } if ((o_ptr->tval == TV_RING) && inventory[INVEN_LEFT].k_idx && inventory[INVEN_RIGHT].k_idx) { /* Restrict the choices */ item_tester_tval = TV_RING; /* Choose a ring from the equipment only */ #ifdef JP q = "どちらの指輪と取り替えますか?"; s = "おっと。"; #else q = "Replace which ring? "; s = "Oops."; #endif if (!get_item(&slot, q, s, (USE_EQUIP))) return; } if (slot == INVEN_WIELD) { if (is_two_handed()) { /* Restrict the choices */ item_tester_hook = item_tester_hook_melee_weapon; /* Choose a ring from the equipment only */ #ifdef JP q = "どちらの武器と取り替えますか?"; s = "おっと。"; #else q = "Replace which weapon? "; s = "Oops."; #endif if (!get_item(&slot, q, s, (USE_EQUIP))) return; } else if (inventory[slot].k_idx) { /* Confirm doing two handed combat */ #ifdef JP if (get_check("二刀流を行いますか?")) #else if (get_check("Do you want to do two handed combat?")) #endif { slot = INVEN_ARM; } } } /* Prevent wielding into a cursed slot */ if (cursed_p(&inventory[slot])) { /* Describe it */ object_desc(o_name, &inventory[slot], OD_OMIT_PREFIX | OD_NAME_ONLY); /* Message */ #ifdef JP msg_format("%s%sは呪われているようだ。", describe_use(slot) , o_name ); #else msg_format("The %s you are %s appears to be cursed.", o_name, describe_use(slot)); #endif /* Cancel the command */ return; } if (cursed_p(o_ptr) && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE))) { char dummy[512]; /* Describe it */ object_desc(o_name, o_ptr, OD_OMIT_PREFIX | OD_NAME_ONLY); #ifdef JP sprintf(dummy, "本当に%s{呪われている}を使いますか?", o_name); #else sprintf(dummy, "Really use the %s {cursed}? ", o_name); #endif if (!get_check(dummy)) return; } #if 0 if ((o_ptr->name1 == ART_STONEMASK) && object_known_p(o_ptr) && (p_ptr->prace != RACE_VAMPIRE)) { char dummy[MAX_NLEN+80]; /* Describe it */ object_desc(o_name, o_ptr, OD_OMIT_PREFIX | OD_NAME_ONLY); #ifdef JP sprintf(dummy, "%sを装備すると吸血鬼になります。よろしいですか?", o_name); #else msg_format("%s will transforms you into a vampire permanently when equiped.", o_name); sprintf(dummy, "Do you become a vampire?"); #endif if (!get_check(dummy)) return; } #endif /* Check if completed a quest */ for (i = 0; i < max_quests; i++) { if ((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) && (quest[i].status == QUEST_STATUS_TAKEN) && (quest[i].k_idx == o_ptr->name1)) { quest[i].status = QUEST_STATUS_COMPLETED; quest[i].complev = (byte)p_ptr->lev; #ifdef JP msg_print("クエストを達成した!"); #else msg_print("You completed your quest!"); #endif sound(SOUND_LEVEL); /* (Sound substitute) No quest sound */ msg_print(NULL); } } /* Take a turn */ energy_use = 100; /* Get local object */ q_ptr = &forge; /* Obtain local object */ object_copy(q_ptr, o_ptr); /* Modify quantity */ q_ptr->number = 1; /* Decrease the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -1); inven_item_optimize(item); } /* Decrease the item (from the floor) */ else { floor_item_increase(0 - item, -1); floor_item_optimize(0 - item); } /* Access the wield slot */ o_ptr = &inventory[slot]; /* Take off existing item */ if (o_ptr->k_idx) { /* Take off existing item */ (void)inven_takeoff(slot, 255); } /* Wear the new stuff */ object_copy(o_ptr, q_ptr); /* Player touches it */ o_ptr->marked |= OM_TOUCHED; /* Forget stack */ o_ptr->next_o_idx = 0; /* Forget location */ o_ptr->iy = o_ptr->ix = 0; /* Increase the weight */ p_ptr->total_weight += q_ptr->weight; /* Increment the equip counter by hand */ equip_cnt++; /* Describe the result */ object_desc(o_name, o_ptr, 0); /* Message */ #ifdef JP msg_format("%s(%c)%s。", o_name, index_to_label(slot), act ); #else msg_format("%s %s (%c).", act, o_name, index_to_label(slot)); #endif sound(SOUND_WIELD); /* Cursed! */ if (cursed_p(o_ptr)) { /* Warn the player */ #ifdef JP msg_print("うわ! すさまじく冷たい!"); #else msg_print("Oops! It feels deathly cold!"); #endif sound(SOUND_CURSED); /* Note the curse */ o_ptr->ident |= (IDENT_SENSE); } #if 0 /* if you weild stonemask, you morph into vampire */ if ((o_ptr->name1 == ART_STONEMASK) && (!is_undead())) { p_ptr->prace = RACE_VAMPIRE; newrace = TRUE; #ifdef JP msg_format("あなたは吸血鬼に変化した!"); #else msg_format("You polymorphed into a vampire!"); #endif } #endif if (newrace) { rp_ptr = &race_info[p_ptr->prace]; /* Experience factor */ calc_expfact(); /* Get new height and weight */ get_ahw(FALSE); check_experience(); /* Hitdice */ p_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp; do_cmd_rerate(TRUE); p_ptr->redraw |= (PR_BASIC); p_ptr->update |= (PU_BONUS); handle_stuff(); /* Load an autopick preference file */ autopick_load_pref(FALSE); lite_spot(py, px); } /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Recalculate torch */ p_ptr->update |= (PU_TORCH); /* Recalculate mana */ p_ptr->update |= (PU_MANA); p_ptr->redraw |= (PR_EQUIPPY); /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER | PW_STATS); }
/* * Hack -- Dump a character description file * * XXX XXX XXX Allow the "full" flag to dump additional info, * and trigger its usage from various places in the code. */ errr file_character(const char *path, bool full) { int i, x, y; int a; wchar_t c; ang_file *fp; struct store *st_ptr = &stores[STORE_HOME]; char o_name[80]; char buf[1024]; char *p; /* Unused parameter */ (void)full; /* Open the file for writing */ fp = file_open(path, MODE_WRITE, FTYPE_TEXT); if (!fp) return (-1); /* Begin dump */ file_putf(fp, " [%s Character Dump]\n\n", buildid); /* Display player */ display_player(0); /* Dump part of the screen */ for (y = 1; y < 23; y++) { p = buf; /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ x_file_putf(fp, "%s\n", buf); } /* Skip a line */ file_putf(fp, "\n"); /* Display player */ display_player(1); /* Dump part of the screen */ for (y = 11; y < 20; y++) { p = buf; /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ x_file_putf(fp, "%s\n", buf); } /* Skip a line */ file_putf(fp, "\n"); /* Dump part of the screen */ for (y = 11; y < 20; y++) { p = buf; /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x + 40, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ x_file_putf(fp, "%s\n", buf); } /* Skip some lines */ file_putf(fp, "\n\n"); /* If dead, dump last messages -- Prfnoff */ if (p_ptr->is_dead) { i = messages_num(); if (i > 15) i = 15; file_putf(fp, " [Last Messages]\n\n"); while (i-- > 0) { x_file_putf(fp, "> %s\n", message_str((s16b)i)); } x_file_putf(fp, "\nKilled by %s.\n\n", p_ptr->died_from); } /* Dump the equipment */ file_putf(fp, " [Character Equipment]\n\n"); for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++) { if (i == INVEN_TOTAL) { file_putf(fp, "\n\n [Character Quiver]\n\n"); continue; } object_desc(o_name, sizeof(o_name), &p_ptr->inventory[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, "%c) %s\n", index_to_label(i), o_name); if (p_ptr->inventory[i].kind) object_info_chardump(fp, &p_ptr->inventory[i], 5, 72); } /* Dump the inventory */ file_putf(fp, "\n\n [Character Inventory]\n\n"); for (i = 0; i < INVEN_PACK; i++) { if (!p_ptr->inventory[i].kind) break; object_desc(o_name, sizeof(o_name), &p_ptr->inventory[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, "%c) %s\n", index_to_label(i), o_name); object_info_chardump(fp, &p_ptr->inventory[i], 5, 72); } file_putf(fp, "\n\n"); /* Dump the Home -- if anything there */ if (st_ptr->stock_num) { /* Header */ file_putf(fp, " [Home Inventory]\n\n"); /* Dump all available items */ for (i = 0; i < st_ptr->stock_num; i++) { object_desc(o_name, sizeof(o_name), &st_ptr->stock[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, "%c) %s\n", I2A(i), o_name); object_info_chardump(fp, &st_ptr->stock[i], 5, 72); } /* Add an empty line */ file_putf(fp, "\n\n"); } /* Dump character history */ dump_history(fp); file_putf(fp, "\n\n"); /* Dump options */ file_putf(fp, " [Options]\n\n"); /* Dump options */ for (i = 0; i < OPT_PAGE_MAX - 1; i++) { int j; const char *title = ""; switch (i) { case 0: title = "Interface"; break; case 1: title = "Warning"; break; case 2: title = "Birth"; break; } file_putf(fp, " [%s]\n\n", title); for (j = 0; j < OPT_PAGE_PER; j++) { int opt = option_page[i][j]; if (!option_name(opt)) continue; file_putf(fp, "%-45s: %s (%s)\n", option_desc(opt), op_ptr->opt[opt] ? "yes" : "no ", option_name(opt)); } /* Skip some lines */ file_putf(fp, "\n"); } file_close(fp); /* Success */ return (0); }
/* * Let the user select an item, save its "index" * * Return TRUE only if an acceptable item was chosen by the user. * * The selected item must satisfy the "item_tester_hook()" function, * if that hook is set, and the "item_tester_tval", if that value is set. * * All "item_tester" restrictions are cleared before this function returns. * * The user is allowed to choose acceptable items from the equipment, * inventory, or floor, respectively, if the proper flag was given, * and there are any acceptable items in that location. * * The equipment or inventory 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. * * Note that the user must press "-" to specify the item on the floor, * and there is no way to "examine" the item on the floor, while the * use of "capital" letters will "examine" an inventory/equipment item, * and prompt for its use. * * If a legal item is selected from the inventory, we save it in "cp" * directly (0 to 35), and return TRUE. * * If a legal item is selected from the floor, we save it in "cp" as * a negative (-1 to -511), and return TRUE. * * If no item is available, we do nothing to "cp", and we display a * warning message, using "str" if available, and return FALSE. * * If no item is selected, we do nothing to "cp", and return FALSE. * * Global "p_ptr->command_wrk" is used to choose between equip/inven/floor * listings. It is equal to USE_INVEN or USE_EQUIP 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 get_item(int *cp, const char *pmt, const char *str, cmd_code cmd, int mode) { int py = p_ptr->py; int px = p_ptr->px; unsigned char cmdkey = cmd_lookup_key(cmd, OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG); //struct keypress which; ui_event press; int j, k; int i1, i2; int e1, e2; int f1, f2; bool done, item; bool oops = FALSE; bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE); bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE); bool use_floor = ((mode & USE_FLOOR) ? TRUE : FALSE); bool is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE); bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE); int olist_mode = 0; bool allow_inven = FALSE; bool allow_equip = FALSE; bool allow_floor = FALSE; bool toggle = FALSE; char tmp_val[160]; char out_val[160]; int floor_list[MAX_FLOOR_STACK]; int floor_num; bool show_list = TRUE; /* Hack - Only shift the command key if it actually needs to be shifted. */ if (cmdkey < 0x20) cmdkey = UN_KTRL(cmdkey); /* 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; /* Paranoia XXX XXX XXX */ message_flush(); /* Not done */ done = FALSE; /* No item selected */ item = FALSE; /* Full inventory */ i1 = 0; i2 = INVEN_PACK - 1; /* Forbid inventory */ if (!use_inven) i2 = -1; /* Restrict inventory indexes */ while ((i1 <= i2) && (!get_item_okay(i1))) i1++; while ((i1 <= i2) && (!get_item_okay(i2))) i2--; /* Accept inventory */ if (i1 <= i2) allow_inven = TRUE; /* Full equipment */ e1 = INVEN_WIELD; e2 = ALL_INVEN_TOTAL - 1; /* Forbid equipment */ if (!use_equip) e2 = -1; /* Restrict equipment indexes */ while ((e1 <= e2) && (!get_item_okay(e1))) e1++; while ((e1 <= e2) && (!get_item_okay(e2))) e2--; /* Accept equipment */ if (e1 <= e2) allow_equip = TRUE; /* Scan all non-gold objects in the grid */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x0B); /* Full floor */ f1 = 0; f2 = floor_num - 1; /* Forbid floor */ if (!use_floor) f2 = -1; /* Restrict floor indexes */ while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f1]))) f1++; while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f2]))) f2--; /* Accept floor */ if (f1 <= f2) allow_floor = TRUE; /* Require at least one legal choice */ if (!allow_inven && !allow_equip && !allow_floor) { /* Oops */ oops = TRUE; done = TRUE; } /* Analyze choices */ else { /* Hack -- Start on equipment if requested */ if ((p_ptr->command_wrk == USE_EQUIP) && allow_equip) p_ptr->command_wrk = USE_EQUIP; else if ((p_ptr->command_wrk == USE_INVEN) && allow_inven) p_ptr->command_wrk = USE_INVEN; else if ((p_ptr->command_wrk == USE_FLOOR) && allow_floor) p_ptr->command_wrk = USE_FLOOR; /* If we are using the quiver then start on equipment */ else if (quiver_tags && allow_equip) p_ptr->command_wrk = USE_EQUIP; /* Use inventory if allowed */ else if (use_inven && allow_inven) p_ptr->command_wrk = USE_INVEN; /* Use equipment if allowed */ else if (use_equip && allow_equip) p_ptr->command_wrk = USE_EQUIP; /* Use floor if allowed */ else if (use_floor && allow_floor) p_ptr->command_wrk = USE_FLOOR; /* Hack -- Use (empty) inventory */ else p_ptr->command_wrk = USE_INVEN; } /* Start out in "display" mode */ if (show_list) { /* Save screen */ screen_save(); } /* Repeat until done */ while (!done) { int ni = 0; int ne = 0; /* Scan windows */ for (j = 0; j < ANGBAND_TERM_MAX; j++) { /* Unused */ if (!angband_term[j]) continue; /* Count windows displaying inven */ if (op_ptr->window_flag[j] & (PW_INVEN)) ni++; /* Count windows displaying equip */ if (op_ptr->window_flag[j] & (PW_EQUIP)) ne++; } /* Toggle if needed */ if (((p_ptr->command_wrk == USE_EQUIP) && ni && !ne) || ((p_ptr->command_wrk == USE_INVEN) && !ni && ne)) { /* Toggle */ toggle_inven_equip(); /* Track toggles */ toggle = !toggle; } /* Redraw */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); /* Redraw windows */ redraw_stuff(p_ptr); /* Viewing inventory */ if (p_ptr->command_wrk == USE_INVEN) { int nmode = olist_mode; /* Show the quiver counts in certain cases, like the 'i' command */ if (mode & SHOW_QUIVER) nmode |= OLIST_QUIVER; /* Redraw if needed */ if (show_list) show_inven(nmode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Inven:"); /* List choices */ if (i1 <= i2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", index_to_label(i1), index_to_label(i2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Indicate legality of "toggle" */ if (use_equip) { my_strcat(out_val, " / for Equip,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate legality of the "floor" */ if (allow_floor) { my_strcat(out_val, " - for floor,", sizeof(out_val)); button_add("[-]", '-'); } } /* Viewing equipment */ else if (p_ptr->command_wrk == USE_EQUIP) { /* Redraw if needed */ if (show_list) show_equip(olist_mode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Equip:"); /* List choices */ if (e1 <= e2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", index_to_label(e1), index_to_label(e2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Indicate legality of "toggle" */ if (use_inven) { my_strcat(out_val, " / for Inven,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate legality of the "floor" */ if (allow_floor) { my_strcat(out_val, " - for floor,", sizeof(out_val)); button_add("[!]", '!'); } } /* Viewing floor */ else { /* Redraw if needed */ if (show_list) show_floor(floor_list, floor_num, olist_mode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Floor:"); /* List choices */ if (f1 <= f2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", I2A(f1), I2A(f2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Append */ if (use_inven) { my_strcat(out_val, " / for Inven,", sizeof(out_val)); button_add("[/]", '/'); } /* Append */ else if (use_equip) { my_strcat(out_val, " / for Equip,", sizeof(out_val)); button_add("[/]", '/'); } } redraw_stuff(p_ptr); /* Finish the prompt */ my_strcat(out_val, " ESC", sizeof(out_val)); /* if we have a prompt header, show the part that we just built */ if (pmt) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), "(%s) %s", out_val, pmt); /* Show the prompt */ prt(tmp_val, 0, 0); } /* Get a key */ //which = inkey(); press = inkey_m(); /* Parse it */ if (press.type == EVT_MOUSE) { if (press.mouse.button == 2) { done = TRUE; } else if (press.mouse.button == 1) { k = -1; if (p_ptr->command_wrk == USE_INVEN) { if (press.mouse.y == 0) { if (use_equip) { p_ptr->command_wrk = USE_EQUIP; } else if (allow_floor) { p_ptr->command_wrk = USE_FLOOR; } } else if ((press.mouse.y <= i2-i1+1) ){ //&& (press.mouse.x > Term->wid - 1 - max_len - ex_width)) { //k = label_to_inven(index_to_label(i1+press.mouse.y-1)); /* get the item index, allowing for skipped indices */ for (j = i1; j <= i2; j++) { if (get_item_okay(j)) { if (press.mouse.y == 1) { k = j; break; } press.mouse.y--; } } } } else if (p_ptr->command_wrk == USE_EQUIP) { if (press.mouse.y == 0) { if (allow_floor) { p_ptr->command_wrk = USE_FLOOR; } else if (use_inven) { p_ptr->command_wrk = USE_INVEN; } } else if (press.mouse.y <= e2-e1+1) { if (olist_mode & OLIST_SEMPTY) { /* If we are showing empties, just set the object (empty objects will just keep the loop going) */ k = label_to_equip(index_to_label(e1+press.mouse.y-1)); } else { /* get the item index, allowing for skipped indices */ for (j = e1; j <= e2; j++) { /* skip the quiver slot which is a blank line in the list */ if (j == 36) { press.mouse.y--; } else if (get_item_okay(j)) { if (press.mouse.y == 1) { k = j; break; } press.mouse.y--; } } } } } else if (p_ptr->command_wrk == USE_FLOOR) { if (press.mouse.y == 0) { if (use_inven) { p_ptr->command_wrk = USE_INVEN; } else if (use_equip) { p_ptr->command_wrk = USE_EQUIP; } } else if ((press.mouse.y <= floor_num) && (press.mouse.y >= 1)) { /* Special index */ k = 0 - floor_list[press.mouse.y-1]; /* get the item index, allowing for skipped indices */ for (j = f1; j <= f2; j++) { if (get_item_okay(0 - floor_list[j])) { if (press.mouse.y == 1) { k = 0 - floor_list[j]; break; } press.mouse.y--; } } /* check the bounds the item number */ if (k < 0) { /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) { done = TRUE; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; } else { /* set k to a value that will be invalid below */ k = -1; } } } if (k >= 0) { /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (normal)!"); } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) { done = TRUE; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; } else if (press.mouse.y == 0) { /* Hack -- Fix screen */ if (show_list) { /* Load screen */ screen_load(); /* Save screen */ screen_save(); } } } } else //switch (which.code) switch (press.key.code) { case ESCAPE: case ' ': { done = TRUE; break; } case '/': { /* Toggle to inventory */ if (use_inven && (p_ptr->command_wrk != USE_INVEN)) { p_ptr->command_wrk = USE_INVEN; } /* Toggle to equipment */ else if (use_equip && (p_ptr->command_wrk != USE_EQUIP)) { p_ptr->command_wrk = USE_EQUIP; } /* No toggle allowed */ else { bell("Cannot switch item selector!"); break; } /* Hack -- Fix screen */ if (show_list) { /* Load screen */ screen_load(); /* Save screen */ screen_save(); } /* Need to redraw */ break; } case '-': { /* Paranoia */ if (!allow_floor) { bell("Cannot select floor!"); break; } /* There is only one item */ if (floor_num == 1) { /* Auto-select */ if (p_ptr->command_wrk == (USE_FLOOR)) { /* Special index */ k = 0 - floor_list[0]; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } } /* Hack -- Fix screen */ if (show_list) { /* Load screen */ screen_load(); /* Save screen */ screen_save(); } p_ptr->command_wrk = (USE_FLOOR); #if 0 /* Check each legal object */ for (i = 0; i < floor_num; ++i) { /* Special index */ k = 0 - floor_list[i]; /* Skip non-okay objects */ if (!get_item_okay(k)) continue; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) continue; /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } #endif break; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* Look up the tag */ //if (!get_tag(&k, which.code, cmd, quiver_tags)) if (!get_tag(&k, press.key.code, cmd, quiver_tags)) { bell("Illegal object choice (tag)!"); break; } /* Hack -- Validate the item */ if ((k < INVEN_WIELD) ? !allow_inven : !allow_equip) { bell("Illegal object choice (tag)!"); break; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (tag)!"); break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } case KC_ENTER: { /* Choose "default" inventory item */ if (p_ptr->command_wrk == USE_INVEN) { if (i1 != i2) { bell("Illegal object choice (default)!"); break; } k = i1; } /* Choose the "default" slot (0) of the quiver */ else if (quiver_tags) k = e1; /* Choose "default" equipment item */ else if (p_ptr->command_wrk == USE_EQUIP) { if (e1 != e2) { bell("Illegal object choice (default)!"); break; } k = e1; } /* Choose "default" floor item */ else { if (f1 != f2) { bell("Illegal object choice (default)!"); break; } k = 0 - floor_list[f1]; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (default)!"); break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } default: { bool verify; /* Note verify */ //verify = (isupper((unsigned char)which.code) ? TRUE : FALSE); verify = (isupper((unsigned char)press.key.code) ? TRUE : FALSE); /* Lowercase */ //which.code = tolower((unsigned char)which.code); press.key.code = tolower((unsigned char)press.key.code); /* Convert letter to inventory index */ if (p_ptr->command_wrk == USE_INVEN) { //k = label_to_inven(which.code); k = label_to_inven(press.key.code); if (k < 0) { bell("Illegal object choice (inven)!"); break; } } /* Convert letter to equipment index */ else if (p_ptr->command_wrk == USE_EQUIP) { //k = label_to_equip(which.code); k = label_to_equip(press.key.code); if (k < 0) { bell("Illegal object choice (equip)!"); break; } } /* Convert letter to floor index */ else { //k = (islower((unsigned char)which.code) ? A2I((unsigned char)which.code) : -1); k = (islower((unsigned char)press.key.code) ? A2I((unsigned char)press.key.code) : -1); if (k < 0 || k >= floor_num) { bell("Illegal object choice (floor)!"); break; } /* Special index */ k = 0 - floor_list[k]; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (normal)!"); break; } /* Verify the item */ if (verify && !verify_item("Try", k)) { done = TRUE; break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } } } /* Fix the screen if necessary */ if (show_list) { /* Load screen */ screen_load(); /* Hack -- Cancel "display" */ show_list = FALSE; } /* Kill buttons */ button_kill('*'); button_kill('/'); button_kill('-'); button_kill('!'); redraw_stuff(p_ptr); /* Forget the item_tester_tval restriction */ item_tester_tval = 0; /* Forget the item_tester_hook restriction */ item_tester_hook = NULL; /* Toggle again if needed */ if (toggle) toggle_inven_equip(); /* Update */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); redraw_stuff(p_ptr); /* Clear the prompt line */ prt("", 0, 0); /* Warning if needed */ if (oops && str) msg("%s", str); /* Result */ return (item); }
/* * Wield or wear a single item from the pack or floor */ void do_cmd_wield(void) { int i, item, slot; object_type forge; object_type *q_ptr; object_type *o_ptr; cptr act; char o_name[MAX_NLEN]; cptr q, s; int need_switch_wielding = 0; if (p_ptr->special_defense & KATA_MUSOU) { set_action(ACTION_NONE); } /* Restrict the choices */ item_tester_hook = item_tester_hook_wear; /* Get an item */ #ifdef JP q = "どれを装備しますか? "; s = "装備可能なアイテムがない。"; #else q = "Wear/Wield which item? "; s = "You have nothing you can wear or wield."; #endif if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Check the slot */ slot = wield_slot(o_ptr); /* Ugly hack! */ if ( object_is_melee_weapon(o_ptr) && p_ptr->pclass == CLASS_PSION && psion_weapon_graft() ) { msg_print("Failed! Your weapon is currently grafted to your arm!"); return; } switch (o_ptr->tval) { /* Shields and some misc. items */ case TV_CAPTURE: case TV_SHIELD: case TV_CARD: /* Dual wielding */ if (buki_motteruka(INVEN_RARM) && buki_motteruka(INVEN_LARM)) { /* Restrict the choices */ item_tester_hook = item_tester_hook_melee_weapon; item_tester_no_ryoute = TRUE; /* Choose a weapon from the equipment only */ #ifdef JP q = "どちらの武器と取り替えますか?"; s = "おっと。"; #else q = "Replace which weapon? "; s = "Oops."; #endif if (!get_item(&slot, q, s, (USE_EQUIP))) return; if (slot == INVEN_RARM) need_switch_wielding = INVEN_LARM; } else if (buki_motteruka(INVEN_LARM)) slot = INVEN_RARM; /* Both arms are already used by non-weapon */ else if (inventory[INVEN_RARM].k_idx && !object_is_melee_weapon(&inventory[INVEN_RARM]) && inventory[INVEN_LARM].k_idx && !object_is_melee_weapon(&inventory[INVEN_LARM])) { /* Restrict the choices */ item_tester_hook = item_tester_hook_mochikae; /* Choose a hand */ #ifdef JP q = "どちらの手に装備しますか?"; s = "おっと。"; #else q = "Equip which hand? "; s = "Oops."; #endif if (!get_item(&slot, q, s, (USE_EQUIP))) return; } break; /* Melee weapons */ case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: /* Asking for dual wielding */ if (slot == INVEN_LARM) { #ifdef JP if (!get_check("二刀流で戦いますか?")) slot = INVEN_RARM; #else if (!get_check("Dual wielding? ")) slot = INVEN_RARM; #endif } else if (!inventory[INVEN_RARM].k_idx && buki_motteruka(INVEN_LARM)) { #ifdef JP if (!get_check("二刀流で戦いますか?")) slot = INVEN_LARM; #else if (!get_check("Dual wielding? ")) slot = INVEN_LARM; #endif } /* Both arms are already used */ else if (inventory[INVEN_LARM].k_idx && inventory[INVEN_RARM].k_idx) { /* Restrict the choices */ item_tester_hook = item_tester_hook_mochikae; /* Choose a hand */ #ifdef JP q = "どちらの手に装備しますか?"; s = "おっと。"; #else q = "Equip which hand? "; s = "Oops."; #endif if (!get_item(&slot, q, s, (USE_EQUIP))) return; if ((slot == INVEN_LARM) && !buki_motteruka(INVEN_RARM)) need_switch_wielding = INVEN_RARM; } break; /* Rings */ case TV_RING: /* Choose a ring slot */ if (inventory[INVEN_LEFT].k_idx && inventory[INVEN_RIGHT].k_idx) { #ifdef JP q = "どちらの指輪と取り替えますか?"; #else q = "Replace which ring? "; #endif } else { #ifdef JP q = "どちらの手に装備しますか?"; #else q = "Equip which hand? "; #endif } #ifdef JP s = "おっと。"; #else s = "Oops."; #endif /* Restrict the choices */ select_ring_slot = TRUE; item_tester_no_ryoute = TRUE; if (!get_item(&slot, q, s, (USE_EQUIP))) { select_ring_slot = FALSE; return; } select_ring_slot = FALSE; break; } /* Prevent wielding into a cursed slot */ if (object_is_cursed(&inventory[slot])) { /* Describe it */ object_desc(o_name, &inventory[slot], (OD_OMIT_PREFIX | OD_NAME_ONLY)); /* Message */ #ifdef JP msg_format("%s%sは呪われているようだ。", describe_use(slot) , o_name ); #else msg_format("The %s you are %s appears to be cursed.", o_name, describe_use(slot)); #endif /* Cancel the command */ return; } if (have_flag(inventory[slot].art_flags, TR_SIGNATURE)) { object_desc(o_name, &inventory[slot], (OD_OMIT_PREFIX | OD_NAME_ONLY)); msg_format("The %s you are %s is your signature item and may not be removed.", o_name, describe_use(slot)); return; } if (confirm_wear && ((object_is_cursed(o_ptr) && object_is_known(o_ptr)) || ((o_ptr->ident & IDENT_SENSE) && (FEEL_BROKEN <= o_ptr->feeling) && (o_ptr->feeling <= FEEL_CURSED)))) { char dummy[MAX_NLEN+80]; /* Describe it */ object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY)); #ifdef JP sprintf(dummy, "本当に%s{呪われている}を使いますか?", o_name); #else sprintf(dummy, "Really use the %s {cursed}? ", o_name); #endif if (!get_check(dummy)) return; } if ((o_ptr->name1 == ART_STONEMASK) && object_is_known(o_ptr) && (p_ptr->prace != RACE_VAMPIRE) && (p_ptr->prace != RACE_ANDROID) && (p_ptr->pclass != CLASS_BLOOD_KNIGHT)) { char dummy[MAX_NLEN+80]; /* Describe it */ object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY)); #ifdef JP sprintf(dummy, "%sを装備すると吸血鬼になります。よろしいですか?", o_name); #else msg_format("%s will transforms you into a vampire permanently when equiped.", o_name); sprintf(dummy, "Do you become a vampire?"); #endif if (!get_check(dummy)) return; } if (need_switch_wielding && !object_is_cursed(&inventory[need_switch_wielding])) { object_type *slot_o_ptr = &inventory[slot]; object_type *switch_o_ptr = &inventory[need_switch_wielding]; object_type object_tmp; object_type *otmp_ptr = &object_tmp; char switch_name[MAX_NLEN]; object_desc(switch_name, switch_o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY)); object_copy(otmp_ptr, switch_o_ptr); object_copy(switch_o_ptr, slot_o_ptr); object_copy(slot_o_ptr, otmp_ptr); #ifdef JP msg_format("%sを%sに構えなおした。", switch_name, (slot == INVEN_RARM) ? (left_hander ? "左手" : "右手") : (left_hander ? "右手" : "左手")); #else msg_format("You wield %s at %s hand.", switch_name, (slot == INVEN_RARM) ? (left_hander ? "left" : "right") : (left_hander ? "right" : "left")); #endif slot = need_switch_wielding; } /* Check if completed a quest */ for (i = 0; i < max_quests; i++) { if ((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) && (quest[i].status == QUEST_STATUS_TAKEN) && (quest[i].k_idx == o_ptr->name1 || quest[i].k_idx == o_ptr->name3)) { if (record_fix_quest) do_cmd_write_nikki(NIKKI_FIX_QUEST_C, i, NULL); quest[i].status = QUEST_STATUS_COMPLETED; quest[i].complev = (byte)p_ptr->lev; #ifdef JP msg_print("クエストを達成した!"); #else msg_print("You completed the quest!"); #endif msg_print(NULL); } } if (p_ptr->personality == PERS_MUNCHKIN) { identify_item(o_ptr); /* Auto-inscription */ autopick_alter_item(item, FALSE); } /* Take a turn */ energy_use = weaponmaster_wield_hack(o_ptr); /* Get local object */ q_ptr = &forge; /* Obtain local object */ object_copy(q_ptr, o_ptr); /* Modify quantity */ q_ptr->number = 1; /* Decrease the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -1); inven_item_optimize(item); } /* Decrease the item (from the floor) */ else { floor_item_increase(0 - item, -1); floor_item_optimize(0 - item); } /* Access the wield slot */ o_ptr = &inventory[slot]; /* Take off existing item */ if (o_ptr->k_idx) { /* Take off existing item */ (void)inven_takeoff(slot, 255); } /* Wear the new stuff */ object_copy(o_ptr, q_ptr); /* Player touches it */ o_ptr->marked |= OM_TOUCHED; /* Increase the weight */ p_ptr->total_weight += q_ptr->weight; /* Increment the equip counter by hand */ equip_cnt++; #ifdef JP #define STR_WIELD_RARM "%s(%c)を右手に装備した。" #define STR_WIELD_LARM "%s(%c)を左手に装備した。" #define STR_WIELD_ARMS "%s(%c)を両手で構えた。" #else #define STR_WIELD_RARM "You are wielding %s (%c) in your right hand." #define STR_WIELD_LARM "You are wielding %s (%c) in your left hand." #define STR_WIELD_ARMS "You are wielding %s (%c) with both hands." #endif /* Where is the item now */ switch (slot) { case INVEN_RARM: if (object_allow_two_hands_wielding(o_ptr) && (empty_hands(FALSE) == EMPTY_HAND_LARM) && CAN_TWO_HANDS_WIELDING()) act = STR_WIELD_ARMS; else act = (left_hander ? STR_WIELD_LARM : STR_WIELD_RARM); break; case INVEN_LARM: if (object_allow_two_hands_wielding(o_ptr) && (empty_hands(FALSE) == EMPTY_HAND_RARM) && CAN_TWO_HANDS_WIELDING()) act = STR_WIELD_ARMS; else act = (left_hander ? STR_WIELD_RARM : STR_WIELD_LARM); break; case INVEN_BOW: #ifdef JP act = "%s(%c)を射撃用に装備した。"; #else act = "You are shooting with %s (%c)."; #endif break; case INVEN_LITE: #ifdef JP act = "%s(%c)を光源にした。"; #else act = "Your light source is %s (%c)."; #endif break; default: #ifdef JP act = "%s(%c)を装備した。"; #else act = "You are wearing %s (%c)."; #endif break; } /* Describe the result */ object_desc(o_name, o_ptr, 0); /* Message */ msg_format(act, o_name, index_to_label(slot)); /* Cursed! */ if (object_is_cursed(o_ptr)) { /* Warn the player */ #ifdef JP msg_print("うわ! すさまじく冷たい!"); #else msg_print("Oops! It feels deathly cold!"); #endif chg_virtue(V_HARMONY, -1); /* Note the curse */ o_ptr->ident |= (IDENT_SENSE); } if (o_ptr->name1 == ART_HAND_OF_VECNA) { msg_print("You chop off your own hand to wield the Hand of Vecna!"); set_cut(CUT_MORTAL_WOUND, FALSE); } if (o_ptr->name1 == ART_EYE_OF_VECNA) { msg_print("You pluck out your own eye to wield the Eye of Vecna!"); set_cut(CUT_MORTAL_WOUND, FALSE); } /* The Stone Mask make the player turn into a vampire! */ if ((o_ptr->name1 == ART_STONEMASK) && (p_ptr->prace != RACE_VAMPIRE) && (p_ptr->prace != RACE_ANDROID) && (p_ptr->pclass != CLASS_BLOOD_KNIGHT) && (p_ptr->pclass != CLASS_BLOOD_MAGE)) { /* Turn into a vampire */ change_race(RACE_VAMPIRE, ""); } /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Recalculate torch */ p_ptr->update |= (PU_TORCH); /* Recalculate mana */ p_ptr->update |= (PU_MANA); p_ptr->redraw |= (PR_EQUIPPY); /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); calc_android_exp(); }
void prise_silmaril(void) { object_type *o_ptr; object_type *w_ptr; artefact_type *a_ptr; object_type object_type_body; cptr freed_msg = NULL; // default to soothe compiler warnings bool freed = FALSE; int slot = 0; int dam = 0; int prt = 0; int net_dam = 0; int prt_percent = 0; int hit_result = 0; int crit_bonus_dice = 0; int pd = 0; int noise = 0; u32b dummy_noticed_flag; int mds = p_ptr->mds; int attack_mod = p_ptr->skill_use[S_MEL]; char o_name[80]; // the Crown is on the ground o_ptr = &o_list[cave_o_idx[p_ptr->py][p_ptr->px]]; switch (o_ptr->name1) { case ART_MORGOTH_3: { pd = 15; noise = 5; freed_msg = "You have freed a Silmaril!"; break; } case ART_MORGOTH_2: { pd = 25; noise = 10; if (p_ptr->crown_shatter) freed_msg = "The fates be damned! You free a second Silmaril."; else freed_msg = "You free a second Silmaril."; break; } case ART_MORGOTH_1: { pd = 30; noise = 15; freed_msg = "You free the final Silmaril. You have a very bad feeling about this."; msg_print("Looking into the hallowed light of the final Silmaril, you are filled with a strange dread."); if (!get_check("Are you sure you wish to proceed? ")) return; break; } } /* Get the weapon */ w_ptr = &inventory[INVEN_WIELD]; // undo rapid attack penalties if (p_ptr->active_ability[S_MEL][MEL_RAPID_ATTACK]) { // undo strength adjustment to the attack mds = total_mds(w_ptr, 0); // undo the dexterity adjustment to the attack attack_mod += 3; } /* Test for hit */ hit_result = hit_roll(attack_mod, 0, PLAYER, NULL, TRUE); /* Make some noise */ stealth_score -= noise; // Determine damage if (hit_result > 0) { crit_bonus_dice = crit_bonus(hit_result, w_ptr->weight, &r_info[R_IDX_MORGOTH], S_MEL, FALSE); dam = damroll(p_ptr->mdd + crit_bonus_dice, mds); prt = damroll(pd, 4); prt_percent = prt_after_sharpness(w_ptr, &dummy_noticed_flag); prt = (prt * prt_percent) / 100; net_dam = dam - prt; /* No negative damage */ if (net_dam < 0) net_dam = 0; //update_combat_rolls1b(PLAYER, TRUE); update_combat_rolls2(p_ptr->mdd + crit_bonus_dice, mds, dam, pd, 4, prt, prt_percent, GF_HURT, TRUE); } // if you succeed in prising out a Silmaril... if (net_dam > 0) { freed = TRUE; switch (o_ptr->name1) { case ART_MORGOTH_3: { break; } case ART_MORGOTH_2: { if (!p_ptr->crown_shatter && one_in_(2)) { shatter_weapon(2); freed = FALSE; } break; } case ART_MORGOTH_1: { if (!p_ptr->crown_shatter) { shatter_weapon(3); freed = FALSE; } else { p_ptr->cursed = TRUE; } break; } } if (freed) { // change its type to that of the crown with one less silmaril o_ptr->name1--; // get the details of this new crown a_ptr = &a_info[o_ptr->name1]; // modify the existing crown object_into_artefact(o_ptr, a_ptr); // report success msg_print(freed_msg); // Get new local object o_ptr = &object_type_body; // Make Silmaril object_prep(o_ptr, lookup_kind(TV_LIGHT, SV_LIGHT_SILMARIL)); // Get it slot = inven_carry(o_ptr); /* Get the object again */ o_ptr = &inventory[slot]; /* Describe the object */ object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); /* Message */ msg_format("You have %s (%c).", o_name, index_to_label(slot)); // Break the truce (always) break_truce(TRUE); // add a note to the notes file do_cmd_note("Cut a Silmaril from Morgoth's crown", p_ptr->depth); } } // if you fail to prise out a Silmaril... else { msg_print("Try though you might, you were unable to free a Silmaril."); msg_print("Perhaps you should try again or use a different weapon."); if (pd == 15) msg_print("(The combat rolls window shows what is happening.)"); // Break the truce if creatures see break_truce(FALSE); } // check for taking of final Silmaril if ((pd == 30) && freed) { msg_print("Until you escape you must now roll twice for every skill check, taking the worse result each time."); msg_print("You hear a cry of veangance echo through the iron hells."); wake_all_monsters(0); } }
/* * 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(int num_obj, int num_head, char labels[50][80], object_type *objects[50], olist_detail_t mode) { int i, row = 0, col = 0; int attr; size_t max_len = 0; int ex_width = 0, ex_offset, ex_offset_ctr; object_type *o_ptr; char o_name[50][80]; char tmp_val[80]; bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; bool terse = FALSE; if (in_term) max_len = 40; if (in_term && Term->wid < 40) mode &= ~(OLIST_WEIGHT); if (Term->wid < 50) terse = TRUE; /* Calculate name offset and max name length */ for (i = 0; i < num_obj; i++) { o_ptr = objects[i]; /* Null objects are used to skip lines, or display only a label */ if (!o_ptr || !o_ptr->kind) { if (i < num_head) strnfmt(o_name[i], sizeof(o_name[i]), ""); else strnfmt(o_name[i], sizeof(o_name[i]), "(nothing)"); } else object_desc(o_name[i], sizeof(o_name[i]), o_ptr, ODESC_PREFIX | ODESC_FULL | (terse ? ODESC_TERSE : 0)); /* Max length of label + object name */ max_len = MAX(max_len, strlen(labels[i]) + strlen(o_name[i])); } /* Take the quiver message into consideration */ if (mode & OLIST_QUIVER && p_ptr->quiver_slots > 0) 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++) { o_ptr = objects[i]; /* Clear the line */ prt("", row + i, MAX(col - 2, 0)); /* If we have no label then we won't display anything */ if (!strlen(labels[i])) continue; /* Print the label */ put_str(labels[i], row + i, col); /* Limit object name */ if (strlen(labels[i]) + strlen(o_name[i]) > (size_t)ex_offset) { int truncate = ex_offset - strlen(labels[i]); if (truncate < 0) truncate = 0; if ((size_t)truncate > sizeof(o_name[i]) - 1) truncate = sizeof(o_name[i]) - 1; o_name[i][truncate] = '\0'; } /* Item kind determines the color of the output */ if (o_ptr && o_ptr->kind) attr = tval_to_attr[o_ptr->tval % N_ELEMENTS(tval_to_attr)]; else attr = TERM_SLATE; /* Object name */ c_put_str(attr, o_name[i], row + i, col + strlen(labels[i])); /* If we don't have an object, we can skip the rest of the output */ if (!(o_ptr && o_ptr->kind)) continue; /* Extra fields */ ex_offset_ctr = ex_offset; if (mode & OLIST_PRICE) { int price = price_item(o_ptr, TRUE, o_ptr->number); strnfmt(tmp_val, sizeof(tmp_val), "%6d au", price); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 9; } if (mode & OLIST_FAIL && obj_can_fail(o_ptr)) { int fail = (9 + get_use_device_chance(o_ptr)) / 10; if (object_effect_is_known(o_ptr)) strnfmt(tmp_val, sizeof(tmp_val), "%4d%% fail", fail); else my_strcpy(tmp_val, " ? fail", sizeof(tmp_val)); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 10; } if (mode & OLIST_WEIGHT) { int weight = o_ptr->weight * o_ptr->number; strnfmt(tmp_val, sizeof(tmp_val), "%4d.%1d lb", weight / 10, weight % 10); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 9; } } /* For the inventory: print the quiver count */ if (mode & OLIST_QUIVER) { int count, j; /* Quiver may take multiple lines */ for(j = 0; j < p_ptr->quiver_slots; j++, i++) { const char *fmt = "in Quiver: %d missile%s"; char letter = index_to_label(in_term ? i - 1 : i); /* Number of missiles in this "slot" */ if (j == p_ptr->quiver_slots - 1 && p_ptr->quiver_remainder > 0) count = p_ptr->quiver_remainder; else count = MAX_STACK_SIZE-1; /* 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(TERM_SLATE, tmp_val, row + i, col); /* Print the count */ strnfmt(tmp_val, sizeof(tmp_val), fmt, count, count == 1 ? "" : "s"); c_put_str(TERM_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)); } } /* Print a drop shadow for the main window if necessary */ else if (i > 0 && row + i < 24) { prt("", row + i, MAX(col - 2, 0)); } }
/* * Wield or wear a single item from the pack or floor */ void do_cmd_wield(object_type *default_o_ptr, int default_item) { int item, slot; object_type *o_ptr; object_type *i_ptr; object_type object_type_body; cptr act; cptr q, s; int i, quantity, original_quantity; bool weapon_less_effective = FALSE; bool grants_two_weapon = FALSE; char o_name[80]; bool combine = FALSE; // use specified item if possible if (default_o_ptr != NULL) { o_ptr = default_o_ptr; item = default_item; } /* Get an item */ else { /* Restrict the choices */ item_tester_hook = item_tester_hook_wear; /* Get an item */ q = "Wear/Wield which item? "; s = "You have nothing you can wear or wield."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } else { o_ptr = &o_list[0 - item]; } } // remember how many there were original_quantity = o_ptr->number; // Check whether it would be too heavy if ((item < 0) && (p_ptr->total_weight + o_ptr->weight > weight_limit()*3/2)) { /* Describe it */ object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); if (o_ptr->k_idx) msg_format("You cannot lift %s.", o_name); /* Abort */ return; } /* Check the slot */ slot = wield_slot(o_ptr); /* Ask for ring to replace */ if ((o_ptr->tval == TV_RING) && inventory[INVEN_LEFT].k_idx && inventory[INVEN_RIGHT].k_idx) { /* Restrict the choices */ item_tester_tval = TV_RING; /* Choose a ring from the equipment only */ q = "Replace which ring? "; s = "Oops."; if (!get_item(&slot, q, s, USE_EQUIP)) return; } // Special cases for merging arrows if (object_similar(&inventory[INVEN_QUIVER1], o_ptr)) { slot = INVEN_QUIVER1; combine = TRUE; } else if (object_similar(&inventory[INVEN_QUIVER2], o_ptr)) { slot = INVEN_QUIVER2; combine = TRUE; } /* Ask for arrow set to replace */ else if ((o_ptr->tval == TV_ARROW) && inventory[INVEN_QUIVER1].k_idx && inventory[INVEN_QUIVER2].k_idx) { /* Restrict the choices */ item_tester_tval = TV_ARROW; /* Choose a set of arrows from the equipment only */ q = "Replace which set of arrows? "; s = "Oops."; if (!get_item(&slot, q, s, USE_EQUIP)) return; } // Ask about two weapon fighting if necessary for (i = 0; i < o_ptr->abilities; i++) { if ((o_ptr->skilltype[i] == S_MEL) && (o_ptr->abilitynum[i] == MEL_TWO_WEAPON) && object_known_p(o_ptr)) { grants_two_weapon = TRUE; } } if ((p_ptr->active_ability[S_MEL][MEL_TWO_WEAPON] || grants_two_weapon) && ((o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM) || (o_ptr->tval == TV_HAFTED) || (o_ptr->tval == TV_DIGGING))) { if (!(k_info[o_ptr->k_idx].flags3 & (TR3_TWO_HANDED))) { if (get_check("Do you wish to wield it in your off-hand? ")) { slot = INVEN_ARM; } } } /* Prevent wielding into a cursed slot */ if (cursed_p(&inventory[slot])) { /* Describe it */ object_desc(o_name, sizeof(o_name), &inventory[slot], FALSE, 0); /* Message */ msg_format("The %s you are %s appears to be cursed.", o_name, describe_use(slot)); /* Cancel the command */ return; } /* Deal with wielding of two-handed weapons when already using a shield */ if ((k_info[o_ptr->k_idx].flags3 & (TR3_TWO_HANDED)) && (inventory[INVEN_ARM].k_idx)) { if (cursed_p(&inventory[INVEN_ARM])) { if (inventory[INVEN_ARM].tval == TV_SHIELD) { msg_print("You would need to remove your shield, but it appears to be cursed."); } else { msg_print("You would need to put down your off-hand weapon, but it appears to be cursed."); } /* Cancel the command */ return; } // warn about dropping item in left hand if ((item < 0) && (&inventory[INVEN_PACK-1])->tval) { /* Flush input */ flush(); if (inventory[INVEN_ARM].tval == TV_SHIELD) { if (!get_check("This would require removing (and dropping) your shield. Proceed? ")) { /* Cancel the command */ return; } } else { msg_print("This would require removing (and dropping) your off-hand weapon."); if (!get_check("Proceed? ")) { /* Cancel the command */ return; } } } } /* Deal with wielding of shield or second weapon when already wielding a two handed weapon */ if ((slot == INVEN_ARM) && (k_info[inventory[INVEN_WIELD].k_idx].flags3 & (TR3_TWO_HANDED))) { if (cursed_p(&inventory[INVEN_WIELD])) { msg_print("You would need to put down your weapon, but it appears to be cursed."); /* Cancel the command */ return; } // warn about dropping item in left hand if ((item < 0) && (&inventory[INVEN_PACK-1])->tval) { /* Flush input */ flush(); if (inventory[INVEN_ARM].tval == TV_SHIELD) { if (!get_check("This would require removing (and dropping) your weapon. Proceed? ")) { /* Cancel the command */ return; } } else { msg_print("This would require removing (and dropping) your weapon."); if (!get_check("Proceed? ")) { /* Cancel the command */ return; } } } } /* Deal with wielding of shield or second weapon when already wielding a hand and a half weapon */ if ((slot == INVEN_ARM) && (k_info[inventory[INVEN_WIELD].k_idx].flags3 & (TR3_HAND_AND_A_HALF)) && (!inventory[INVEN_ARM].k_idx)) { weapon_less_effective = TRUE; } /* Take a turn */ p_ptr->energy_use = 100; // store the action type p_ptr->previous_action[0] = ACTION_MISC; /* Get local object */ i_ptr = &object_type_body; /* Obtain local object */ object_copy(i_ptr, o_ptr); // Handle quantity differently for arrows if (i_ptr->tval == TV_ARROW) { if (combine) quantity = MIN(o_ptr->number, MAX_STACK_SIZE - 1 - (&inventory[slot])->number); else quantity = o_ptr->number; } else { quantity = 1; } /* Modify quantity */ i_ptr->number = quantity; /* Decrease the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -quantity); inven_item_optimize(item); } /* Decrease the item (from the floor) */ else { floor_item_increase(0 - item, -quantity); floor_item_optimize(0 - item); } /* Get the wield slot */ o_ptr = &inventory[slot]; /* Take off existing item */ if (o_ptr->k_idx && !combine) { /* Take off existing item */ (void)inven_takeoff(slot, 255); } /* Deal with wielding of two-handed weapons when already using a shield */ if ((k_info[i_ptr->k_idx].flags3 & (TR3_TWO_HANDED)) && (inventory[INVEN_ARM].k_idx)) { /* Take off shield */ check_pack_overflow(); (void)inven_takeoff(INVEN_ARM, 255); } /* Deal with wielding of shield or second weapon when already wielding a two handed weapon */ if ((slot == INVEN_ARM) && (k_info[inventory[INVEN_WIELD].k_idx].flags3 & (TR3_TWO_HANDED))) { /* Stop wielding two handed weapon */ (void)inven_takeoff(INVEN_WIELD, 255); } /* Combine the new stuff into the equipment */ if (combine) { msg_print("You combine them with some that are already in your quiver."); object_absorb(o_ptr, i_ptr); } /* Wear the new stuff */ else { object_copy(o_ptr, i_ptr); } /* Increment the equip counter by hand */ if (!combine) p_ptr->equip_cnt++; /* Where is the item now */ if ((slot == INVEN_WIELD) || ((slot == INVEN_ARM) && (o_ptr->tval != TV_SHIELD))) { act = "You are wielding"; } else if (slot == INVEN_BOW) { act = "You are shooting with"; } else if (slot == INVEN_LITE) { act = "Your light source is"; } else if ((slot == INVEN_QUIVER1) || (slot == INVEN_QUIVER2)) { act = "In your quiver you have"; } else { act = "You are wearing"; } /* Describe the result */ object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); /* Message */ msg_format("%s %s (%c).", act, o_name, index_to_label(slot)); // Deal with wielding from the floor if (item < 0) { /* Forget monster */ o_ptr->held_m_idx = 0; /* Forget location */ o_ptr->iy = o_ptr->ix = 0; // Break the truce if picking up an item from the floor break_truce(FALSE); // Special effects when picking up all the items from the floor if (i_ptr->number == original_quantity) { /* No longer marked */ o_ptr->marked = FALSE; } } /* Cursed! */ if (cursed_p(o_ptr)) { /* Warn the player */ msg_print("You have a very bad feeling about this..."); /* Remove special inscription, if any */ if (o_ptr->discount >= INSCRIP_NULL) o_ptr->discount = 0; /* Sense the object if allowed */ if (o_ptr->discount == 0) o_ptr->discount = INSCRIP_CURSED; /* The object has been "sensed" */ o_ptr->ident |= (IDENT_SENSE); } if (weapon_less_effective) { /* Describe it */ object_desc(o_name, sizeof(o_name), &inventory[INVEN_WIELD], FALSE, 0); /* Message */ msg_format("You are no longer able to wield your %s as effectively.", o_name); } ident_on_wield(o_ptr); // activate all of its new abilities for (i = 0; i < o_ptr->abilities; i++) { if (!p_ptr->have_ability[o_ptr->skilltype[i]][o_ptr->abilitynum[i]]) { p_ptr->have_ability[o_ptr->skilltype[i]][o_ptr->abilitynum[i]] = TRUE; p_ptr->active_ability[o_ptr->skilltype[i]][o_ptr->abilitynum[i]] = TRUE; } } /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Recalculate mana */ p_ptr->update |= (PU_MANA); /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0); p_ptr->redraw |= (PR_EQUIPPY | PR_RESIST); }
/* * Hack -- Dump a character description file * * XXX XXX XXX Allow the "full" flag to dump additional info, * and trigger its usage from various places in the code. */ errr file_character(const char *path, bool full) { int i, x, y; byte a; char c; ang_file *fp; struct store *st_ptr = &stores[STORE_HOME]; char o_name[80]; byte (*old_xchar_hook)(byte c) = Term.xchar_hook; char buf[1024]; /* We use either ascii or system-specific encoding */ int encoding = OPT(xchars_to_file) ? SYSTEM_SPECIFIC : ASCII; /* Unused parameter */ (void)full; /* Open the file for writing */ fp = file_open(path, MODE_WRITE, FTYPE_TEXT); if (!fp) return (-1); /* Display the requested encoding -- ASCII or system-specific */ if (!OPT(xchars_to_file)) Term.xchar_hook = null; /* Begin dump */ file_putf(fp, " [%s Character Dump]\n\n", buildid); /* Display player */ display_player(0); /* Dump part of the screen */ for (y = 1; y < 23; y++) { /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; } /* Back up over spaces */ while ((x > 0) && (buf[x-1] == ' ')) --x; /* Terminate */ buf[x] = '\0'; /* End the row */ x_file_putf(fp, encoding, "%s\n", buf); } /* Skip a line */ file_putf(fp, "\n"); /* Display player */ display_player(1); /* Dump part of the screen */ for (y = 11; y < 20; y++) { /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; } /* Back up over spaces */ while ((x > 0) && (buf[x-1] == ' ')) --x; /* Terminate */ buf[x] = '\0'; /* End the row */ x_file_putf(fp, encoding, "%s\n", buf); } /* Skip a line */ file_putf(fp, "\n"); /* Dump part of the screen */ for (y = 11; y < 20; y++) { /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x + 40, y, &a, &c)); /* Dump it */ buf[x] = c; } /* Back up over spaces */ while ((x > 0) && (buf[x-1] == ' ')) --x; /* Terminate */ buf[x] = '\0'; /* End the row */ x_file_putf(fp, encoding, "%s\n", buf); } /* Skip some lines */ file_putf(fp, "\n\n"); /* If dead, dump last messages -- Prfnoff */ if (p_ptr.is_dead) { i = messages_num(); if (i > 15) i = 15; file_putf(fp, " [Last Messages]\n\n"); while (i-- > 0) { x_file_putf(fp, encoding, "> %s\n", message_str((s16b)i)); } x_file_putf(fp, encoding, "\nKilled by %s.\n\n", p_ptr.died_from); } /* Dump the equipment */ file_putf(fp, " [Character Equipment]\n\n"); for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++) { if (i == INVEN_TOTAL) { file_putf(fp, "\n\n [Character Quiver]\n\n"); continue; } object_desc(o_name, sizeof(o_name), &p_ptr.inventory[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, encoding, "%c) %s\n", index_to_label(i), o_name); if (p_ptr.inventory[i].kind) object_info_chardump(fp, &p_ptr.inventory[i], 5, 72); } /* Dump the inventory */ file_putf(fp, "\n\n [Character Inventory]\n\n"); for (i = 0; i < INVEN_PACK; i++) { if (!p_ptr.inventory[i].kind) break; object_desc(o_name, sizeof(o_name), &p_ptr.inventory[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, encoding, "%c) %s\n", index_to_label(i), o_name); object_info_chardump(fp, &p_ptr.inventory[i], 5, 72); } file_putf(fp, "\n\n"); /* Dump the Home -- if anything there */ if (st_ptr.stock_num) { /* Header */ file_putf(fp, " [Home Inventory]\n\n"); /* Dump all available items */ for (i = 0; i < st_ptr.stock_num; i++) { object_desc(o_name, sizeof(o_name), &st_ptr.stock[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, encoding, "%c) %s\n", I2A(i), o_name); object_info_chardump(fp, &st_ptr.stock[i], 5, 72); } /* Add an empty line */ file_putf(fp, "\n\n"); } /* Dump character history */ dump_history(fp); file_putf(fp, "\n\n"); /* Dump options */ file_putf(fp, " [Options]\n\n"); /* Dump options */ for (i = OPT_BIRTH; i < OPT_BIRTH + N_OPTS_BIRTH; i++) { if (option_name(i)) { file_putf(fp, "%-45s: %s (%s)\n", option_desc(i), op_ptr.opt[i] ? "yes" : "no ", option_name(i)); } } /* Skip some lines */ file_putf(fp, "\n\n"); /* Return to standard display */ Term.xchar_hook = old_xchar_hook; file_close(fp); /* Success */ return (0); }
/** * Make the correct prompt for items, handle mouse buttons */ void item_prompt(int mode) { char tmp_val[160]; char out_val[160]; bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE); bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE); bool can_squelch = ((mode & CAN_SQUELCH) && !show_list ? TRUE : FALSE); bool allow_floor = (f1 <= f2); /* Viewing inventory */ if (p_ptr->command_wrk == USE_INVEN) { /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Inven:"); /* List choices */ if (i1 <= i2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", index_to_label(i1), index_to_label(i2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Indicate legality of "toggle" */ if (use_equip) { my_strcat(out_val, " / for Equip,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate legality of the "floor" */ if (allow_floor) { my_strcat(out_val, " - for floor,", sizeof(out_val)); button_add("[-]", '-'); } /* Indicate that squelched items can be selected */ if (can_squelch) { my_strcat(out_val, " ! for squelched,", sizeof(out_val)); button_add("[!]", '!'); } } /* Viewing equipment */ else if (p_ptr->command_wrk == USE_EQUIP) { /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Equip:"); /* List choices */ if (e1 <= e2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", index_to_label(e1), index_to_label(e2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Indicate legality of "toggle" */ if (use_inven) { my_strcat(out_val, " / for Inven,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate legality of the "floor" */ if (allow_floor) { my_strcat(out_val, " - for floor,", sizeof(out_val)); button_add("[!]", '!'); } } /* Viewing floor */ else { /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Floor:"); /* List choices */ if (f1 <= f2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", I2A(f1), I2A(f2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Append */ if (use_inven) { my_strcat(out_val, " / for Inven,", sizeof(out_val)); button_add("[/]", '/'); } /* Append */ else if (use_equip) { my_strcat(out_val, " / for Equip,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate that squelched items can be selected */ if (can_squelch) { my_strcat(out_val, " ! for squelched,", sizeof(out_val)); button_add("[!]", '!'); } } /* Finish the prompt */ my_strcat(out_val, " ESC", sizeof(out_val)); /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), "(%s) %s", out_val, prompt); /* Show the prompt */ prt(tmp_val, 0, 0); }
/* * 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(int num_obj, u32b display, olist_detail_t mode) { int i, row = 0, col = 0, sp = 0; size_t max_len = Term->wid - 1; int ex_width = 0; object_type *o_ptr; char tmp_val[80]; bool in_term; in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; get_max_len(&max_len); /* Check for window size restrictions */ if (in_term) { /* Scan windows */ for (i = 0; i < ANGBAND_TERM_MAX; i++) { /* Unused */ if (!angband_term[i]) continue; /* Count windows displaying inven */ if (op_ptr->window_flag[i] & display) max_len = MIN(max_len, angband_term[i]->wid); } } /* 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; col = MIN(col, 20); if (col < 3) col = 0; } /* Output the list */ for (i = 0; i < num_obj; i++) { o_ptr = items[i].object; /* Display each line */ show_obj(i + sp, max_len, items[i].label, o_ptr, FALSE, mode); if ((i == (INVEN_FEET - INVEN_WIELD)) && need_spacer) { sp = 1; prt("", i + sp + 1, MAX(col - 2, 0)); } } /* For the inventory: print the quiver count */ if (mode & OLIST_QUIVER) { int count, j; /* Adjust for subwindow */ int skip = (in_term) ? 1 : 0; /* Quiver may take multiple lines */ for(j = 0; j < p_ptr->quiver_slots; j++, i++) { /* Number of missiles in this "slot" */ if (j == p_ptr->quiver_slots - 1 && p_ptr->quiver_remainder > 0) count = p_ptr->quiver_remainder; else count = 99; /* Clear the line */ prt("", row + i + skip, MAX(col - 2, 0)); /* Print the (disabled) label */ strnfmt(tmp_val, sizeof(tmp_val), "%c) ", index_to_label(i)); c_put_str(TERM_SLATE, tmp_val, row + i + skip, col); /* Print the count */ strnfmt(tmp_val, sizeof(tmp_val), "in Quiver: %d missile%s", count, count == 1 ? "" : "s"); c_put_str(TERM_L_UMBER, tmp_val, row + i + skip, col + 3); } } /* Clear term windows */ if (in_term) { for (; i < Term->hgt; i++) { prt("", row + i + offset + sp, MAX(col - 2, 0)); } } /* Print a drop shadow for the main window if necessary */ else if (i > 0 && row + i < 24) { prt("", row + i + sp, MAX(col - 2, 0)); } }
/* * Build the object list. Note that only the equipment has first non-zero. */ static void build_obj_list(int first, int last, const int *floor_list, olist_detail_t mode) { int i; object_type *o_ptr; bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; need_spacer = FALSE; offset = 0; num_obj = 0; /* Clear the existing contents */ for (i = 0; i < 50; i++) { items[i].object = NULL; items[i].index = 0; items[i].key = '\0'; my_strcpy(items[i].label, "", sizeof(items[i].label)); } /* Leave top line clear for inventory subwindow */ if (!first && !floor_list && in_term) offset = 1; for (i = first; i <= last; i++) { if (floor_list) o_ptr = &o_list[floor_list[i]]; else o_ptr = &p_ptr->inventory[i]; /* May need a blank line to separate equipment and quiver */ if ((i == INVEN_TOTAL) && (first)) { int j; /* Scan the rest of the items for acceptable entries */ for (j = i; j <= last; j++) { o_ptr = &p_ptr->inventory[j]; if (item_tester_okay(o_ptr) || in_term) need_spacer = TRUE; } continue; } /* Tester always skips gold. When gold should be displayed, * only test items that are not gold. */ if (((o_ptr->tval == TV_GOLD) && (mode & OLIST_GOLD)) || item_tester_okay(o_ptr)) strnfmt(items[num_obj].label, sizeof(items[num_obj].label), "%c) ", index_to_label(i)); /* Unacceptable carried items are still displayed in term windows */ else if ((in_term) && (!floor_list)) my_strcpy(items[num_obj].label, " ", sizeof(items[num_obj].label)); /* Unacceptable items are skipped in the main window */ else continue; /* Special labels for equipment */ if (first){ char tmp_val[80]; /* Show full slot labels */ if (OPT(show_labels)) { strnfmt(tmp_val, sizeof(tmp_val), "%-14s: ", mention_use(i)); my_strcat(items[num_obj].label, tmp_val, sizeof(items[num_obj].label)); } /* Otherwise only show short quiver labels */ else if (i >= QUIVER_START) { strnfmt(tmp_val, sizeof(tmp_val), "[f%d]: ", i - QUIVER_START); my_strcat(items[num_obj].label, tmp_val, sizeof(items[num_obj].label)); } } /* Save the object */ items[num_obj].object = o_ptr; items[num_obj].index = i; items[num_obj].key = (items[num_obj].label)[0]; num_obj++; } }
/* * Display the equipment. Builds a list of objects and passes them * off to show_obj_list() for display. Mode flags documented in * object.h */ void show_equip(olist_detail_t mode) { int i, last_slot = 0; object_type *o_ptr; int num_obj = 0; char labels[50][80]; object_type *objects[50]; char tmp_val[80]; bool in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; /* Find the last equipment slot to display */ for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++) { o_ptr = &p_ptr->inventory[i]; if (i < INVEN_TOTAL || o_ptr->k_idx) last_slot = i; } /* Build the object list */ for (i = INVEN_WIELD; i <= last_slot; i++) { if (((i >= INVEN_WIELD) && (i < (INVEN_WIELD + rp_ptr->melee_slots))) || ((i >= INVEN_BOW) && (i < (INVEN_BOW + rp_ptr->range_slots))) || ((i >= INVEN_FINGER) && (i < (INVEN_FINGER + rp_ptr->ring_slots))) || ((i >= INVEN_NECK) && (i < (INVEN_NECK + rp_ptr->amulet_slots))) || ((i >= INVEN_LIGHT) && (i < (INVEN_LIGHT + rp_ptr->light_slots))) || ((i >= INVEN_BODY) && (i < (INVEN_BODY + rp_ptr->body_slots))) || ((i >= INVEN_OUTER) && (i < (INVEN_OUTER + rp_ptr->cloak_slots))) || ((i >= INVEN_ARM) && (i < (INVEN_ARM + rp_ptr->shield_slots))) || ((i >= INVEN_HEAD) && (i < (INVEN_HEAD + rp_ptr->helm_slots))) || ((i >= INVEN_HANDS) && (i < (INVEN_HANDS + rp_ptr->glove_slots))) || ((i >= INVEN_FEET) && (i < (INVEN_FEET + rp_ptr->boot_slots)))) { o_ptr = &p_ptr->inventory[i]; /* May need a blank line to separate the quiver */ if (i == INVEN_TOTAL) { int j; bool need_spacer = FALSE; /* Scan the rest of the items for acceptable entries */ for (j = i; j < last_slot; j++) { o_ptr = &p_ptr->inventory[j]; if (item_tester_okay(o_ptr)) need_spacer = TRUE; } /* Add a spacer between equipment and quiver */ if (num_obj > 0 && need_spacer) { my_strcpy(labels[num_obj], "", sizeof(labels[num_obj])); objects[num_obj] = NULL; num_obj++; } continue; } /* Acceptable items get a label */ //if (item_tester_okay(o_ptr)) strnfmt(labels[num_obj], sizeof(labels[num_obj]), "%c) ", index_to_label(num_obj)); /* Unacceptable items are still displayed in term windows */ //else if (in_term) // my_strcpy(labels[num_obj], " ", sizeof(labels[num_obj])); /* Unacceptable items are skipped in the main window */ //else continue; /* Show full slot labels */ if (TRUE)//OPT(show_labels)) { strnfmt(tmp_val, sizeof(tmp_val), "%-14s: ", mention_use(i)); my_strcat(labels[num_obj], tmp_val, sizeof(labels[num_obj])); } /* Otherwise only show short quiver labels */ else if (i >= QUIVER_START) { strnfmt(tmp_val, sizeof(tmp_val), "[f%d]: ", i - QUIVER_START); my_strcat(labels[num_obj], tmp_val, sizeof(labels[num_obj])); } /* Save the object */ objects[num_obj] = o_ptr; num_obj++; } } /* Display the object list */ show_obj_list(num_obj, labels, objects, mode); }
/* * 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(int num_obj, char labels[50][80], object_type *objects[50], olist_detail_t mode) { int i, row = 0, col = 0; size_t max_len = 0; int ex_width = 0, ex_offset, ex_offset_ctr; object_type *o_ptr; char o_name[50][80]; char tmp_val[80]; bool in_term; in_term = (mode & OLIST_WINDOW) ? TRUE : FALSE; if (in_term) max_len = 40; /* Calculate name offset and max name length */ for (i = 0; i < num_obj; i++) { o_ptr = objects[i]; /* Null objects are used to skip lines, or display only a label */ if (o_ptr == NULL) continue; /* Max length of label + object name */ object_desc(o_name[i], sizeof(o_name[i]), o_ptr, ODESC_PREFIX | ODESC_FULL); max_len = MAX(max_len, strlen(labels[i]) + strlen(o_name[i])); } /* 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++) { o_ptr = objects[i]; /* Clear the line */ prt("", row + i, MAX(col - 2, 0)); /* Print the label */ put_str(labels[i], row + i, col); /* Print the object */ if (o_ptr != NULL) { /* Limit object name */ if (strlen(labels[i]) + strlen(o_name[i]) > (size_t)ex_offset) { int truncate = ex_offset - strlen(labels[i]); if (truncate < 0) truncate = 0; if ((size_t)truncate > sizeof(o_name[i]) - 1) truncate = sizeof(o_name[i]) - 1; o_name[i][truncate] = '\0'; } /* Object name */ c_put_str(tval_to_attr[o_ptr->tval % N_ELEMENTS(tval_to_attr)], o_name[i], row + i, col + strlen(labels[i])); /* Extra fields */ ex_offset_ctr = ex_offset; if (mode & OLIST_PRICE) { int price = price_item(o_ptr, TRUE, o_ptr->number); strnfmt(tmp_val, sizeof(tmp_val), "%6d au", price); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 9; } if (mode & OLIST_FAIL) { int fail = (9 + get_use_device_chance(o_ptr)) / 10; if (object_effect_is_known(o_ptr)) strnfmt(tmp_val, sizeof(tmp_val), "%4d%% fail", fail); else my_strcpy(tmp_val, " ? fail", sizeof(tmp_val)); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 10; } if (mode & OLIST_WEIGHT) { int weight = o_ptr->weight * o_ptr->number; strnfmt(tmp_val, sizeof(tmp_val), "%4d.%1d lb", weight / 10, weight % 10); put_str(tmp_val, row + i, col + ex_offset_ctr); ex_offset_ctr += 9; } } } /* For the inventory: print the quiver count */ if (mode & OLIST_QUIVER) { int count, j; /* Quiver may take multiple lines */ for(j = 0; j < p_ptr->quiver_slots; j++, i++) { /* Number of missiles in this "slot" */ if (j == p_ptr->quiver_slots - 1 && p_ptr->quiver_remainder > 0) count = p_ptr->quiver_remainder; else count = 99; /* Clear the line */ prt("", row + i, MAX(col - 2, 0)); /* Print the (disabled) label */ strnfmt(tmp_val, sizeof(tmp_val), "%c) ", index_to_label(i)); c_put_str(TERM_SLATE, tmp_val, row + i, col); /* Print the count */ strnfmt(tmp_val, sizeof(tmp_val), "in Quiver: %d missile%s", count, count == 1 ? "" : "s"); c_put_str(TERM_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)); } } /* Print a drop shadow for the main window if necessary */ else if (i > 0 && row + i < 24) { prt("", row + i, MAX(col - 2, 0)); } }
/* * Wield or wear a single item from the pack or floor */ void do_cmd_wield(void) { int item, slot; object_type *o_ptr; object_type *i_ptr; object_type object_type_body; cptr act; cptr q, s; char o_name[80]; /* Restrict the choices */ item_tester_hook = item_tester_hook_wear; /* Get an item */ q = "Wear/Wield which item? "; s = "You have nothing you can wear or wield."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Check the slot */ slot = wield_slot(o_ptr); /* Prevent wielding into a cursed slot */ if (cursed_p(&inventory[slot])) { /* Describe it */ object_desc(o_name, &inventory[slot], FALSE, 0); /* Message */ msg_format("The %s you are %s appears to be cursed.", o_name, describe_use(slot)); /* Cancel the command */ return; } /* Take a turn */ p_ptr->energy_use = 100; /* Get local object */ i_ptr = &object_type_body; /* Obtain local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Decrease the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -1); inven_item_optimize(item); } /* Decrease the item (from the floor) */ else { floor_item_increase(0 - item, -1); floor_item_optimize(0 - item); } /* Get the wield slot */ o_ptr = &inventory[slot]; /* Take off existing item */ if (o_ptr->k_idx) { /* Take off existing item */ (void)inven_takeoff(slot, 255); } /* Wear the new stuff */ object_copy(o_ptr, i_ptr); /* Increase the weight */ p_ptr->total_weight += i_ptr->weight; /* Increment the equip counter by hand */ p_ptr->equip_cnt++; /* Where is the item now */ if (slot == INVEN_WIELD) { act = "You are wielding"; } else if (slot == INVEN_BOW) { act = "You are shooting with"; } else if (slot == INVEN_LIGHT) { act = "Your light source is"; } else { act = "You are wearing"; } /* Describe the result */ object_desc(o_name, o_ptr, TRUE, 3); /* Message */ msg_format("%s %s (%c).", act, o_name, index_to_label(slot)); /* Cursed! */ if (cursed_p(o_ptr)) { /* Warn the player */ msg_print("Oops! It feels deathly cold!"); /* Remove special inscription, if any */ if (o_ptr->discount >= INSCRIP_NULL) o_ptr->discount = 0; /* Sense the object if allowed */ if (o_ptr->discount == 0) o_ptr->discount = INSCRIP_CURSED; /* The object has been "sensed" */ o_ptr->ident |= (IDENT_SENSE); } /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Recalculate torch */ p_ptr->update |= (PU_TORCH); /* Recalculate mana */ p_ptr->update |= (PU_MANA); /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); p_ptr->redraw |= (PR_EQUIPPY); }
/* * Let the user select an item, save its "index" * * Return TRUE only if an acceptable item was chosen by the user. * * The selected item must satisfy the "item_tester_hook()" function, * if that hook is set, and the "item_tester_tval", if that value is set. * * All "item_tester" restrictions are cleared before this function returns. * * The user is allowed to choose acceptable items from the equipment, * inventory, or floor, respectively, if the proper flag was given, * and there are any acceptable items in that location. * * The equipment or inventory 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. * * Note that the user must press "-" to specify the item on the floor, * and there is no way to "examine" the item on the floor, while the * use of "capital" letters will "examine" an inventory/equipment item, * and prompt for its use. * * If a legal item is selected from the inventory, we save it in "cp" * directly (0 to 35), and return TRUE. * * If a legal item is selected from the floor, we save it in "cp" as * a negative (-1 to -511), and return TRUE. * * If no item is available, we do nothing to "cp", and we display a * warning message, using "str" if available, and return FALSE. * * If no item is selected, we do nothing to "cp", and return FALSE. * * Global "p_ptr->command_wrk" is used to choose between equip/inven/floor * listings. It is equal to USE_INVEN or USE_EQUIP 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 get_item(int *cp, cptr pmt, cptr str, cmd_code cmd, int mode) { int py = p_ptr->py; int px = p_ptr->px; unsigned char cmdkey = cmd_lookup_key(cmd); ui_event_data which; int j, k; int i1, i2; int e1, e2; int f1, f2; bool done, item; bool oops = FALSE; bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE); bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE); bool use_floor = ((mode & USE_FLOOR) ? TRUE : FALSE); bool use_quiver = ((mode & QUIVER_TAGS) ? TRUE : FALSE); bool is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE); bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE); olist_detail_t olist_mode = 0; bool allow_inven = FALSE; bool allow_equip = FALSE; bool allow_floor = FALSE; bool toggle = FALSE; char tmp_val[160]; char out_val[160]; int floor_list[MAX_FLOOR_STACK]; int floor_num; bool show_list = 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); /* Paranoia XXX XXX XXX */ message_flush(); /* Not done */ done = FALSE; /* No item selected */ item = FALSE; /* Full inventory */ i1 = 0; i2 = INVEN_PACK - 1; /* Forbid inventory */ if (!use_inven) i2 = -1; /* Restrict inventory indexes */ while ((i1 <= i2) && (!get_item_okay(i1))) i1++; while ((i1 <= i2) && (!get_item_okay(i2))) i2--; /* Accept inventory */ if (i1 <= i2) allow_inven = TRUE; /* Full equipment */ e1 = INVEN_WIELD; e2 = ALL_INVEN_TOTAL - 1; /* Forbid equipment */ if (!use_equip) e2 = -1; /* Restrict equipment indexes */ while ((e1 <= e2) && (!get_item_okay(e1))) e1++; while ((e1 <= e2) && (!get_item_okay(e2))) e2--; /* Accept equipment */ if (e1 <= e2) allow_equip = TRUE; /* Scan all non-gold objects in the grid */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x03); /* Full floor */ f1 = 0; f2 = floor_num - 1; /* Forbid floor */ if (!use_floor) f2 = -1; /* Restrict floor indexes */ while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f1]))) f1++; while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f2]))) f2--; /* Accept floor */ if (f1 <= f2) allow_floor = TRUE; /* Require at least one legal choice */ if (!allow_inven && !allow_equip && !allow_floor) { /* Oops */ oops = TRUE; done = TRUE; } /* Analyze choices */ else { /* Hack -- Start on equipment if requested */ if ((p_ptr->command_wrk == USE_EQUIP) && use_equip) p_ptr->command_wrk = USE_EQUIP; /* If we are using the quiver then start on equipment */ else if (use_quiver) p_ptr->command_wrk = USE_EQUIP; /* Use inventory if allowed */ else if (use_inven) p_ptr->command_wrk = USE_INVEN; /* Use equipment if allowed */ else if (use_equip) p_ptr->command_wrk = USE_EQUIP; /* Use floor if allowed */ else if (use_floor) p_ptr->command_wrk = USE_FLOOR; /* Hack -- Use (empty) inventory */ else p_ptr->command_wrk = USE_INVEN; } /* Start out in "display" mode */ if (show_list) { /* Save screen */ screen_save(); } /* Repeat until done */ while (!done) { int ni = 0; int ne = 0; /* Scan windows */ for (j = 0; j < REPOSBAND_TERM_MAX; j++) { /* Unused */ if (!reposband_term[j]) continue; /* Count windows displaying inven */ if (op_ptr->window_flag[j] & (PW_INVEN)) ni++; /* Count windows displaying equip */ if (op_ptr->window_flag[j] & (PW_EQUIP)) ne++; } /* Toggle if needed */ if (((p_ptr->command_wrk == USE_EQUIP) && ni && !ne) || ((p_ptr->command_wrk == USE_INVEN) && !ni && ne)) { /* Toggle */ toggle_inven_equip(); /* Track toggles */ toggle = !toggle; } /* Redraw */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); /* Redraw windows */ redraw_stuff(); /* Viewing inventory */ if (p_ptr->command_wrk == USE_INVEN) { /* Redraw if needed */ if (show_list) show_inven(olist_mode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Inven:"); /* List choices */ if (i1 <= i2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", index_to_label(i1), index_to_label(i2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Indicate legality of "toggle" */ if (use_equip) { my_strcat(out_val, " / for Equip,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate legality of the "floor" */ if (allow_floor) { my_strcat(out_val, " - for floor,", sizeof(out_val)); button_add("[-]", '-'); } } /* Viewing equipment */ else if (p_ptr->command_wrk == USE_EQUIP) { /* Redraw if needed */ if (show_list) show_equip(olist_mode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Equip:"); /* List choices */ if (e1 <= e2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", index_to_label(e1), index_to_label(e2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Indicate legality of "toggle" */ if (use_inven) { my_strcat(out_val, " / for Inven,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate legality of the "floor" */ if (allow_floor) { my_strcat(out_val, " - for floor,", sizeof(out_val)); button_add("[!]", '!'); } } /* Viewing floor */ else { /* Redraw if needed */ if (show_list) show_floor(floor_list, floor_num, olist_mode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Floor:"); /* List choices */ if (f1 <= f2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", I2A(f1), I2A(f2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Append */ if (use_inven) { my_strcat(out_val, " / for Inven,", sizeof(out_val)); button_add("[/]", '/'); } /* Append */ else if (use_equip) { my_strcat(out_val, " / for Equip,", sizeof(out_val)); button_add("[/]", '/'); } } redraw_stuff(); /* Finish the prompt */ my_strcat(out_val, " ESC", sizeof(out_val)); /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), "(%s) %s", out_val, pmt); /* Show the prompt */ prt(tmp_val, 0, 0); /* Get a key */ which = inkey_ex(); /* Parse it */ switch (which.key) { case ESCAPE: { done = TRUE; break; } case '/': { /* Toggle to inventory */ if (use_inven && (p_ptr->command_wrk != USE_INVEN)) { p_ptr->command_wrk = USE_INVEN; } /* Toggle to equipment */ else if (use_equip && (p_ptr->command_wrk != USE_EQUIP)) { p_ptr->command_wrk = USE_EQUIP; } /* No toggle allowed */ else { bell("Cannot switch item selector!"); break; } /* Hack -- Fix screen */ if (show_list) { /* Load screen */ screen_load(); /* Save screen */ screen_save(); } /* Need to redraw */ break; } case '-': { /* Paranoia */ if (!allow_floor) { bell("Cannot select floor!"); break; } /* There is only one item */ if (floor_num == 1) { /* Auto-select */ if (p_ptr->command_wrk == (USE_FLOOR)) { /* Special index */ k = 0 - floor_list[0]; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } } /* Hack -- Fix screen */ if (show_list) { /* Load screen */ screen_load(); /* Save screen */ screen_save(); } p_ptr->command_wrk = (USE_FLOOR); #if 0 /* Check each legal object */ for (i = 0; i < floor_num; ++i) { /* Special index */ k = 0 - floor_list[i]; /* Skip non-okay objects */ if (!get_item_okay(k)) continue; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) continue; /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } #endif break; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* Look up the tag */ if (!get_tag(&k, which.key, cmd, quiver_tags)) { bell("Illegal object choice (tag)!"); break; } /* Hack -- Validate the item */ if ((k < INVEN_WIELD) ? !allow_inven : !allow_equip) { bell("Illegal object choice (tag)!"); break; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (tag)!"); break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } case '\n': case '\r': { /* Choose "default" inventory item */ if (p_ptr->command_wrk == USE_INVEN) { if (i1 != i2) { bell("Illegal object choice (default)!"); break; } k = i1; } /* Choose the "default" slot (0) of the quiver */ else if (quiver_tags) k = e1; /* Choose "default" equipment item */ else if (p_ptr->command_wrk == USE_EQUIP) { if (e1 != e2) { bell("Illegal object choice (default)!"); break; } k = e1; } /* Choose "default" floor item */ else { if (f1 != f2) { bell("Illegal object choice (default)!"); break; } k = 0 - floor_list[f1]; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (default)!"); break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } default: { bool verify; /* Note verify */ verify = (isupper((unsigned char)which.key) ? TRUE : FALSE); /* Lowercase */ which.key = tolower((unsigned char)which.key); /* Convert letter to inventory index */ if (p_ptr->command_wrk == USE_INVEN) { k = label_to_inven(which.key); if (k < 0) { bell("Illegal object choice (inven)!"); break; } } /* Convert letter to equipment index */ else if (p_ptr->command_wrk == USE_EQUIP) { k = label_to_equip(which.key); if (k < 0) { bell("Illegal object choice (equip)!"); break; } } /* Convert letter to floor index */ else { k = (islower((unsigned char)which.key) ? A2I(which.key) : -1); if (k < 0 || k >= floor_num) { bell("Illegal object choice (floor)!"); break; } /* Special index */ k = 0 - floor_list[k]; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (normal)!"); break; } /* Verify the item */ if (verify && !verify_item("Try", k)) { done = TRUE; break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } } } /* Fix the screen if necessary */ if (show_list) { /* Load screen */ screen_load(); /* Hack -- Cancel "display" */ show_list = FALSE; } /* Kill buttons */ button_kill('*'); button_kill('/'); button_kill('-'); button_kill('!'); redraw_stuff(); /* Forget the item_tester_tval restriction */ item_tester_tval = 0; /* Forget the item_tester_hook restriction */ item_tester_hook = NULL; /* Toggle again if needed */ if (toggle) toggle_inven_equip(); /* Update */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); redraw_stuff(); /* Clear the prompt line */ prt("", 0, 0); /* Warning if needed */ if (oops && str) msg_print(str); /* Result */ return (item); }
bool pickup_object(void) { object_type *o_ptr = &o_list[cave_o_idx[p_ptr->py][p_ptr->px]]; char commands[80]; int value = evaluate_object(o_ptr); if (value > 0) { int slot = wield_slot(o_ptr); // if it is a non-wieldable item if (slot == -1) { // create the commands strnfmt(commands, sizeof(commands), "g-"); // queue the commands automaton_keypresses(commands); } // special rules for arrows else if ((slot == INVEN_QUIVER1) || (slot == INVEN_QUIVER2)) { // if it is considered equal in value to existing arrows, then just get it to allow auto-merging if (value == 1) { // create the commands strnfmt(commands, sizeof(commands), "g-"); // queue the commands automaton_keypresses(commands); } // otherwise it is considered better than the existing arrows so wield it... else { // create the commands strnfmt(commands, sizeof(commands), "w-"); // queue the commands automaton_keypresses(commands); // if both slots are full, we need to tell the game to replace the inferior one if (inventory[INVEN_QUIVER1].k_idx && inventory[INVEN_QUIVER2].k_idx) { if (evaluate_arrow(&inventory[INVEN_QUIVER1]) > evaluate_arrow(&inventory[INVEN_QUIVER2])) { automaton_keypress(index_to_label(INVEN_QUIVER2)); } else { automaton_keypress(index_to_label(INVEN_QUIVER1)); } } } } // default for wieldable items else { // create the commands strnfmt(commands, sizeof(commands), "w-"); // queue the commands automaton_keypresses(commands); } return (TRUE); } return (FALSE); }
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; }