static int _calc_innate_blows_aux(innate_attack_ptr a, int max, int str_idx, int dex_idx) { int result = 0; int blow_str_idx; int mul = 55, div = MAX(70, a->weight); _range_t rng = _blows_range[dex_idx]; blow_str_idx = (adj_str_blow[str_idx] * mul / div); if (blow_str_idx > 110) blow_str_idx = 110; result = rng.min + (rng.max - rng.min) * blow_str_idx / 110; if (prace_is_(RACE_MON_LEPRECHAUN)) result /= 2; if (prace_is_(RACE_MON_HYDRA)) result *= 2; if (result < 100) result = 100; if (result > max) result = max; return result; }
void vampire_feed(int amt) { int food; int div = 4; if (prace_is_(MIMIC_BAT)) div = 16; if (p_ptr->food < PY_FOOD_FULL) hp_player(amt); else msg_print("You were not hungry."); /* Experimental: Scale the feeding asymptotically. Historically, vampiric feeding was too slow in the early game (low damage) hence tedious. But by the end game, a mere two bites would fill the vampire, rendering the talent rather useless. */ if (p_ptr->food < PY_FOOD_VAMP_MAX) food = p_ptr->food + (PY_FOOD_VAMP_MAX - p_ptr->food) / div; /* Exceeding PY_FOOD_VAMP_MAX is unlikely, but possible (eg. eating rations of food?!) */ else if (p_ptr->food < PY_FOOD_MAX) food = p_ptr->food + (PY_FOOD_MAX - p_ptr->food) / div; else food = p_ptr->food + amt; assert(food >= p_ptr->food); set_food(food); }
int bow_range(object_type *o_ptr) { int range, mult; switch (o_ptr->sval) { case SV_LIGHT_XBOW: range = 9; /* somebody is adding 1 later ... */ range += (p_ptr->concent + 1) / 2; /* Snipers? */ break; case SV_SHORT_BOW: range = 9; /* somebody is adding 1 later ... */ break; default: mult = bow_mult(o_ptr); range = 13 + mult/80; if (o_ptr->sval == SV_HEAVY_XBOW) { if (p_ptr->concent) range -= (5 - (p_ptr->concent + 1) / 2); else range -= 5; } break; } if (prace_is_(RACE_DEMIGOD) && p_ptr->psubrace == DEMIGOD_ARTEMIS) range += 1 + p_ptr->lev/12; return range; }
bool res_save_inventory(int which) { int power = res_is_low(which) ? 66 : 41; /* Mercy for racial vulnerabilities: ResCt Old% New% ===== ==== ==== 1 24.2 35.2 2 1.5 16.7 3 0.0 7.4 4 3.7 5 1.9 6 0.0 */ if (prace_is_(RACE_ENT) && which == RES_FIRE) power = 54; if (prace_is_(RACE_ANDROID) && which == RES_ELEC) power = 54; return res_save(which, power); }
void display_shooter_info(doc_ptr doc) { object_type *bow_ptr = NULL; int slot = equip_find_object(TV_BOW, SV_ANY); char o_name[MAX_NLEN]; int mult; int num_fire = 0; int to_h = 0; int to_d = 0; int i, j; if (!slot || prace_is_(RACE_MON_JELLY) || p_ptr->shooter_info.tval_ammo == TV_NO_AMMO) return; bow_ptr = equip_obj(slot); assert(bow_ptr); mult = bow_mult(bow_ptr); if (p_ptr->shooter_info.num_fire) num_fire = p_ptr->shooter_info.num_fire * 100 * 100 / bow_energy(bow_ptr->sval); if (object_is_known(bow_ptr)) { to_h = bow_ptr->to_h; to_d = bow_ptr->to_d; if (weaponmaster_is_(WEAPONMASTER_CROSSBOWS) && p_ptr->lev >= 15) to_d += 1 + p_ptr->lev/10; } /* Shooter */ object_desc(o_name, bow_ptr, OD_OMIT_INSCRIPTION | OD_COLOR_CODED); doc_printf(doc, " <color:y>Shooting</color>: <indent><style:indent>%s</style></indent>\n", o_name); doc_printf(doc, " %-8.8s: %d'\n", "Range", (bow_range(bow_ptr) + 1) * 10); doc_printf(doc, " %-8.8s: %d.%02d\n", "Shots", num_fire/100, num_fire%100); doc_printf(doc, " %-8.8s: %d.%02dx\n", "Mult", mult/100, mult%100); doc_printf(doc, " %-8.8s: %d + %d = %d\n", "To Hit", to_h, p_ptr->shooter_info.dis_to_h, to_h + p_ptr->shooter_info.dis_to_h); doc_printf(doc, " %-8.8s: %d (%s)\n", "To Dam", to_d, "Multiplier Applies"); doc_printf(doc, " %-8.8s: %d (%s)\n", "Xtra Dam", p_ptr->shooter_info.dis_to_d, "Multiplier Does Not Apply"); doc_newline(doc); /* Ammo */ j = 0; for (i = 0; i < INVEN_PACK; i++) { if (inventory[i].tval == p_ptr->shooter_info.tval_ammo) _shooter_info_aux(doc, bow_ptr, &inventory[i], ++j); } }
int calculate_base_blows(int hand, int str_idx, int dex_idx) { int result = 0; weapon_info_t *info_ptr = &p_ptr->weapon_info[hand]; object_type *o_ptr = NULL; int blow_str_idx; int div = 0; int mul = 0; int wgt = 0; _blow_info_t blow_info = {0}; _range_t rng = _blows_range[dex_idx]; if (info_ptr->wield_how == WIELD_NONE) return 0; o_ptr = equip_obj(info_ptr->slot); if (!o_ptr) return 0; if (info_ptr->heavy_wield) return 100; blow_info = _get_blow_info(hand); wgt = o_ptr->weight; div = (wgt < blow_info.wgt) ? blow_info.wgt : wgt; mul = blow_info.mul + info_ptr->giant_wield * 10; blow_str_idx = adj_str_blow[str_idx] * mul / div; /* Scaled by 10 */ if (info_ptr->wield_how == WIELD_TWO_HANDS) { if (!info_ptr->omoi) blow_str_idx += 10; if (prace_is_(RACE_MON_GIANT) && giant_is_favorite(o_ptr)) blow_str_idx += 10; } if (p_ptr->pclass == CLASS_NINJA) blow_str_idx = MAX(0, blow_str_idx-10); if (blow_str_idx > 110) blow_str_idx = 110; result = rng.min + (rng.max - rng.min) * blow_str_idx / 110; if (p_ptr->pclass == CLASS_MAULER) result = 100 + (result - 100)/8; if (result > blow_info.num) result = blow_info.num; if (result < 100) result = 100; return result; }
void hypnotic_gaze_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Hypnotic Gaze"); break; case SPELL_DESC: var_set_string(res, "Attempt to charm a monster."); break; case SPELL_GAIN_MUT: msg_print("Your eyes look mesmerizing..."); break; case SPELL_LOSE_MUT: msg_print("Your eyes look uninteresting."); break; case SPELL_MUT_DESC: var_set_string(res, "Your gaze is hypnotic."); break; case SPELL_CAST: { int dir = 0; var_set_bool(res, FALSE); if (get_aim_dir(&dir)) { int power = p_ptr->lev; if (prace_is_(RACE_MON_VAMPIRE)) power *= 2; msg_print("Your eyes look mesmerizing..."); charm_monster(dir, power); var_set_bool(res, TRUE); } break; } default: default_spell(cmd, res); break; } }
int res_pct_aux(int which, int count) { int result = 0; int idx = count; if (count < 0) idx *= -1; if (idx >= _MAX_PCTS) idx = _MAX_PCTS-1; if (res_is_low(which)) result = _lo_pcts[idx]; else result = _hi_pcts[idx]; if (count < 0) result *= -1; else if (result < 100) { if (which == RES_CONF) { if (prace_is_(RACE_TONBERRY) || demon_is_(DEMON_CYBERDEMON)) result = (result + 1) / 2; } if (which == RES_LITE) { if (prace_is_(RACE_VAMPIRE) || prace_is_(RACE_MON_VAMPIRE) || prace_is_(MIMIC_VAMPIRE)) result = (result + 1) / 2; } if (which == RES_FIRE) { if (prace_is_(RACE_ENT)) result = result * 7 / 10; } if (which == RES_ELEC) { if (prace_is_(RACE_ANDROID)) result = result * 7 / 10; } } return result; }
/* * Destroy an item */ void do_cmd_destroy(void) { int item, amt = 1; int old_number; bool force = FALSE; object_type *o_ptr; object_type forge; object_type *q_ptr = &forge; bool is_equipped = FALSE; char o_name[MAX_NLEN]; char out_val[MAX_NLEN+40]; cptr q, s; int mode = USE_INVEN | USE_FLOOR; if (p_ptr->pclass == CLASS_RUNE_KNIGHT) mode |= USE_EQUIP; if (p_ptr->special_defense & KATA_MUSOU) { set_action(ACTION_NONE); } /* Hack -- force destruction */ if (command_arg > 0) force = TRUE; /* Get an item */ q = "Destroy which item? "; s = "You have nothing to destroy."; if (!get_item(&item, q, s, mode)) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; is_equipped = equip_is_valid_slot(item); } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Hack for Rune Knight: They can destroy worn equipment, but only if it has the Sacrifice rune. get_item() is not smart enough to handle this restriction ... */ if (is_equipped && o_ptr->rune != RUNE_SACRIFICE) { msg_print("You must first remove that item before destroying it."); return; } /* Verify unless quantity given beforehand */ if (!force && (confirm_destroy || (object_value(o_ptr) > 0))) { object_desc(o_name, o_ptr, OD_OMIT_PREFIX); /* Make a verification */ sprintf(out_val, "Really destroy %s? [y/n/Auto]", o_name); msg_print(NULL); /* HACK : Add the line to message buffer */ message_add(out_val); p_ptr->window |= (PW_MESSAGE); window_stuff(); /* Get an acceptable answer */ while (TRUE) { char i; /* Prompt */ prt(out_val, 0, 0); i = inkey(); /* Erase the prompt */ prt("", 0, 0); if (i == 'y' || i == 'Y') { break; } if (i == ESCAPE || i == 'n' || i == 'N') { /* Cancel */ return; } if (i == 'A') { /* Add an auto-destroy preference line */ if (autopick_autoregister(o_ptr)) { /* Auto-destroy it */ autopick_alter_item(item, TRUE); } /* The object is already destroyed. */ return; } } /* while (TRUE) */ } /* See how many items */ if (o_ptr->number > 1) { /* Get a quantity */ amt = get_quantity(NULL, o_ptr->number); /* Allow user abort */ if (amt <= 0) return; } /* Describe the object */ old_number = o_ptr->number; o_ptr->number = amt; object_desc(o_name, o_ptr, 0); o_ptr->number = old_number; /* Take a turn */ energy_use = 100; /* Artifacts cannot be destroyed */ if (!can_player_destroy_object(o_ptr)) { energy_use = 0; /* Message */ msg_format("You cannot destroy %s.", o_name); /* Done */ return; } object_copy(q_ptr, o_ptr); stats_on_p_destroy(o_ptr, amt); if (prace_is_(RACE_MON_JELLY)) jelly_eat_object(o_ptr); else if (prace_is_(RACE_MON_SWORD) && object_is_melee_weapon(o_ptr)) sword_absorb_object(o_ptr); else if (prace_is_(RACE_MON_RING) && object_is_jewelry(o_ptr)) ring_absorb_object(o_ptr); else msg_format("You destroy %s.", o_name); if (o_ptr->rune == RUNE_SACRIFICE) { int add_hp = is_equipped ? p_ptr->mhp : p_ptr->mhp/3; int add_sp = is_equipped ? p_ptr->msp : p_ptr->msp/3; msg_print("You feel a surge of wondrous power enter your body."); p_ptr->chp = MIN(p_ptr->mhp, p_ptr->chp + add_hp); p_ptr->chp_frac = 0; p_ptr->csp = MIN(p_ptr->msp, p_ptr->csp + add_sp); p_ptr->csp_frac = 0; p_ptr->redraw |= (PR_MANA); p_ptr->window |= (PW_PLAYER); p_ptr->window |= (PW_SPELL); p_ptr->redraw |= (PR_HP); if (is_equipped) { blast_object(o_ptr); o_ptr->curse_flags = TRC_HEAVY_CURSE; } } else if (is_equipped) blast_object(o_ptr); sound(SOUND_DESTITEM); /* Reduce the charges of rods/wands */ reduce_charges(o_ptr, amt); /* Eliminate the item (from the pack) */ if (item >= 0) { if (!is_equipped) { inven_item_increase(item, -amt); inven_item_describe(item); inven_item_optimize(item); } } /* Eliminate the item (from the floor) */ else { floor_item_increase(0 - item, -amt); floor_item_describe(0 - item); floor_item_optimize(0 - item); } if ( p_ptr->pclass == CLASS_NECROMANCER && (q_ptr->tval == TV_LIFE_BOOK || q_ptr->tval == TV_CRUSADE_BOOK) ) { int sp = 0; int osp = p_ptr->csp; switch (q_ptr->sval) { case 0: sp = 10; break; case 1: sp = 25; break; case 2: sp = 100; break; case 3: sp = 666; break; } p_ptr->csp += sp; if (p_ptr->csp >= p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; } if (p_ptr->csp > osp) msg_print("You feel your head clear."); p_ptr->redraw |= (PR_MANA); } if (high_level_book(q_ptr)) { bool gain_expr = FALSE; if (p_ptr->prace == RACE_ANDROID) { } else if ((p_ptr->pclass == CLASS_WARRIOR) || (p_ptr->pclass == CLASS_BERSERKER)) { gain_expr = TRUE; } else if (p_ptr->pclass == CLASS_PALADIN) { if (is_good_realm(p_ptr->realm1)) { if (!is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE; } else { if (is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE; } } if (gain_expr && (p_ptr->exp < PY_MAX_EXP)) { s32b tester_exp = p_ptr->max_exp / 20; if (tester_exp > 10000) tester_exp = 10000; if (q_ptr->sval < 3) tester_exp /= 4; if (tester_exp<1) tester_exp = 1; msg_print("You feel more experienced."); gain_exp(tester_exp * amt); } } if (high_level_book(q_ptr) && q_ptr->tval == TV_LIFE_BOOK) { virtue_add(VIRTUE_UNLIFE, 1); virtue_add(VIRTUE_VITALITY, -1); } else if ( high_level_book(q_ptr) && (q_ptr->tval == TV_DEATH_BOOK || q_ptr->tval == TV_NECROMANCY_BOOK) ) { virtue_add(VIRTUE_UNLIFE, -1); virtue_add(VIRTUE_VITALITY, 1); } if (q_ptr->to_a || q_ptr->to_h || q_ptr->to_d) virtue_add(VIRTUE_ENCHANTMENT, -1); if (object_value_real(q_ptr) > 30000) virtue_add(VIRTUE_SACRIFICE, 2); else if (object_value_real(q_ptr) > 10000) virtue_add(VIRTUE_SACRIFICE, 1); if (q_ptr->to_a != 0 || q_ptr->to_d != 0 || q_ptr->to_h != 0) virtue_add(VIRTUE_HARMONY, 1); if (equip_is_valid_slot(item)) calc_android_exp(); }
static void do_cmd_eat_food_aux(int item) { int ident, lev; object_type *o_ptr; if (music_singing_any()) bard_stop_singing(); if (hex_spelling_any()) stop_hex_spell_all(); warlock_stop_singing(); /* 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]; } if (object_is_mushroom(o_ptr) && o_ptr->art_name && o_ptr->timeout) { msg_print("Your mushroom is still charging."); return; } /* Sound */ sound(SOUND_EAT); /* Take a turn */ energy_use = 100; /* Identity not known yet */ ident = FALSE; /* Object level */ lev = k_info[o_ptr->k_idx].level; if (o_ptr->tval == TV_FOOD) { /* Analyze the food */ switch (o_ptr->sval) { case SV_FOOD_POISON: { if (!res_save_default(RES_POIS)) { if (set_poisoned(p_ptr->poisoned + randint0(10) + 10, FALSE)) ident = TRUE; } break; } case SV_FOOD_BLINDNESS: { if (!res_save_default(RES_BLIND)) { if (set_blind(p_ptr->blind + randint0(200) + 200, FALSE)) ident = TRUE; } break; } case SV_FOOD_PARANOIA: { if (!fear_save_p(fear_threat_level())) ident = fear_add_p(FEAR_SCARED); break; } case SV_FOOD_CONFUSION: { if (!res_save_default(RES_CONF)) { if (set_confused(p_ptr->confused + randint0(10) + 10, FALSE)) ident = TRUE; } break; } case SV_FOOD_HALLUCINATION: { if (!res_save_default(RES_CHAOS)) { if (set_image(p_ptr->image + randint0(25) + 25, FALSE)) ident = TRUE; } break; } case SV_FOOD_PARALYSIS: { if (!p_ptr->free_act) { if (set_paralyzed(randint1(4), FALSE)) { ident = TRUE; } } break; } case SV_FOOD_WEAKNESS: { take_hit(DAMAGE_NOESCAPE, damroll(6, 6), "poisonous food", -1); (void)do_dec_stat(A_STR); ident = TRUE; break; } case SV_FOOD_SICKNESS: { take_hit(DAMAGE_NOESCAPE, damroll(6, 6), "poisonous food", -1); (void)do_dec_stat(A_CON); ident = TRUE; break; } case SV_FOOD_STUPIDITY: { take_hit(DAMAGE_NOESCAPE, damroll(8, 8), "poisonous food", -1); (void)do_dec_stat(A_INT); ident = TRUE; break; } case SV_FOOD_NAIVETY: { take_hit(DAMAGE_NOESCAPE, damroll(8, 8), "poisonous food", -1); (void)do_dec_stat(A_WIS); ident = TRUE; break; } case SV_FOOD_UNHEALTH: { take_hit(DAMAGE_NOESCAPE, damroll(10, 10), "poisonous food", -1); (void)do_dec_stat(A_CON); ident = TRUE; break; } case SV_FOOD_DISEASE: { take_hit(DAMAGE_NOESCAPE, damroll(10, 10), "poisonous food", -1); (void)do_dec_stat(A_STR); ident = TRUE; break; } case SV_FOOD_CURE_POISON: { if (set_poisoned(0, TRUE)) ident = TRUE; break; } case SV_FOOD_CURE_BLINDNESS: { if (set_blind(0, TRUE)) ident = TRUE; break; } case SV_FOOD_CURE_PARANOIA: { if (p_ptr->afraid) { fear_clear_p(); ident = TRUE; } break; } case SV_FOOD_CURE_CONFUSION: { if (set_confused(0, TRUE)) ident = TRUE; break; } case SV_FOOD_CURE_SERIOUS: { if (hp_player(damroll(6, 8))) ident = TRUE; if (set_cut((p_ptr->cut / 2) - 50, TRUE)) ident = TRUE; break; } case SV_FOOD_RESTORE_STR: { if (do_res_stat(A_STR)) ident = TRUE; break; } case SV_FOOD_RESTORE_CON: { if (do_res_stat(A_CON)) ident = TRUE; break; } case SV_FOOD_RESTORING: { if (do_res_stat(A_STR)) ident = TRUE; if (do_res_stat(A_INT)) ident = TRUE; if (do_res_stat(A_WIS)) ident = TRUE; if (do_res_stat(A_DEX)) ident = TRUE; if (do_res_stat(A_CON)) ident = TRUE; if (do_res_stat(A_CHR)) ident = TRUE; break; } case SV_FOOD_RATION: case SV_FOOD_BISCUIT: case SV_FOOD_JERKY: case SV_FOOD_SLIME_MOLD: { msg_print("That tastes good."); ident = TRUE; break; } case SV_FOOD_AMBROSIA: { msg_print("That tastes divine!"); set_poisoned(0, TRUE); hp_player(damroll(15, 15)); do_res_stat(A_STR); do_res_stat(A_INT); do_res_stat(A_WIS); do_res_stat(A_DEX); do_res_stat(A_CON); do_res_stat(A_CHR); restore_level(); ident = TRUE; break; } case SV_FOOD_WAYBREAD: { msg_print("That tastes good."); (void)set_poisoned(0, TRUE); (void)hp_player(damroll(4, 8)); ident = TRUE; break; } case SV_FOOD_PINT_OF_ALE: case SV_FOOD_PINT_OF_WINE: { msg_print("That tastes good."); ident = TRUE; break; } } } if (prace_is_(RACE_SNOTLING) && object_is_mushroom(o_ptr)) { int lev = k_info[o_ptr->k_idx].level; int dur = lev + randint1(lev); set_fast(p_ptr->fast + dur, FALSE); set_shield(p_ptr->shield + dur, FALSE); set_hero(p_ptr->hero + dur, FALSE); set_tim_building_up(p_ptr->tim_building_up + dur, FALSE); } /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); if (!(object_is_aware(o_ptr))) { virtue_add(VIRTUE_KNOWLEDGE, -1); virtue_add(VIRTUE_PATIENCE, -1); virtue_add(VIRTUE_CHANCE, 1); } /* We have tried it */ if (o_ptr->tval == TV_FOOD) object_tried(o_ptr); stats_on_use(o_ptr, 1); /* The player is now aware of the object */ if (ident && !object_is_aware(o_ptr)) { object_aware(o_ptr); stats_on_notice(o_ptr, 1); gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev); }
static void do_cmd_eat_food_aux(obj_ptr obj) { int lev = k_info[obj->k_idx].level; bool ident = FALSE; if (music_singing_any()) bard_stop_singing(); if (hex_spelling_any()) stop_hex_spell_all(); warlock_stop_singing(); if (object_is_mushroom(obj) && obj->art_name && obj->timeout) { msg_print("Your mushroom is still charging."); return; } sound(SOUND_EAT); energy_use = 100; ident = FALSE; /* Food may have effects */ if (obj->tval == TV_FOOD) { switch (obj->sval) { case SV_FOOD_POISON: { if (!res_save_default(RES_POIS)) { if (set_poisoned(p_ptr->poisoned + randint0(10) + 10, FALSE)) ident = TRUE; } break; } case SV_FOOD_BLINDNESS: { if (!res_save_default(RES_BLIND)) { if (set_blind(p_ptr->blind + randint0(200) + 200, FALSE)) ident = TRUE; } break; } case SV_FOOD_PARANOIA: { if (!fear_save_p(fear_threat_level())) ident = fear_add_p(FEAR_SCARED); break; } case SV_FOOD_CONFUSION: { if (!res_save_default(RES_CONF)) { if (set_confused(p_ptr->confused + randint0(10) + 10, FALSE)) ident = TRUE; } break; } case SV_FOOD_HALLUCINATION: { if (!res_save_default(RES_CHAOS)) { if (set_image(p_ptr->image + randint0(25) + 25, FALSE)) ident = TRUE; } break; } case SV_FOOD_PARALYSIS: { if (!p_ptr->free_act) { if (set_paralyzed(randint1(4), FALSE)) { ident = TRUE; } } else equip_learn_flag(OF_FREE_ACT); break; } case SV_FOOD_WEAKNESS: { take_hit(DAMAGE_NOESCAPE, damroll(6, 6), "poisonous food", -1); do_dec_stat(A_STR); ident = TRUE; break; } case SV_FOOD_SICKNESS: { take_hit(DAMAGE_NOESCAPE, damroll(6, 6), "poisonous food", -1); do_dec_stat(A_CON); ident = TRUE; break; } case SV_FOOD_STUPIDITY: { take_hit(DAMAGE_NOESCAPE, damroll(8, 8), "poisonous food", -1); do_dec_stat(A_INT); ident = TRUE; break; } case SV_FOOD_NAIVETY: { take_hit(DAMAGE_NOESCAPE, damroll(8, 8), "poisonous food", -1); do_dec_stat(A_WIS); ident = TRUE; break; } case SV_FOOD_UNHEALTH: { take_hit(DAMAGE_NOESCAPE, damroll(10, 10), "poisonous food", -1); do_dec_stat(A_CON); ident = TRUE; break; } case SV_FOOD_DISEASE: { take_hit(DAMAGE_NOESCAPE, damroll(10, 10), "poisonous food", -1); do_dec_stat(A_STR); ident = TRUE; break; } case SV_FOOD_CURE_POISON: { if (set_poisoned(0, TRUE)) ident = TRUE; break; } case SV_FOOD_CURE_BLINDNESS: { if (set_blind(0, TRUE)) ident = TRUE; break; } case SV_FOOD_CURE_PARANOIA: { if (p_ptr->afraid) { fear_clear_p(); ident = TRUE; } break; } case SV_FOOD_CURE_CONFUSION: { if (set_confused(0, TRUE)) ident = TRUE; break; } case SV_FOOD_CURE_SERIOUS: { if (hp_player(damroll(6, 8))) ident = TRUE; if (set_cut((p_ptr->cut / 2) - 50, TRUE)) ident = TRUE; break; } case SV_FOOD_RESTORE_STR: { if (do_res_stat(A_STR)) ident = TRUE; break; } case SV_FOOD_RESTORE_CON: { if (do_res_stat(A_CON)) ident = TRUE; break; } case SV_FOOD_RESTORING: { if (do_res_stat(A_STR)) ident = TRUE; if (do_res_stat(A_INT)) ident = TRUE; if (do_res_stat(A_WIS)) ident = TRUE; if (do_res_stat(A_DEX)) ident = TRUE; if (do_res_stat(A_CON)) ident = TRUE; if (do_res_stat(A_CHR)) ident = TRUE; break; } case SV_FOOD_RATION: case SV_FOOD_BISCUIT: case SV_FOOD_JERKY: case SV_FOOD_SLIME_MOLD: { msg_print("That tastes good."); ident = TRUE; break; } case SV_FOOD_AMBROSIA: { msg_print("That tastes divine!"); set_poisoned(0, TRUE); hp_player(damroll(15, 15)); do_res_stat(A_STR); do_res_stat(A_INT); do_res_stat(A_WIS); do_res_stat(A_DEX); do_res_stat(A_CON); do_res_stat(A_CHR); restore_level(); ident = TRUE; break; } case SV_FOOD_WAYBREAD: { msg_print("That tastes good."); set_poisoned(0, TRUE); hp_player(damroll(4, 8)); ident = TRUE; break; } case SV_FOOD_PINT_OF_ALE: case SV_FOOD_PINT_OF_WINE: { msg_print("That tastes good."); ident = TRUE; break; } } } if (prace_is_(RACE_SNOTLING) && object_is_mushroom(obj)) { int dur = lev + randint1(lev); set_fast(p_ptr->fast + dur, FALSE); set_shield(p_ptr->shield + dur, FALSE); set_hero(p_ptr->hero + dur, FALSE); set_tim_building_up(p_ptr->tim_building_up + dur, FALSE); } if (!object_is_aware(obj)) { virtue_add(VIRTUE_KNOWLEDGE, -1); virtue_add(VIRTUE_PATIENCE, -1); virtue_add(VIRTUE_CHANCE, 1); } /* We have tried it */ if (obj->tval == TV_FOOD) object_tried(obj); stats_on_use(obj, 1); /* The player is now aware of the object */ if (ident && !object_is_aware(obj)) { object_aware(obj); stats_on_notice(obj, 1); gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev); p_ptr->notice |= PN_OPTIMIZE_PACK; }
/*! * @brief モンスターの魔法一覧から戦術的に適さない魔法を除外する / * Remove the "bad" spells from a spell list * @param m_idx モンスターの構造体参照ポインタ * @param f4p モンスター魔法のフラグリスト1 * @param f5p モンスター魔法のフラグリスト2 * @param f6p モンスター魔法のフラグリスト3 * @return なし */ static void remove_bad_spells(int m_idx, u32b *f4p, u32b *f5p, u32b *f6p) { monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; u32b f4 = (*f4p); u32b f5 = (*f5p); u32b f6 = (*f6p); u32b smart = 0L; /* Too stupid to know anything */ if (r_ptr->flags2 & RF2_STUPID) return; /* Must be cheating or learning */ if (!smart_cheat && !smart_learn) return; /* Update acquired knowledge */ if (smart_learn) { /* Hack -- Occasionally forget player status */ /* Only save SM_FRIENDLY, SM_PET or SM_CLONED */ if (m_ptr->smart && (randint0(100) < 1)) m_ptr->smart &= (SM_FRIENDLY | SM_PET | SM_CLONED); /* Use the memorized flags */ smart = m_ptr->smart; } /* Cheat if requested */ if (smart_cheat) { /* Know basic info */ if (p_ptr->resist_acid) smart |= (SM_RES_ACID); if (IS_OPPOSE_ACID()) smart |= (SM_OPP_ACID); if (p_ptr->immune_acid) smart |= (SM_IMM_ACID); if (p_ptr->resist_elec) smart |= (SM_RES_ELEC); if (IS_OPPOSE_ELEC()) smart |= (SM_OPP_ELEC); if (p_ptr->immune_elec) smart |= (SM_IMM_ELEC); if (p_ptr->resist_fire) smart |= (SM_RES_FIRE); if (IS_OPPOSE_FIRE()) smart |= (SM_OPP_FIRE); if (p_ptr->immune_fire) smart |= (SM_IMM_FIRE); if (p_ptr->resist_cold) smart |= (SM_RES_COLD); if (IS_OPPOSE_COLD()) smart |= (SM_OPP_COLD); if (p_ptr->immune_cold) smart |= (SM_IMM_COLD); /* Know poison info */ if (p_ptr->resist_pois) smart |= (SM_RES_POIS); if (IS_OPPOSE_POIS()) smart |= (SM_OPP_POIS); /* Know special resistances */ if (p_ptr->resist_neth) smart |= (SM_RES_NETH); if (p_ptr->resist_lite) smart |= (SM_RES_LITE); if (p_ptr->resist_dark) smart |= (SM_RES_DARK); if (p_ptr->resist_fear) smart |= (SM_RES_FEAR); if (p_ptr->resist_conf) smart |= (SM_RES_CONF); if (p_ptr->resist_chaos) smart |= (SM_RES_CHAOS); if (p_ptr->resist_disen) smart |= (SM_RES_DISEN); if (p_ptr->resist_blind) smart |= (SM_RES_BLIND); if (p_ptr->resist_nexus) smart |= (SM_RES_NEXUS); if (p_ptr->resist_sound) smart |= (SM_RES_SOUND); if (p_ptr->resist_shard) smart |= (SM_RES_SHARD); if (p_ptr->reflect) smart |= (SM_IMM_REFLECT); /* Know bizarre "resistances" */ if (p_ptr->free_act) smart |= (SM_IMM_FREE); if (!p_ptr->msp) smart |= (SM_IMM_MANA); } /* Nothing known */ if (!smart) return; if (smart & SM_IMM_ACID) { f4 &= ~(RF4_BR_ACID); f5 &= ~(RF5_BA_ACID); f5 &= ~(RF5_BO_ACID); } else if ((smart & (SM_OPP_ACID)) && (smart & (SM_RES_ACID))) { if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_ACID); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_ACID); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ACID); } else if ((smart & (SM_OPP_ACID)) || (smart & (SM_RES_ACID))) { if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_ACID); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_ACID); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_ACID); } if (smart & (SM_IMM_ELEC)) { f4 &= ~(RF4_BR_ELEC); f5 &= ~(RF5_BA_ELEC); f5 &= ~(RF5_BO_ELEC); } else if ((smart & (SM_OPP_ELEC)) && (smart & (SM_RES_ELEC))) { if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_ELEC); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_ELEC); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ELEC); } else if ((smart & (SM_OPP_ELEC)) || (smart & (SM_RES_ELEC))) { if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_ELEC); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_ELEC); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_ELEC); } if (smart & (SM_IMM_FIRE)) { f4 &= ~(RF4_BR_FIRE); f5 &= ~(RF5_BA_FIRE); f5 &= ~(RF5_BO_FIRE); } else if ((smart & (SM_OPP_FIRE)) && (smart & (SM_RES_FIRE))) { if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_FIRE); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_FIRE); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_FIRE); } else if ((smart & (SM_OPP_FIRE)) || (smart & (SM_RES_FIRE))) { if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_FIRE); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_FIRE); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_FIRE); } if (smart & (SM_IMM_COLD)) { f4 &= ~(RF4_BR_COLD); f5 &= ~(RF5_BA_COLD); f5 &= ~(RF5_BO_COLD); f5 &= ~(RF5_BO_ICEE); } else if ((smart & (SM_OPP_COLD)) && (smart & (SM_RES_COLD))) { if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_COLD); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_COLD); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_COLD); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ICEE); } else if ((smart & (SM_OPP_COLD)) || (smart & (SM_RES_COLD))) { if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_COLD); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_COLD); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_COLD); if (int_outof(r_ptr, 20)) f5 &= ~(RF5_BO_ICEE); } if ((smart & (SM_OPP_POIS)) && (smart & (SM_RES_POIS))) { if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_POIS); if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_POIS); if (int_outof(r_ptr, 60)) f4 &= ~(RF4_BA_NUKE); if (int_outof(r_ptr, 60)) f4 &= ~(RF4_BR_NUKE); } else if ((smart & (SM_OPP_POIS)) || (smart & (SM_RES_POIS))) { if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_POIS); if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_POIS); } if (smart & (SM_RES_NETH)) { if (prace_is_(RACE_SPECTRE)) { f4 &= ~(RF4_BR_NETH); f5 &= ~(RF5_BA_NETH); f5 &= ~(RF5_BO_NETH); } else { if (int_outof(r_ptr, 20)) f4 &= ~(RF4_BR_NETH); if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BA_NETH); if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BO_NETH); } } if (smart & (SM_RES_LITE)) { if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_LITE); if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BA_LITE); } if (smart & (SM_RES_DARK)) { if (prace_is_(RACE_VAMPIRE)) { f4 &= ~(RF4_BR_DARK); f5 &= ~(RF5_BA_DARK); } else { if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_DARK); if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BA_DARK); } } if (smart & (SM_RES_FEAR)) { f5 &= ~(RF5_SCARE); } if (smart & (SM_RES_CONF)) { f5 &= ~(RF5_CONF); if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_CONF); } if (smart & (SM_RES_CHAOS)) { if (int_outof(r_ptr, 20)) f4 &= ~(RF4_BR_CHAO); if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BA_CHAO); } if (smart & (SM_RES_DISEN)) { if (int_outof(r_ptr, 40)) f4 &= ~(RF4_BR_DISE); } if (smart & (SM_RES_BLIND)) { f5 &= ~(RF5_BLIND); } if (smart & (SM_RES_NEXUS)) { if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_NEXU); f6 &= ~(RF6_TELE_LEVEL); } if (smart & (SM_RES_SOUND)) { if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_SOUN); } if (smart & (SM_RES_SHARD)) { if (int_outof(r_ptr, 40)) f4 &= ~(RF4_BR_SHAR); } if (smart & (SM_IMM_REFLECT)) { if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_COLD); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_FIRE); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_ACID); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_ELEC); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_NETH); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_WATE); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_MANA); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_PLAS); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_BO_ICEE); if (int_outof(r_ptr, 150)) f5 &= ~(RF5_MISSILE); } if (smart & (SM_IMM_FREE)) { f5 &= ~(RF5_HOLD); f5 &= ~(RF5_SLOW); } if (smart & (SM_IMM_MANA)) { f5 &= ~(RF5_DRAIN_MANA); } /* XXX XXX XXX No spells left? */ /* if (!f4 && !f5 && !f6) ... */ (*f4p) = f4; (*f5p) = f5; (*f6p) = f6; }
void display_weapon_info(doc_ptr doc, int hand) { object_type *o_ptr = equip_obj(p_ptr->weapon_info[hand].slot); char o_name[MAX_NLEN]; u32b flgs[TR_FLAG_SIZE]; int dd; int ds; int to_d = 0; int to_h = 0; int mult; critical_t crit = {0}; int crit_pct = 0; int num_blow = NUM_BLOWS(hand); bool force = FALSE; doc_ptr cols[2] = {0}; if (p_ptr->weapon_info[hand].wield_how == WIELD_NONE) return; if (!o_ptr) return; dd = o_ptr->dd + p_ptr->weapon_info[hand].to_dd; ds = o_ptr->ds + p_ptr->weapon_info[hand].to_ds; if (object_is_known(o_ptr)) { to_d = o_ptr->to_d; to_h = o_ptr->to_h; } switch (display_weapon_mode) { case MAULER_STUNNING_BLOW: case MAULER_CRITICAL_BLOW: case MAULER_CRUSHING_BLOW: case MAULER_KNOCKBACK: num_blow = 100; break; case MAULER_KNOCKOUT_BLOW: num_blow = 100; to_h -= 50; break; case PY_POWER_ATTACK: to_h += 10; to_d += p_ptr->lev / 2; break; } weapon_flags_known(hand, flgs); if ( (have_flag(flgs, TR_FORCE_WEAPON) || p_ptr->tim_force) && (p_ptr->csp > o_ptr->dd*o_ptr->ds/5) ) { force = TRUE; } if (weaponmaster_get_toggle() == TOGGLE_SHIELD_BASH && object_is_shield(o_ptr)) { dd = 3 + p_ptr->weapon_info[hand].to_dd; ds = o_ptr->ac + p_ptr->weapon_info[hand].to_ds; if (object_is_known(o_ptr)) { to_h = o_ptr->to_a; to_d = o_ptr->to_a; to_h += 2*o_ptr->to_h; to_d += 2*o_ptr->to_d; } } mult = 100; if (have_flag(flgs, TR_VORPAL2)) mult = mult * 5 / 3; else if (have_flag(flgs, TR_VORPAL)) mult = mult * 11 / 9; mult += mult * p_ptr->weapon_info[hand].to_mult / 100; if (display_weapon_mode == MAULER_CRUSHING_BLOW) { int d = p_ptr->lev/5; int n = 10*(1 + d)/2; /* scale by 10 */ mult = mult * (50 + n)/30; } if (!have_flag(flgs, TR_ORDER)) { const int attempts = 10 * 1000; int i; int crits = 0; /* Compute Average Effects of Criticals by sampling */ for (i = 0; i < attempts; i++) { critical_t tmp = critical_norm(o_ptr->weight, to_h, p_ptr->weapon_info[hand].to_h, display_weapon_mode, hand); if (tmp.desc) { crit.mul += tmp.mul; crit.to_d += tmp.to_d; crits++; } else crit.mul += 100; } crit.mul = crit.mul / attempts; crit.to_d = crit.to_d * 100 / attempts; crit_pct = crits * 1000 / attempts; } else crit.mul = 100; /* Display in 2 columns, side by side */ cols[0] = doc_alloc(60); cols[1] = doc_alloc(10); /* Column #1 */ object_desc(o_name, o_ptr, OD_COLOR_CODED | OD_NAME_AND_ENCHANT); if (prace_is_(RACE_MON_SWORD)) doc_printf(cols[0], "<color:y> You :</color> <indent><style:indent>%s</style></indent>\n", o_name); else doc_printf(cols[0], "<color:y> Hand #%d:</color> <indent><style:indent>%s</style></indent>\n", hand+1, o_name); doc_printf(cols[0], " %-7.7s: %d.%d lbs\n", "Weight", o_ptr->weight/10, o_ptr->weight%10); if (weaponmaster_get_toggle() == TOGGLE_SHIELD_BASH) { assert(o_ptr->tval == TV_SHIELD); doc_printf(cols[0], " %-7.7s: %dd%d (%+d,%+d)\n", "Bash", dd, ds, to_h, to_d); doc_printf(cols[0], " %-7.7s: %s (%+d To Hit)\n", "Profic", skills_shield_describe_current(o_ptr->sval), skills_shield_calc_bonus(o_ptr->sval)); } else { doc_printf(cols[0], " %-7.7s: %s (%+d To Hit)\n", "Profic", skills_weapon_describe_current(o_ptr->tval, o_ptr->sval), skills_weapon_calc_bonus(o_ptr->tval, o_ptr->sval)); } doc_printf(cols[0], " %-7.7s: %d + %d = %d\n", "To Hit", to_h, p_ptr->weapon_info[hand].to_h, to_h + p_ptr->weapon_info[hand].to_h); doc_printf(cols[0], " %-7.7s: %d + %d = %d\n", "To Dam", to_d, p_ptr->weapon_info[hand].to_d, to_d + p_ptr->weapon_info[hand].to_d); doc_printf(cols[0], " %-7.7s: %d.%2.2d\n", "Blows", num_blow/100, num_blow%100); if (p_ptr->weapon_info[hand].dual_wield_pct < 1000) { doc_printf(cols[0], " %-7.7s: %d.%d%%\n", "Skill", p_ptr->weapon_info[hand].dual_wield_pct/ 10, p_ptr->weapon_info[hand].dual_wield_pct % 10); } mult = mult * crit.mul / 100; to_d = to_d + crit.to_d/100 + p_ptr->weapon_info[hand].to_d; doc_printf(cols[0], "<color:G> %-7.7s</color>\n", "Damage"); if (!have_flag(flgs, TR_ORDER)) { if (crit.to_d) { doc_printf(cols[0], " %-7.7s: %d.%02dx + %d.%02d\n", "Crits", crit.mul/100, crit.mul%100, crit.to_d/100, crit.to_d%100); } else { doc_printf(cols[0], " %-7.7s: %d.%02dx (%d.%d%%)\n", "Crits", crit.mul/100, crit.mul%100, crit_pct / 10, crit_pct % 10); } } if (p_ptr->weapon_info[hand].to_mult) { int m = 100 + p_ptr->weapon_info[hand].to_mult; doc_printf(cols[0], " %-7.7s: %d.%02dx\n", "Mauler", m / 100, m % 100); } _display_weapon_slay(mult, 100, FALSE, num_blow, dd, ds, to_d, "Normal", TERM_WHITE, cols[0]); if (force) _display_weapon_slay(mult, 100, force, num_blow, dd, ds, to_d, "Force", TERM_L_BLUE, cols[0]); if (p_ptr->tim_slay_sentient) _display_weapon_slay(mult, 200, force, num_blow, dd, ds, to_d, "Sent.", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_ANIMAL)) _display_weapon_slay(mult, 400, force, num_blow, dd, ds, to_d, "Animals", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_ANIMAL)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Animals", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_EVIL)) _display_weapon_slay(mult, 350, force, num_blow, dd, ds, to_d, "Evil", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_EVIL)) _display_weapon_slay(mult, 200, force, num_blow, dd, ds, to_d, "Evil", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_SLAY_GOOD)) _display_weapon_slay(mult, 200, force, num_blow, dd, ds, to_d, "Good", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_SLAY_LIVING)) _display_weapon_slay(mult, 200, force, num_blow, dd, ds, to_d, "Living", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_HUMAN)) _display_weapon_slay(mult, 400, force, num_blow, dd, ds, to_d, "Human", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_HUMAN)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Human", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_UNDEAD)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Undead", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_UNDEAD)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Undead", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_DEMON)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Demons", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_DEMON)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Demons", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_ORC)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Orcs", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_ORC)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Orcs", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_TROLL)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Trolls", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_TROLL)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Trolls", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_GIANT)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Giants", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_GIANT)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Giants", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_KILL_DRAGON)) _display_weapon_slay(mult, 500, force, num_blow, dd, ds, to_d, "Dragons", TERM_YELLOW, cols[0]); else if (have_flag(flgs, TR_SLAY_DRAGON)) _display_weapon_slay(mult, 300, force, num_blow, dd, ds, to_d, "Dragons", TERM_YELLOW, cols[0]); if (have_flag(flgs, TR_BRAND_ACID)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Acid", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_ELEC)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Elec", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_FIRE)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Fire", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_COLD)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Cold", TERM_RED, cols[0]); if (have_flag(flgs, TR_BRAND_POIS)) _display_weapon_slay(mult, 250, force, num_blow, dd, ds, to_d, "Poison", TERM_RED, cols[0]); if (p_ptr->weapon_info[hand].wield_how == WIELD_TWO_HANDS) { if (p_ptr->weapon_info[hand].omoi) doc_insert(cols[0], " Your weapon requires two hands to wield properly.\n"); } if (p_ptr->weapon_info[hand].info) { byte a = p_ptr->weapon_info[hand].info_attr; if (!a) a = TERM_WHITE; /* uninitialized is TERM_DARK???! */ doc_printf(cols[0], " <color:%c>%s</color>\n", attr_to_attr_char(a), p_ptr->weapon_info[hand].info); } /* Column #1 */ doc_insert(cols[1], "<color:G>Accuracy</color>\n"); doc_insert(cols[1], " AC Hit\n"); doc_printf(cols[1], "%3d %2d%%\n", 25, hit_chance(hand, to_h, 25)); doc_printf(cols[1], "%3d %2d%%\n", 50, hit_chance(hand, to_h, 50)); doc_printf(cols[1], "%3d %2d%%\n", 75, hit_chance(hand, to_h, 75)); doc_printf(cols[1], "%3d %2d%%\n", 100, hit_chance(hand, to_h, 100)); doc_printf(cols[1], "%3d %2d%%\n", 125, hit_chance(hand, to_h, 125)); doc_printf(cols[1], "%3d %2d%%\n", 150, hit_chance(hand, to_h, 150)); doc_printf(cols[1], "%3d %2d%%\n", 175, hit_chance(hand, to_h, 175)); doc_printf(cols[1], "%3d %2d%%\n", 200, hit_chance(hand, to_h, 200)); /* Assemble the result */ doc_insert_cols(doc, cols, 2, 1); doc_free(cols[0]); doc_free(cols[1]); }
/* * Allocates some objects (using "place" and "type") */ static void alloc_object(int set, int typ, int num) { int y = 0, x = 0, k; /* A small level has few objects. */ num = MAX(1, num * cur_hgt * cur_wid / (MAX_HGT*MAX_WID)); /* Diligent players should be encouraged to explore more! */ if (typ == ALLOC_TYP_OBJECT || typ == ALLOC_TYP_GOLD) num = num * (625 + virtue_current(VIRTUE_DILIGENCE)) / 625; for (k = 0; k < num; k++) { object_type forge; int k_idx; if (!_get_loc(set, &x, &y)) { if (cheat_room) msg_print("Warning! Could not place object!"); return; } switch (typ) { case ALLOC_TYP_RUBBLE: place_rubble(y, x); cave[y][x].info &= ~(CAVE_FLOOR); break; case ALLOC_TYP_TRAP: place_trap(y, x); cave[y][x].info &= ~(CAVE_FLOOR); break; case ALLOC_TYP_GOLD: place_gold(y, x); break; case ALLOC_TYP_OBJECT: /* Comment: Monsters drop objects at (ML + DL)/2. In practice, this means that your best drops are just laying on the ground, and this encourages recall scumming for end game resources such as wands of rockets. Note: Vaults are not affected and we want to encourage these! Room templates need some thought ... */ if (base_level > 31) { int n = base_level - 30; object_level = 30 + n/2 + randint1(n/2); } else object_level = base_level; /* paranoia */ place_object(y, x, 0L); object_level = base_level; break; case ALLOC_TYP_FOOD: if (prace_is_(RACE_ENT)) k_idx = lookup_kind(TV_POTION, SV_POTION_WATER); else k_idx = lookup_kind(TV_FOOD, SV_FOOD_RATION); object_prep(&forge, k_idx); obj_make_pile(&forge); drop_near(&forge, -1, y, x); break; case ALLOC_TYP_LIGHT: if (one_in_(3)) k_idx = lookup_kind(TV_FLASK, SV_FLASK_OIL); else k_idx = lookup_kind(TV_LITE, SV_LITE_LANTERN); object_prep(&forge, k_idx); apply_magic(&forge, dun_level, 0); obj_make_pile(&forge); drop_near(&forge, -1, y, x); break; case ALLOC_TYP_RECALL: k_idx = lookup_kind(TV_SCROLL, SV_SCROLL_WORD_OF_RECALL); object_prep(&forge, k_idx); /*obj_make_pile(&forge);*/ drop_near(&forge, -1, y, x); break; case ALLOC_TYP_SKELETON: k_idx = lookup_kind(TV_CORPSE, SV_SKELETON); object_prep(&forge, k_idx); apply_magic(&forge, dun_level, 0); drop_near(&forge, -1, y, x); break; } } }
int calculate_fail_rate(int level, int base_fail, int stat_idx) { int fail = base_fail; int min = 0; caster_info *caster_ptr = get_caster_info(); if (p_ptr->lev < level) return 100; if (caster_ptr && (caster_ptr->options & CASTER_NO_SPELL_FAIL)) return 0; if (base_fail == 0) return 0; /* Adjust Fail Rate */ fail -= 3 * (p_ptr->lev - level); fail += p_ptr->to_m_chance; fail -= 3 * (adj_mag_stat[stat_idx] - 1); if (p_ptr->heavy_spell) fail += 20; { if (p_ptr->dec_mana && p_ptr->easy_spell) fail -= 4; else if (p_ptr->easy_spell) fail -= 3; else if (p_ptr->dec_mana) fail -= 2; } /* Apply Min Fail Rate */ min = adj_mag_fail[stat_idx]; if (caster_ptr && min < caster_ptr->min_fail) min = caster_ptr->min_fail; if (mut_present(MUT_ARCANE_MASTERY)) fail -= 3; if (prace_is_(RACE_DEMIGOD) && p_ptr->psubrace == DEMIGOD_ATHENA) { fail -= 2; if (min > 0) min -= 1; } if (fail < min) fail = min; /* Stunning affects even 0% fail spells */ if (p_ptr->stun > 50) fail += 25; else if (p_ptr->stun) fail += 15; /* Max Fail Rate */ if (fail > 95) fail = 95; /* Some effects violate the Min/Max Fail Rates */ if (p_ptr->heavy_spell) fail += 5; /* Fail could go to 100% */ if (p_ptr->dec_mana) fail--; /* 5% casters could get 4% fail rates */ if (fail < 0) fail = 0; if (fail > 100) fail = 100; return fail; }
static _blow_info_t _get_blow_info(int hand) { _blow_info_t result = {0}; int arm = hand / 2; object_type *o_ptr = equip_obj(p_ptr->weapon_info[hand].slot); if (!o_ptr) return result; /* TODO: Use race_ptr and class_ptr instead of this giant switch ... */ switch (p_ptr->pclass) { case CLASS_WARRIOR: result.num = 600; result.wgt = 70; result.mul = 50 + p_ptr->lev/2; break; case CLASS_MAULER: result.num = 175; result.wgt = 280; result.mul = 75; break; case CLASS_BERSERKER: result.num = 600; result.wgt = 70; result.mul = 75; break; case CLASS_RAGE_MAGE: result.num = 300; result.wgt = 70; result.mul = 30; break; case CLASS_MAGE: case CLASS_NECROMANCER: case CLASS_BLOOD_MAGE: case CLASS_HIGH_MAGE: case CLASS_BLUE_MAGE: result.num = 400; result.wgt = 100; result.mul = 20; break; case CLASS_WARLOCK: result.num = 400; result.wgt = 100; result.mul = 35; switch (p_ptr->psubclass) { case WARLOCK_DRAGONS: if ( p_ptr->riding && (object_is_(o_ptr, TV_POLEARM, SV_LANCE) || object_is_(o_ptr, TV_POLEARM, SV_HEAVY_LANCE)) ) { result.mul = 65; } break; case WARLOCK_ANGELS: case WARLOCK_DEMONS: result.num = 450; break; case WARLOCK_HOUNDS: result.num = 475; break; case WARLOCK_GIANTS: result.wgt = 200; result.mul = 50 + p_ptr->lev/5; result.num = 500; break; } break; case CLASS_PSION: result.num = 400; result.wgt = 100; result.mul = 30; break; case CLASS_PRIEST: case CLASS_MAGIC_EATER: case CLASS_MINDCRAFTER: result.num = 500; result.wgt = 100; result.mul = 35; break; case CLASS_DEVICEMASTER: result.num = 400; result.wgt = 100; result.mul = 35; if (p_ptr->psubclass == DEVICEMASTER_POTIONS || p_ptr->psubclass == DEVICEMASTER_SCROLLS) result.num = 500; break; case CLASS_ROGUE: result.num = 525; result.wgt = 40; result.mul = 30; if (o_ptr->weight < 50) result.num = 600; break; case CLASS_SCOUT: result.num = 400; result.wgt = 70; result.mul = 25; break; case CLASS_RANGER: result.num = 500; result.wgt = 70; result.mul = 40; break; case CLASS_PALADIN: case CLASS_SAMURAI: result.num = 550; result.wgt = 70; result.mul = 45; break; case CLASS_MYSTIC: result.num = 100; result.wgt = 100; result.mul = 10; break; case CLASS_WEAPONSMITH: case CLASS_RUNE_KNIGHT: result.num = 525; result.wgt = 150; result.mul = 55; break; case CLASS_WEAPONMASTER: result.num = weaponmaster_get_max_blows(o_ptr, hand); result.wgt = 70; result.mul = 50; break; case CLASS_WARRIOR_MAGE: case CLASS_RED_MAGE: result.num = 525; result.wgt = 70; result.mul = 30; break; case CLASS_CHAOS_WARRIOR: result.num = 550; result.wgt = 70; result.mul = 45; break; case CLASS_MONK: result.num = 500; result.wgt = 60; result.mul = 30; break; case CLASS_TOURIST: case CLASS_TIME_LORD: result.num = 400; result.wgt = 100; result.mul = 30; break; case CLASS_ARCHAEOLOGIST: result.num = 400; result.wgt = 70; result.mul = 30; if (archaeologist_is_favored_weapon(o_ptr)) { result.num = 500; result.mul = 40; } break; case CLASS_BLOOD_KNIGHT: result.num = 300; result.wgt = 150; result.mul = 30; break; case CLASS_DUELIST: result.num = 100; result.wgt = 70; result.mul = 40; break; case CLASS_IMITATOR: result.num = 550; result.wgt = 70; result.mul = 40; break; case CLASS_WILD_TALENT: result.num = 450; result.wgt = 70; result.mul = 40; break; case CLASS_BEASTMASTER: result.num = 500; result.wgt = 70; result.mul = 35; break; case CLASS_CAVALRY: { u32b flgs[TR_FLAG_SIZE]; object_flags(o_ptr, flgs); if (p_ptr->riding && have_flag(flgs, TR_RIDING)) {result.num = 550; result.wgt = 70; result.mul = 65;} else {result.num = 500; result.wgt = 100; result.mul = 35;} break; } case CLASS_SORCERER: result.num = 100; result.wgt = 1; result.mul = 10; break; case CLASS_ARCHER: case CLASS_BARD: result.num = 450; result.wgt = 70; result.mul = 20; break; case CLASS_FORCETRAINER: result.num = 400; result.wgt = 60; result.mul = 20; break; case CLASS_MIRROR_MASTER: case CLASS_SNIPER: result.num = 400; result.wgt = 100; result.mul = 30; break; case CLASS_NINJA: result.num = 425; result.wgt = 20; result.mul = 10; break; case CLASS_MONSTER: result.num = 500; result.wgt = 70; result.mul = 50; if (prace_is_(RACE_MON_LICH)) { result.num = 400; result.mul = 30; } else if (prace_is_(RACE_MON_POSSESSOR)) { result.num = 400; } else if (prace_is_(RACE_MON_MIMIC)) { result.num = 400; } else if (prace_is_(RACE_MON_TROLL)) { result.num = 550; } else if (prace_is_(RACE_MON_GIANT)) { result.num = 550; result.mul = 50 + p_ptr->lev/5; result.wgt = 200; if (giant_is_(GIANT_HRU) && p_ptr->lev >= 40) result.mul = 80; } else if ( prace_is_(RACE_MON_JELLY) || demon_is_(DEMON_KHORNE) ) { result.num = 600; result.mul = 50 + p_ptr->lev/5; } else if (prace_is_(RACE_MON_LEPRECHAUN)) { result.num = 300; result.mul = 20; } else if (prace_is_(RACE_MON_SWORD)) { result.num = 525; if (p_ptr->lev >= 45) /* Death Scythes retaliate! */ result.num = 300; } else if (prace_is_(RACE_MON_GOLEM)) { result.num = 100; } break; } if (hex_spelling(HEX_XTRA_MIGHT) || hex_spelling(HEX_BUILDING) || p_ptr->tim_building_up) { result.wgt /= 2; result.mul += 20; } /* Xorns and Mariliths have multiple sets of arms */ if (arm > 0) result.num -= 100; if (result.num < 100) result.num = 100; if (o_ptr->tval == TV_SWORD && o_ptr->sval == SV_POISON_NEEDLE) result.num = 100; return result; }
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; }