bool player_can_read(void) { if (query_timed(TIMED_BLIND) || no_lite() || query_timed(TIMED_CONFUSED)) { return (FALSE); } return (TRUE); }
bool player_can_study(void) { if (p_ptr->spell.realm[0]) { if (query_timed(TIMED_BLIND) || no_lite() || query_timed(TIMED_CONFUSED) || p_ptr->csp < 1) { return (FALSE); } } if (p_ptr->rp.pclass == CLASS_MINDCRAFTER) { return (FALSE); } return (TRUE); }
void rage_mage_gain_spell(void) { int item; if (p_ptr->blind || no_lite()) { msg_print("You cannot see!"); return; } if (p_ptr->confused) { msg_print("You are too confused!"); return; } if (!p_ptr->new_spells) { msg_print("You cannot learn any new techniques!"); return; } msg_format("You can learn %d new technique%s.", p_ptr->new_spells, (p_ptr->new_spells == 1 ? "" : "s")); msg_print(NULL); item_tester_tval = TV_RAGE_BOOK; if (get_item(&item, "Study which book?", "You have no books that you can read.", USE_INVEN)) { int book = inventory[item].sval; if (_gain_spell(book)) { char o_name[MAX_NLEN]; int old_amt = inventory[item].number; inventory[item].number = 1; object_desc(o_name, &inventory[item], 0); inventory[item].number = old_amt; msg_format("%^s is destroyed.", o_name); inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); energy_use = 100; } } }
void rage_mage_gain_spell(void) { obj_prompt_t prompt = {0}; if (p_ptr->blind || no_lite()) { msg_print("You cannot see!"); return; } if (p_ptr->confused) { msg_print("You are too confused!"); return; } if (!p_ptr->new_spells) { msg_print("You cannot learn any new techniques!"); return; } prompt.prompt = "Study which book?"; prompt.error = "You have no books that you can read."; prompt.filter = _is_rage_book; prompt.where[0] = INV_PACK; prompt.where[1] = INV_FLOOR; obj_prompt(&prompt); if (!prompt.obj) return; if (_gain_spell(prompt.obj->sval)) { char o_name[MAX_NLEN]; object_desc(o_name, prompt.obj, OD_COLOR_CODED | OD_SINGULAR); msg_format("%^s is destroyed.", o_name); prompt.obj->number--; obj_release(prompt.obj, 0); energy_use = 100; } }
/* * Read a scroll (from the pack or floor). * * Certain scrolls can be "aborted" without losing the scroll. These * include scrolls with no effects but recharge or identify, which are * cancelled before use. XXX Reading them still takes a turn, though. */ void do_cmd_read_scroll(void) { int item, used_up, lev; bool ident; object_type *o_ptr; cptr q, s; /* Check some conditions */ if (p_ptr->blind) { msg_print("You can't see anything."); return; } if (no_lite()) { msg_print("You have no light to read by."); return; } if (p_ptr->confused) { msg_print("You are too confused!"); return; } /* Restrict choices to scrolls */ item_tester_tval = TV_SCROLL; /* Get an item */ q = "Read which scroll? "; s = "You have no scrolls to read."; 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]; } /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ ident = FALSE; /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Read the scroll */ used_up = use_object(o_ptr, &ident); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* The item was tried */ object_tried(o_ptr); /* An identification was made */ if (ident && !object_aware_p(o_ptr)) { object_aware(o_ptr); gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev); } /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); /* Hack -- allow certain scrolls to be "preserved" */ if (!used_up) return; /* Destroy a scroll in the pack */ if (item >= 0) { inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); } /* Destroy a scroll on the floor */ else { floor_item_increase(0 - item, -1); floor_item_describe(0 - item); floor_item_optimize(0 - item); } }
/* * Perform the basic "open" command on doors * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ static bool do_cmd_open_aux(int y, int x) { int i, j; bool more = FALSE; /* Verify legality */ if (!do_cmd_open_test(y, x)) return (FALSE); /* Jammed door */ if (cave_feat[y][x] >= FEAT_DOOR_HEAD + 0x08) { /* Stuck */ msg_print("The door appears to be stuck."); } /* Locked door */ else if (cave_feat[y][x] >= FEAT_DOOR_HEAD + 0x01) { /* Disarm factor */ i = p_ptr->skill_dis; /* Penalize some conditions */ if (p_ptr->blind || no_lite()) i = i / 10; if (p_ptr->confused || p_ptr->image) i = i / 10; /* Extract the lock power */ j = cave_feat[y][x] - FEAT_DOOR_HEAD; /* Extract the difficulty XXX XXX XXX */ j = i - (j * 4); /* Always have a small chance of success */ if (j < 2) j = 2; /* Success */ if (randint0(100) < j) { /* Message */ msgt(MSG_OPENDOOR, "You have picked the lock."); /* Open the door */ cave_set_feat(y, x, FEAT_OPEN); /* Update the visuals */ p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Sound */ sound(SOUND_OPENDOOR); /* Experience */ gain_exp(1); } /* Failure */ else { /* Failure */ if (flush_failure) flush(); /* Message */ msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock."); /* We may keep trying */ more = TRUE; } } /* Closed door */ else { /* Open the door */ cave_set_feat(y, x, FEAT_OPEN); /* Update the visuals */ p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Sound */ sound(SOUND_OPENDOOR); } /* Result */ return (more); }
/* * Attempt to disarm the chest at the given location * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ static bool do_cmd_disarm_chest(int y, int x, s16b o_idx) { int i, j; bool more = FALSE; object_type *o_ptr = &o_list[o_idx]; /* Get the "disarm" factor */ i = p_ptr->skill_dis; /* Penalize some conditions */ if (p_ptr->blind || no_lite()) i = i / 10; if (p_ptr->confused || p_ptr->image) i = i / 10; /* Difficulty rating. */ j = i - (5 + o_ptr->pval / 2); /* Always have a small chance of success */ if (j < 2) j = 2; /* Must find the trap first. */ if (!object_known_p(o_ptr)) { msg_print("I don't see any traps."); } /* Already disarmed/unlocked */ else if (o_ptr->pval <= 0) { msg_print("The chest is not trapped."); } /* No traps to find. */ else if (!chest_traps[o_ptr->pval]) { msg_print("The chest is not trapped."); } /* Success (get a fair amount of experience) */ else if (randint0(100) < j) { msg_print("You have disarmed the chest."); gain_exp(o_ptr->pval * o_ptr->pval / 10); o_ptr->pval = (0 - o_ptr->pval); } /* Failure -- Keep trying */ else if ((i > 5) && (randint1(i) > 5)) { /* We may keep trying */ more = TRUE; if (flush_failure) flush(); msg_print("You failed to disarm the chest."); } /* Failure -- Set off the trap */ else { msg_print("You set off a trap!"); chest_trap(y, x, o_idx); } /* Result */ return (more); }
/* * Attempt to open the given chest at the given location * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ static bool do_cmd_open_chest(int y, int x, s16b o_idx) { int i, j; bool flag = TRUE; bool more = FALSE; object_type *o_ptr = &o_list[o_idx]; /* Attempt to unlock it */ if (o_ptr->pval > 0) { /* Assume locked, and thus not open */ flag = FALSE; /* Get the "disarm" factor */ i = p_ptr->skill_dis; /* Penalize some conditions */ if (p_ptr->blind || no_lite()) i = i / 10; if (p_ptr->confused || p_ptr->image) i = i / 10; /* Difficulty rating. Tweaked to compensate for higher pvals. */ j = i - 2 * o_ptr->pval / 3; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success -- May still have traps */ if (randint0(100) < j) { msg_print("You have picked the lock."); gain_exp(o_ptr->pval); flag = TRUE; } /* Failure -- Keep trying */ else { /* We may continue repeating */ more = TRUE; if (flush_failure) flush(); msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock."); } } /* Allowed to open */ if (flag) { /* Apply chest traps, if any */ chest_trap(y, x, o_idx); /* Let the Chest drop items */ chest_death(FALSE, y, x, o_idx); } /* Result */ return (more); }
/* * Perform the basic "disarm" command on a trap or glyph. * * Assume there is no monster blocking the destination (tested by * do_cmd_disarm). Traps now have level-dependent power. * Decrement Rogue traps and glyphs of warding. -LM- * * Returns TRUE if repeated commands may continue */ static bool do_cmd_disarm_aux(int y, int x) { int i, j, power; const char * name; bool more = FALSE; /* Verify legality */ if (!do_cmd_disarm_test(y, x)) return (FALSE); /* Access trap or glyph name */ name = (f_name + f_info[cave_feat[y][x]].name); /* Get the "disarm" factor */ i = p_ptr->skill_dis; /* Penalize some conditions */ if (p_ptr->blind || no_lite()) i = i / 10; if (p_ptr->confused || p_ptr->image) i = i / 10; /* Extract trap "power". */ power = 5 + p_ptr->depth / 4; /* Prevent the player's own traps granting exp. */ if ((cave_feat[y][x] >= FEAT_MTRAP_HEAD) && (cave_feat[y][x] <= FEAT_MTRAP_TAIL)) power = 0; /* Prevent glyphs of warding granting exp. */ if (cave_feat[y][x] == FEAT_GLYPH) power = 0; /* Extract the disarm probability */ j = i - power; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success */ if ((power == 0) || (randint0(100) < j)) { /* Special message for glyphs. */ if (cave_feat[y][x] == FEAT_GLYPH) msg("You have desanctified the %s.", name); /* Normal message otherwise */ else msg("You have disarmed the %s.", name); /* If a Rogue's monster trap, decrement the trap count. */ if ((cave_feat[y][x] >= FEAT_MTRAP_HEAD) && (cave_feat[y][x] <= FEAT_MTRAP_TAIL)) num_trap_on_level--; /* If a glyph, decrement the glyph count. */ if (cave_feat[y][x] == FEAT_GLYPH) num_glyph_on_level--; /* Reward */ gain_exp(power); /* Forget the trap */ cave_info[y][x] &= ~(CAVE_MARK); /* Remove the trap */ cave_set_feat(y, x, FEAT_FLOOR); } /* Failure -- Keep trying */ else if ((i > 5) && (randint1(i) > 5)) { /* Failure */ if (flush_failure) flush(); /* Message */ msg("You failed to disarm the %s.", name); /* We may keep trying */ more = TRUE; } /* Failure -- Set off the trap */ else { /* Message */ msg("You set off the %s!", name); /* Hit the trap */ hit_trap(y, x); } /* Result */ return (more); }
void gray_mage_gain_spell(void) { int item; if (p_ptr->blind || no_lite()) { msg_print("You cannot see!"); return; } if (p_ptr->confused) { msg_print("You are too confused!"); return; } if (!p_ptr->new_spells) { msg_print("You cannot learn any new spells!"); return; } item_tester_hook = _spell_book_p; if (get_item(&item, "Study which book?", "You have no books that you can read.", USE_INVEN)) { object_type *o_ptr = &inventory[item]; int spell_idx; _slot_info_ptr slot_ptr; /* Pick a spell to learn */ spell_idx = _choose_spell_to_gain(o_ptr); if (spell_idx == -1) return; /* Pick a slot for storage (possibly replacing an already learned spell) */ slot_ptr = _choose("Replace", _ALLOW_EMPTY | _SHOW_INFO); if (!slot_ptr) return; if (slot_ptr->realm != REALM_NONE) { string_ptr prompt = string_alloc_format( "Really replace %s? <color:y>[y/N]</color>", do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_NAME)); if (msg_prompt(string_buffer(prompt), "ny", PROMPT_DEFAULT) == 'n') { string_free(prompt); return; } string_free(prompt); } /* Learn the spell: Note, we don't bother with spell_learned# and spell_order[], since these are hard coded for 2 spell realms. Hopefully, ticking up learned_spells is enough? */ p_ptr->learned_spells++; slot_ptr->realm = tval2realm(o_ptr->tval); slot_ptr->spell = spell_idx; msg_format("You have learned the spell '%s'.", do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_NAME)); p_ptr->update |= PU_SPELLS; p_ptr->redraw |= PR_EFFECTS; energy_use = 100; } }