/* * Become aware of a lot of objects */ static void do_cmd_wiz_learn(void) { int i; object_type *i_ptr; object_type object_type_body; /* Scan every object */ for (i = 1; i < z_info->k_max; i++) { object_kind *k_ptr = &k_info[i]; /* Induce awareness */ if (k_ptr->level <= p_ptr->command_arg) { /* Get local object */ i_ptr = &object_type_body; /* Prepare object */ object_prep(i_ptr, i); /* Awareness */ object_aware(i_ptr); } } }
/* * Become aware of a lot of objects */ static void do_cmd_wiz_learn(void) { int i; object_type forge; object_type *q_ptr; /* Scan every object */ for (i = 1; i < max_k_idx; i++) { object_kind *k_ptr = &k_info[i]; /* Induce awareness */ if (k_ptr->level <= p_ptr->command_arg) { /* Get local object */ q_ptr = &forge; /* Prepare object */ object_prep(q_ptr, i); /* Awareness */ object_aware(q_ptr); } } }
static void _upgrade_weapon(int tval, int sval) { object_type *o_ptr = _weapon(); object_prep(o_ptr, lookup_kind(tval, sval)); o_ptr->to_h = p_ptr->lev / 5; o_ptr->to_d = p_ptr->lev / 3; add_flag(o_ptr->art_flags, TR_NO_REMOVE); object_aware(o_ptr); object_known(o_ptr); o_ptr->ident |= IDENT_MENTAL; p_ptr->update |= PU_BONUS; p_ptr->window |= PW_INVEN | PW_EQUIP | PW_PLAYER; }
bool quest_poison_quest_hook(char *fmt) { object_type forge, *q_ptr; s32b q_idx; q_idx = get_next_arg(fmt); if (q_idx != QUEST_POISON) return FALSE; q_ptr = &forge; object_prep(q_ptr, lookup_kind(TV_POTION2, SV_POTION2_CURE_WATER)); q_ptr->number = 99; object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; q_ptr->note = quark_add("quest"); (void)inven_carry(q_ptr, FALSE); del_hook(HOOK_INIT_QUEST, quest_poison_quest_hook); process_hooks_restart = TRUE; return FALSE; }
/* * Scatter some "great" objects near the player */ void acquirement(s32b y1, s32b x1, s32b num, bool great, bool known) { object_type *i_ptr; /* Acquirement */ while (num--) { /* Get local object */ i_ptr = make_object(TRUE, great, NULL); /* Make a good (or great) object (if possible) */ if (i_ptr == NULL) return; if (known) { object_aware(i_ptr); object_known(i_ptr); } /* Drop the object */ drop_near(i_ptr, -1, y1, x1); } }
/* * Dump the object information a format easily parsed by a spreadsheet. * * Original function by -EB- (probably), revisions by -LM- & JG. */ void write_a_info_txt(void) { int i, j, bc; int dlen; char buf[1024]; int fd; FILE *fff = NULL; cptr desc; artifact_type *a_ptr; /* We allow 75 characters on the line (plus 2) */ u16b line_length = 75; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_EDIT, "a_output.txt"); /* Check for existing file */ fd = fd_open(buf, O_RDONLY); /* Existing file */ if (fd >= 0) { char out_val[160]; /* Close the file */ fd_close(fd); /* Build query */ sprintf(out_val, "Replace existing file %s? ", buf); /* Ask */ if (get_check(out_val)) fd = -1; } /* Open the non-existing file */ if (fd < 0) fff = my_fopen(buf, "w"); /* No output file - fail */ if (!fff) return; /* Write a note */ fprintf(fff, "# File: a_info.txt (autogenerated)\n\n"); /* Read and print out all the objects */ for (i = 0; i < z_info->art_norm_max; i++) { int counter = 1; char o_name[80]; object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Get the object */ a_ptr = &a_info[i]; /* Ignore unused objects */ if (!strlen(a_ptr->name)) { fprintf(fff, "## empty space (available for artifact) ##\n\n"); continue; } /* Perform any translations */ /* Write New/Number/Name */ fprintf(fff, "N:%d:%s\n", i, a_ptr->name); /* Write the complete name of the artifact*/ make_fake_artifact(i_ptr, i); /*identify it*/ /* Identify it */ object_aware(i_ptr); object_known(i_ptr); i_ptr->ident |= (IDENT_MENTAL); /* Get a description to dump */ object_desc(o_name, sizeof(o_name), i_ptr, TRUE, 0); /*dump the long name*/ fprintf(fff, "desc:%d: # %s\n", i, o_name); /* Write I: line */ fprintf(fff, "I:%d:%d:%d:%d\n", i, a_ptr->tval, a_ptr->sval, a_ptr->pval); /* Write W: line */ fprintf(fff, "W:%d:%d:%d:%d:%d\n", i, a_ptr->a_level, a_ptr->a_rarity, a_ptr->weight, a_ptr->cost); /* Write P: line */ fprintf(fff, "P:%d:%d:%d:d:%d:%d:%d:%d\n", i, a_ptr->ac, a_ptr->dd, a_ptr->ds, a_ptr->to_h, a_ptr->to_d, a_ptr->to_a); /* Get the flags, store flag text in a format easily parsed by a * database, but pretty much illegible to a person. */ dump_flags(fff, a_ptr->a_flags1, 1, i); dump_flags(fff, a_ptr->a_flags2, 2, i); dump_flags(fff, a_ptr->a_flags3, 3, i); dump_flags(fff, a_ptr->a_native, 4, i); /* Write the A line */ fprintf(fff, "A:%d:%d:%d:%d\n", i, a_ptr->activation, a_ptr->time, a_ptr->randtime); /* Acquire the description */ desc = a_text + a_ptr->text; dlen = strlen(desc); if (dlen < 1) { /* Space between entries */ fprintf(fff, "\n\n\n"); continue; } /* Write Description */ for (j = 0; j < dlen;) { char buf[160], *t; /* Initialize */ t = buf; bc = 0; /* Build this line */ while (TRUE) { /* Insert this character, count it */ *t++ = desc[j++]; /* Oops. Line is too long. */ if (bc++ >= line_length) { /* Parse backwards until we find a space */ while (!my_isspace(desc[j-1]) && (bc-- > 40)) { j--; t--; } /* Time to end this line */ *t++ = '\0'; break; } /* All done */ if (j >= dlen) { /* Time to end this line */ *t++ = '\0'; break; } } /* Done with this line; write it */ fprintf(fff, "D-%d:%d:%s\n", counter, i, buf); counter++; } /* * Print out empty lines, so all objects have * an equal number of lines * makes parsing and combining the description easier */ for (; counter <+ 12; counter++) { fprintf(fff, "D-%d:%d\n", counter, i); } /* Space between entries */ fprintf(fff, "\n\n\n"); } /* Done */ fclose(fff); }
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); }
/* * Eat some food (from the pack or floor) */ void do_cmd_eat_food(void) { int item, ident, lev; /* Must be true to let us cancel */ bool cancel = TRUE; object_type *o_ptr; cptr q, s; int power; /* Restrict choices to food */ item_tester_tval = TV_FOOD; /* Get an item */ q = "Eat which item? "; s = "You have nothing to eat."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_FEATU))) return; /* Get the feature */ if (item >= INVEN_TOTAL+1) { object_type object_type_body; o_ptr = &object_type_body; if (!make_feat(o_ptr, cave_feat[p_ptr->py][p_ptr->px])) return; } /* Get the item (in the pack) */ else if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Sound */ sound(MSG_EAT); /* Take a (partial) turn */ if ((variant_fast_floor) && (item < 0)) p_ptr->energy_use = 50; else if ((variant_fast_equip) && (item >= INVEN_WIELD)) p_ptr->energy_use = 50; else p_ptr->energy_use = 100; /* Identity not known yet */ ident = FALSE; /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Get food effect */ get_spell(&power, "use", o_ptr, FALSE); /* Paranoia */ if (power < 0) return; /* Apply food effect */ if (process_spell_eaten(power,0,&cancel)) ident = TRUE; /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* We have tried it */ object_tried(o_ptr); /* The player is now aware of the object */ if (ident && !object_aware_p(o_ptr)) { object_aware(o_ptr); gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev); }
/* * Activate (zap) a Rod * * Unstack fully charged rods as needed. * * Hack -- rods of perception/banishment can be "cancelled" * All rods can be cancelled at the "Direction?" prompt */ void do_cmd_zap_rod(void) { int item; bool ident; object_type *o_ptr; cptr q, s; /* Restrict choices to rods */ item_tester_tval = TV_ROD; /* Get an item */ q = "Zap which rod? "; s = "You have no rod to zap."; 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]; } /* Mega-Hack -- refuse to zap a pile from the ground */ if ((item < 0) && (o_ptr->number > 1)) { msg_print("You must first pick up the rods."); return; } /* Zap the rod */ if (!use_object(o_ptr, &ident)) return; /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Tried the object */ object_tried(o_ptr); /* Successfully determined the object function */ if (ident && !object_aware_p(o_ptr)) { /* Object level */ int lev = k_info[o_ptr->k_idx].level; object_aware(o_ptr); gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev); } /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); /* XXX Hack -- unstack if necessary */ if ((item >= 0) && (o_ptr->number > 1) && (o_ptr->pval > 0)) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Restore "charge" */ o_ptr->pval = 0; /* Unstack the used item */ o_ptr->number--; p_ptr->total_weight -= i_ptr->weight; item = inven_carry(i_ptr); /* Message */ msg_print("You unstack your rod."); } }
/** * Hack - Know inventory and home items upon death */ static void death_knowledge(void) { int i, which = 0; object_type *o_ptr; store_type *st_ptr = NULL; /* Get the store number of the home */ if (OPT(adult_dungeon)) which = NUM_TOWNS_SMALL * 4 + STORE_HOME; else { for (i = 0; i < NUM_TOWNS; i++) { /* Found the town */ if (p_ptr->home == towns[i]) { which += (i < NUM_TOWNS_SMALL ? 3 : STORE_HOME); break; } /* Next town */ else which += (i < NUM_TOWNS_SMALL ? MAX_STORES_SMALL : MAX_STORES_BIG); } } /* Hack -- Know everything in the inven/equip */ for (i = 0; i < ALL_INVEN_TOTAL; i++) { o_ptr = &p_ptr->inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Aware and Known */ object_aware(o_ptr); object_known(o_ptr); /* Fully known */ cf_union(o_ptr->id_curse, o_ptr->flags_curse); } /* Thralls sometimes (often!) don't have a home */ if (p_ptr->home) { /* Activate the store */ st_ptr = &store[which]; /* Hack -- Know everything in the home */ for (i = 0; i < st_ptr->stock_num; i++) { o_ptr = &st_ptr->stock[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Aware and Known */ object_aware(o_ptr); object_known(o_ptr); /* Fully known */ cf_union(o_ptr->id_curse, o_ptr->flags_curse); } } history_unmask_unknown(); /* Hack -- Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Handle stuff */ handle_stuff(); }
/* * Aim a wand (from the pack or floor). * * Use a single charge from a single item. * Handle "unstacking" in a logical manner. * * For simplicity, you cannot use a stack of items from the * ground. This would require too much nasty code. * * There are no wands which can "destroy" themselves, in the inventory * or on the ground, so we can ignore this possibility. Note that this * required giving "wand of wonder" the ability to ignore destruction * by electric balls. * * All wands can be "cancelled" at the "Direction?" prompt for free. * * Note that the basic "bolt" wands do slightly less damage than the * basic "bolt" rods, but the basic "ball" wands do the same damage * as the basic "ball" rods. */ void do_cmd_aim_wand(void) { int item, lev; bool ident; object_type *o_ptr; cptr q, s; /* Restrict choices to wands */ item_tester_tval = TV_WAND; /* Get an item */ q = "Aim which wand? "; s = "You have no wand to aim."; 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]; } /* Mega-Hack -- refuse to aim a pile from the ground */ if ((item < 0) && (o_ptr->number > 1)) { msg_print("You must first pick up the wands."); return; } /* Aim the wand */ if (!use_object(o_ptr, &ident)) return; /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Mark it as tried */ object_tried(o_ptr); /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Apply identification */ 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); /* Use a single charge */ o_ptr->pval--; /* Hack -- unstack if necessary */ if ((item >= 0) && (o_ptr->number > 1)) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Restore the charges */ o_ptr->pval++; /* Unstack the used item */ o_ptr->number--; p_ptr->total_weight -= i_ptr->weight; item = inven_carry(i_ptr); /* Message */ msg_print("You unstack your wand."); } /* Describe the charges in the pack */ if (item >= 0) { inven_item_charges(item); } /* Describe the charges on the floor */ else { floor_item_charges(0 - item); } }
/* * Eat some food (from the pack or floor) */ void do_cmd_eat_food(void) { int item, lev; bool ident; object_type *o_ptr; cptr q, s; /* Restrict choices to food */ item_tester_tval = TV_FOOD; /* Get an item */ q = "Eat which item? "; s = "You have nothing to eat."; 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]; } /* Sound */ sound(MSG_EAT); /* Take a turn */ p_ptr->energy_use = 100; /* Identity not known yet */ ident = FALSE; /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Eat the food */ use_object(o_ptr, &ident); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* We have tried it */ object_tried(o_ptr); /* The player is now aware of the object */ 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); /* Destroy a food in the pack */ if (item >= 0) { inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); } /* Destroy a food on the floor */ else { floor_item_increase(0 - item, -1); floor_item_describe(0 - item); floor_item_optimize(0 - item); } }
/* * 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); } }
/* * Use a staff * * One charge of one staff disappears. * * Hack -- staffs of identify can be "cancelled". */ void do_cmd_use_staff(void) { int item, chance, lev; bool ident; object_type *o_ptr; bool use_charge; cptr q, s; /* Restrict choices to staves */ item_tester_tval = TV_STAFF; /* Get an item */ q = "Use which staff? "; s = "You have no staff to use."; 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]; } /* Mega-Hack -- refuse to use a pile from the ground */ if ((item < 0) && (o_ptr->number > 1)) { msg_print("You must first pick up the staffs."); return; } /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ ident = FALSE; /* Extract the item level */ lev = k_info[o_ptr->k_idx].level; /* Base chance of success */ chance = p_ptr->skill_dev; /* Confusion hurts skill */ if (p_ptr->confused) chance = chance / 2; /* High level objects are harder */ chance = chance - ((lev > 50) ? 50 : lev); /* Give everyone a (slight) chance */ if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) { chance = USE_DEVICE; } /* Roll for usage */ if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { if (flush_failure) flush(); msg_print("You failed to use the staff properly."); return; } /* Notice empty staffs */ if (o_ptr->pval <= 0) { if (flush_failure) flush(); msg_print("The staff has no charges left."); o_ptr->ident |= (IDENT_EMPTY); p_ptr->notice |= (PN_COMBINE | PN_REORDER); p_ptr->window |= (PW_INVEN); return; } /* Sound */ sound(MSG_ZAP); /* Use the staff */ use_charge = use_object(o_ptr, &ident); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Tried the item */ 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 -- some uses are "free" */ if (!use_charge) return; /* Use a single charge */ o_ptr->pval--; /* XXX Hack -- unstack if necessary */ if ((item >= 0) && (o_ptr->number > 1)) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Restore the charges */ o_ptr->pval++; /* Unstack the used item */ o_ptr->number--; p_ptr->total_weight -= i_ptr->weight; item = inven_carry(i_ptr); /* Message */ msg_print("You unstack your staff."); } /* Describe charges in the pack */ if (item >= 0) { inven_item_charges(item); } /* Describe charges on the floor */ else { floor_item_charges(0 - item); } }
static void do_cmd_eat_food_aux(int item) { int ident, lev; object_type *o_ptr; /* 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]; } /* Sound */ sound(SOUND_EAT); /* Take a turn */ energy_use = 100; /* Identity not known yet */ ident = FALSE; /* Object level */ lev = get_object_level(o_ptr); /* Analyze the food */ switch (o_ptr->sval) { #ifdef JP /* それぞれの食べ物の感想をオリジナルより細かく表現 */ case SV_FOOD_SLIME_MOLD: { msg_print("これはなんとも形容しがたい味だ。"); ident = TRUE; break; } case SV_FOOD_RATION: { msg_print("これはおいしい。"); ident = TRUE; break; } #else case SV_FOOD_RATION: case SV_FOOD_SLIME_MOLD: { msg_print("That tastes good."); ident = TRUE; break; } #endif case SV_FOOD_WAYBREAD: { #ifdef JP msg_print("これはひじょうに美味だ。"); #else msg_print("That tastes good."); #endif (void)set_poisoned(0); (void)hp_player(damroll(4, 8)); ident = TRUE; break; } } /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* We have tried it */ object_tried(o_ptr); /* The player is now aware of the object */ if (ident && !object_aware_p(o_ptr)) { object_aware(o_ptr); gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev); }
/* * Quaff a potion (from the pack or the floor) */ void do_cmd_quaff_potion(void) { int item, lev; bool ident; object_type *o_ptr; cptr q, s; /* Restrict choices to potions */ item_tester_tval = TV_POTION; /* Get an item */ q = "Quaff which potion? "; s = "You have no potions to quaff."; 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]; } /* Sound */ sound(MSG_QUAFF); /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ ident = FALSE; /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Quaff the potion */ use_object(o_ptr, &ident); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* The item has been 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); /* Destroy a potion in the pack */ if (item >= 0) { inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); } /* Destroy a potion on the floor */ else { floor_item_increase(0 - item, -1); floor_item_describe(0 - item); floor_item_optimize(0 - item); } }
/*used to check the power of artifacts. Currently unused*/ void dump_artifact_power(void) { int i; char buf[1024]; int fd; FILE *fff = NULL; artifact_type *a_ptr; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_EDIT, "power.txt"); /* Check for existing file */ fd = fd_open(buf, O_RDONLY); /* Existing file */ if (fd >= 0) { char out_val[160]; /* Close the file */ fd_close(fd); /* Build query */ sprintf(out_val, "Replace existing file %s? ", buf); /* Ask */ if (get_check(out_val)) fd = -1; } /* Open the non-existing file */ if (fd < 0) fff = my_fopen(buf, "w"); /* No output file - fail */ if (!fff) return; /* Write a note */ fprintf(fff, "# File: artifact_power.txt (autogenerated)\n\n"); /* Read and print out all the objects */ for (i = 1; i < z_info->art_norm_max; i++) { s32b power; char o_name[80]; object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Get the object */ a_ptr = &a_info[i]; /* Ignore unused objects */ if (!strlen(a_ptr->name)) { fprintf(fff, "## empty space (available for artifact) ##\n\n"); continue; } /* Write the complete name of the artifact*/ make_fake_artifact(i_ptr, i); /* Identify it */ object_aware(i_ptr); object_known(i_ptr); i_ptr->ident |= (IDENT_MENTAL); /* Get a description to dump */ object_desc(o_name, sizeof(o_name), i_ptr, TRUE, 0); power = artifact_power(i); /*dump the information*/ fprintf(fff, "%9d is the power of %55s, tval is %6d \n", power, o_name, a_ptr->tval); } /* Done */ fclose(fff); }
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; }
/** * Handle player hitting a real trap. Rewritten in Oangband to allow a * greater variety of traps, with effects controlled by dungeon level. * To allow a trap to choose one of a variety of effects consistantly, * the quick RNG is often used, and xy coordinates input as a seed value. */ extern void hit_trap(int y, int x) { int i, j, k, num; int dam = 0; int nastyness, selection; feature_type *f_ptr = &f_info[cave_feat[y][x]]; cptr name = f_ptr->name; /* Use the "simple" RNG to insure that traps are consistant. */ Rand_quick = TRUE; /* Use the coordinates of the trap to seed the RNG. */ Rand_value = y * x; /* Disturb the player */ disturb(0, 0); /* Analyze XXX XXX XXX */ switch (cave_feat[y][x]) { /* trap door. */ case FEAT_TRAP_HEAD + 0x00: { Rand_quick = FALSE; /* Paranoia -NRM- */ if (((stage_map[p_ptr->stage][STAGE_TYPE] == CAVE) || (stage_map[p_ptr->stage][STAGE_TYPE] == VALLEY)) && (!stage_map[p_ptr->stage][DOWN])) { cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); msg_print("The trap fails!"); break; } msg_print("You fall through a trap door!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently down to the next level."); } else { dam = damroll(2, 8); take_hit(dam, name); } /* Remember where we came from */ p_ptr->last_stage = p_ptr->stage; if (!stage_map[p_ptr->stage][DOWN]) { /* Set the ways forward and back */ stage_map[255][UP] = p_ptr->stage; stage_map[p_ptr->stage][DOWN] = 255; stage_map[255][DEPTH] = p_ptr->depth + 1; } /* New stage */ p_ptr->stage = stage_map[p_ptr->stage][DOWN]; /* New depth */ p_ptr->depth = stage_map[p_ptr->stage][DEPTH]; /* Leaving */ p_ptr->leaving = TRUE; Rand_quick = TRUE; break; } /* pits. */ case FEAT_TRAP_HEAD + 0x01: { /* determine how dangerous the trap is allowed to be. */ nastyness = randint1(p_ptr->depth); if (randint1(20) == 1) nastyness += 20; else if (randint1(5) == 1) nastyness += 10; /* Player is now in pit. */ monster_swap(p_ptr->py, p_ptr->px, y, x); /* Center on player. */ y = p_ptr->py; x = p_ptr->px; /* pit of daggers. */ if ((nastyness > 80) && (randint1(3) != 3)) { msg_print("You fall into a pit of daggers!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently to the floor of the pit."); msg_print("You carefully avoid setting off the daggers."); } else { /* a trap of morgul. */ if (randint1(6) == 1) { Rand_quick = FALSE; msg_print ("A single coldly gleaming dagger pierces you deeply!"); msg_print ("You feel a deadly chill slowly withering your soul."); /* activate the Black Breath. */ p_ptr->black_breath = TRUE; /* lots of damage. */ dam = damroll(20, 15); /* undead may be attracted. */ if (randint1(2) == 1) { msg_print ("Undead suddenly appear and call you to them!"); k = randint1(3) + 2; for (i = 0; i < k; i++) { summon_specific(y, x, FALSE, p_ptr->depth, SUMMON_UNDEAD); } } /* morgul-traps are one-time only. */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); Rand_quick = TRUE; } else { Rand_quick = FALSE; /* activate the ordinary daggers. */ msg_print("Daggers pierce you everywhere!"); k = randint1(10) + 5; for (i = 0; i < k; i++) { dam += damroll(3, 4); } Rand_quick = TRUE; } /* cut the player. */ (void) inc_timed(TMD_CUT, randint1(dam), TRUE); /* Take the damage. */ take_hit(dam, name); } } /* poisoned spiked pit. */ else if ((nastyness > 55) && (randint1(3) != 3)) { msg_print("You fall into a spiked pit!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently to the floor of the pit."); msg_print("You carefully avoid touching the spikes."); } else { Rand_quick = FALSE; /* Base damage */ dam = damroll(2, 6); /* Extra spike damage */ if (randint0(100) < 85) { bool was_poisoned; msg_print("You are impaled on poisonous spikes!"); dam = dam * (randint1(6) + 3); (void) inc_timed(TMD_CUT, randint1(dam), TRUE); was_poisoned = pois_hit(dam); if (!was_poisoned) msg_print("The poison does not affect you!"); } /* Take the damage */ take_hit(dam, name); Rand_quick = TRUE; } } /* spiked pit. */ else if ((nastyness > 30) && (randint1(3) != 3)) { msg_print("You fall into a spiked pit!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently to the floor of the pit."); msg_print("You carefully avoid touching the spikes."); } else { Rand_quick = FALSE; /* Base damage */ dam = damroll(2, 6); /* Extra spike damage */ if (randint0(100) < 85) { msg_print("You are impaled!"); dam = dam * (2 + randint1(4)); (void) inc_timed(TMD_CUT, randint1(dam), TRUE); } /* Take the damage */ take_hit(dam, name); Rand_quick = TRUE; } } /* ordinary pit in all other cases. */ else { msg_print("You fall into a pit!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently to the bottom of the pit."); } else { Rand_quick = FALSE; dam = damroll(2, 6); take_hit(dam, name); Rand_quick = TRUE; } } break; } /* stat-reducing dart traps. */ case FEAT_TRAP_HEAD + 0x02: { /* decide if the dart hits. */ if (check_trap_hit(50 + p_ptr->depth)) { /* select a stat to drain. */ selection = randint0(6); Rand_quick = FALSE; msg_print("A small dart hits you!"); dam = damroll(1, 4); take_hit(dam, name); /* Determine how dangerous the trap is allowed to be. */ nastyness = randint1(p_ptr->depth); /* decide how much to drain the stat by. */ if ((nastyness > 50) && (randint1(3) == 1)) { num = randint1(4); } else num = 1; /* drain the stat. */ for (i = 0; i < num; i++) { (void) do_dec_stat(selection); } Rand_quick = TRUE; } else { msg_print("A small dart barely misses you."); } break; } /* discolored spots. */ case FEAT_TRAP_HEAD + 0x03: { /* determine how dangerous the trap is allowed to be. */ nastyness = randint1(p_ptr->depth); if (randint1(5) == 1) nastyness += 10; /* pick a elemental attack type. */ selection = randint1(4); /* electicity trap. */ if (selection == 1) { if ((nastyness >= 50) && (randint1(2) == 1)) { Rand_quick = FALSE; msg_print("You are struck by lightning!"); dam = damroll(6, 30); Rand_quick = TRUE; } else { Rand_quick = FALSE; msg_print("You get zapped!"); dam = damroll(4, 8); Rand_quick = TRUE; } Rand_quick = FALSE; elec_dam(dam, "an electricity trap"); Rand_quick = TRUE; } /* frost trap. */ if (selection == 2) { if ((nastyness >= 50) && (randint1(2) == 1)) { Rand_quick = FALSE; msg_print("You are lost within a blizzard!"); dam = damroll(6, 30); Rand_quick = TRUE; } else { Rand_quick = FALSE; msg_print("You are coated in frost!"); dam = damroll(4, 8); Rand_quick = TRUE; } Rand_quick = FALSE; cold_dam(dam, "a frost trap"); Rand_quick = TRUE; } /* fire trap. */ if (selection == 3) { if ((nastyness >= 50) && (randint1(2) == 1)) { Rand_quick = FALSE; msg_print("You are enveloped in a column of fire!"); dam = damroll(6, 30); Rand_quick = TRUE; } else { Rand_quick = FALSE; msg_print("You are surrounded by flames!"); dam = damroll(4, 8); Rand_quick = TRUE; } Rand_quick = FALSE; fire_dam(dam, "a fire trap"); Rand_quick = TRUE; } /* acid trap. */ if (selection == 4) { if ((nastyness >= 50) && (randint1(2) == 1)) { Rand_quick = FALSE; msg_print("A cauldron of acid is tipped over your head!"); dam = damroll(6, 30); Rand_quick = TRUE; } else { Rand_quick = FALSE; msg_print("You are splashed with acid!"); dam = damroll(4, 8); Rand_quick = TRUE; } Rand_quick = FALSE; acid_dam(dam, "an acid trap"); Rand_quick = TRUE; } break; } /* gas traps. */ case FEAT_TRAP_HEAD + 0x04: { selection = randint1(4); /* blinding trap. */ if (selection == 1) { msg_print("You are surrounded by a black gas!"); if (!p_ptr->state.no_blind) { Rand_quick = FALSE; (void) inc_timed(TMD_BLIND, randint0(30) + 15, TRUE); Rand_quick = TRUE; } } else notice_obj(OF_SEEING, 0); /* confusing trap. */ if (selection == 2) { msg_print ("You are surrounded by a gas of scintillating colors!"); if (!p_resist_good(P_RES_CONFU)) { Rand_quick = FALSE; (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE); Rand_quick = TRUE; } else notice_other(IF_RES_CONFU, 0); } /* poisoning trap. */ if (selection == 3) { msg_print("You are surrounded by a pungent green gas!"); Rand_quick = FALSE; pois_hit(25); Rand_quick = TRUE; } /* sleeping trap. */ if (selection == 4) { msg_print("You are surrounded by a strange white mist!"); if (!p_ptr->state.free_act) { (void) inc_timed(TMD_PARALYZED, randint0(10) + 5, TRUE); } else notice_obj(OF_FREE_ACT, 0); } break; } /* summoning traps. */ case FEAT_TRAP_HEAD + 0x05: { sound(MSG_SUM_MONSTER); /* sometimes summon thieves. */ if ((p_ptr->depth > 8) && (randint1(5) == 1)) { msg_print("You have aroused a den of thieves!"); Rand_quick = FALSE; num = 2 + randint1(3); for (i = 0; i < num; i++) { (void) summon_specific(y, x, FALSE, p_ptr->depth, SUMMON_THIEF); } Rand_quick = TRUE; } /* sometimes summon a nasty unique. */ else if (randint1(8) == 1) { msg_print("You are enveloped in a cloud of smoke!"); Rand_quick = FALSE; (void) summon_specific(y, x, FALSE, p_ptr->depth + 5, SUMMON_UNIQUE); Rand_quick = TRUE; } /* otherwise, the ordinary summon monsters. */ else { msg_print("You are enveloped in a cloud of smoke!"); Rand_quick = FALSE; num = 2 + randint1(3); for (i = 0; i < num; i++) { (void) summon_specific(y, x, FALSE, p_ptr->depth, 0); } Rand_quick = TRUE; } /* these are all one-time traps. */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); break; } /* dungeon alteration traps. */ case FEAT_TRAP_HEAD + 0x06: { /* determine how dangerous the trap is allowed to be. */ nastyness = randint1(p_ptr->depth); if (randint1(5) == 1) nastyness += 10; /* make room for alterations. */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); /* Everything truely random from here on. */ Rand_quick = FALSE; /* dungeon destruction trap. */ if ((nastyness > 60) && (randint1(12) == 1)) { msg_print ("A ear-splitting howl shatters your mind as the dungeon is smashed by hammer blows!"); (void) destroy_level(FALSE); /* the player is hard-hit. */ (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE); (void) inc_timed(TMD_BLIND, randint0(30) + 15, TRUE); (void) inc_timed(TMD_STUN, randint1(50) + 50, TRUE); dam = damroll(15, 15); take_hit(dam, name); } /* earthquake trap. */ else if ((nastyness > 20) && (randint1(4) == 1)) { msg_print("A tremor shakes the earth around you"); earthquake(y, x, 10, FALSE); } /* falling rock trap. */ else if ((nastyness > 4) && (randint1(2) == 1)) { msg_print("A rock falls on your head."); dam = damroll(2, 10); take_hit(dam, name); (void) inc_timed(TMD_STUN, randint1(10) + 10, TRUE); } /* a few pebbles. */ else { msg_print("A bunch of pebbles rain down on you."); dam = damroll(1, 8); take_hit(dam, name); } Rand_quick = TRUE; break; } /* various char and equipment-alteration traps, lumped together to * avoid any one effect being too common (some of them can be rather * nasty). */ case FEAT_TRAP_HEAD + 0x07: { /* determine how dangerous the trap is allowed to be. */ nastyness = randint0(100); /* these are all one-time traps. */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); /* Everything truely random from here on. */ Rand_quick = FALSE; /* trap of drain wands. */ if (nastyness < 15) { /* Hold the object information. */ object_type *o_ptr; /* Find an item */ for (i = 0; i < 20; i++) { /* Pick an item */ i = randint0(INVEN_PACK - p_ptr->pack_size_reduce); /* Obtain the item */ o_ptr = &p_ptr->inventory[i]; /* use "num" to decide if a item can be uncharged. By * default, assume it can't. */ num = 0; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Drain charged wands/staffs/rods */ if ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_ROD)) { /* case of charged wands/staffs. */ if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)) && (o_ptr->pval)) num = 1; /* case of charged rods. */ if ((o_ptr->tval == TV_ROD) && (o_ptr->timeout < randcalc(o_ptr->time, 0, MINIMISE))) num = 1; if (num == 1) { /* Message */ msg_print("Energy drains from your pack!"); /* Uncharge */ if ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)) o_ptr->pval = 0; if (o_ptr->tval == TV_ROD) o_ptr->timeout = randcalc(o_ptr->time, 0, RANDOMISE) * o_ptr->number * 2; /* Combine / Reorder the pack */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* not more than one inventory slot effected. */ break; } else continue; } } } /* trap of forgetting. */ else if (nastyness < 35) { if (check_save(100)) { msg_print("You hang on to your memories!"); } else if (lose_all_info()) { msg_print("Your memories fade away."); } } /* trap of alter reality. */ else if (nastyness < 50) { if (OPT(adult_ironman)) msg_print("Nothing happens."); else { msg_print("The world changes!"); /* Leaving */ p_ptr->leaving = TRUE; } } /* trap of remold player. */ else if (nastyness < 75) { int max1, cur1, max2, cur2, ii, jj; msg_print("You feel yourself being twisted by wild magic!"); if (check_save(100)) { msg_print("You resist the effects!"); } else { msg_print("Your body starts to scramble..."); /* Pick a pair of stats */ ii = randint0(6); for (jj = ii; jj == ii; jj = randint0(6)) /* loop */ ; max1 = p_ptr->stat_max[ii]; cur1 = p_ptr->stat_cur[ii]; max2 = p_ptr->stat_max[jj]; cur2 = p_ptr->stat_cur[jj]; p_ptr->stat_max[ii] = max2; p_ptr->stat_cur[ii] = cur2; p_ptr->stat_max[jj] = max1; p_ptr->stat_cur[jj] = cur1; p_ptr->update |= (PU_BONUS); } } /* time ball trap. */ else if (nastyness < 90) { msg_print("You feel time itself assault you!"); /* Target the player with a radius 0 ball attack. */ fire_meteor(0, GF_TIME, p_ptr->py, p_ptr->px, 75, 0, TRUE); } /* trap of bugs gone berserk. */ else { /* explain what the dickens is going on. */ msg_print("GRUESOME Gnawing Bugs leap out at you!"); if (!p_resist_good(P_RES_CONFU)) { (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE); } else notice_other(IF_RES_CONFU, 0); if (!p_resist_good(P_RES_CHAOS)) { (void) inc_timed(TMD_IMAGE, randint1(40), TRUE); } else notice_other(IF_RES_CHAOS, 0); /* XXX (hard coded) summon 3-6 bugs. */ k = randint1(4) + 2; for (i = 0; i < k; ++i) { /* Look for a location */ for (j = 0; j < 20; ++j) { /* Pick a (scattered) distance. */ int d = (j / 10) + randint1(3); /* Pick a location */ scatter(&y, &x, y, x, d, 0); /* Require passable terrain */ if (!cave_passable_bold(y, x)) continue; /* Hack -- no summon on glyph of warding */ if (cave_feat[y][x] == FEAT_RUNE_PROTECT) continue; /* Okay */ break; } /* Attempt to place the awake bug */ place_monster_aux(y, x, 453, FALSE, TRUE); } /* herald the arrival of bugs. */ msg_print("AAAAAAAHHHH! THEY'RE EVERYWHERE!"); } Rand_quick = TRUE; break; } /* teleport trap */ case FEAT_TRAP_HEAD + 0x08: { if (stage_map[p_ptr->stage][STAGE_TYPE] >= CAVE) msg_print("You teleport across the dungeon."); else msg_print("You teleport across the wilderness."); Rand_quick = FALSE; teleport_player(250, FALSE); Rand_quick = TRUE; break; } /* murder holes. */ case FEAT_TRAP_HEAD + 0x09: { /* hold the object info. */ object_type *o_ptr; object_type object_type_body; /* hold the missile type and name. */ int sval = 0; int tval = 0; cptr missile_name = ""; /* Determine the missile type and base damage. */ if (randint1(3) == 1) { if (p_ptr->depth < 40) { missile_name = "shot"; dam = damroll(2, 3); tval = TV_SHOT; sval = SV_AMMO_NORMAL; } else { missile_name = "seeker shot"; dam = damroll(3, 7); tval = TV_SHOT; sval = SV_AMMO_HEAVY; } } else if (randint1(2) == 1) { if (p_ptr->depth < 55) { missile_name = "arrow"; dam = damroll(2, 4); tval = TV_ARROW; sval = SV_AMMO_NORMAL; } else { missile_name = "seeker arrow"; dam = damroll(3, 9); tval = TV_ARROW; sval = SV_AMMO_HEAVY; } } else { if (p_ptr->depth < 65) { missile_name = "bolt"; dam = damroll(2, 5); tval = TV_BOLT; sval = SV_AMMO_NORMAL; } else { missile_name = "seeker bolt"; dam = damroll(3, 11); tval = TV_BOLT; sval = SV_AMMO_HEAVY; } } /* determine if the missile hits. */ if (check_trap_hit(75 + p_ptr->depth)) { msg_format("A %s hits you from above.", missile_name); Rand_quick = FALSE; /* critical hits. */ if (randint1(2) == 1) { msg_print("It was well-aimed!"); dam *= 1 + randint1(2); } if (randint1(2) == 1) { msg_print("It gouges you!"); dam = 3 * dam / 2; /* cut the player. */ (void) inc_timed(TMD_CUT, randint1(dam), TRUE); } Rand_quick = TRUE; take_hit(dam, name); } /* Explain what just happened. */ else msg_format("A %s wizzes by your head.", missile_name); /* these will eventually run out of ammo. */ Rand_quick = FALSE; if (randint0(8) == 0) { cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); } Rand_quick = TRUE; /* Get local object */ o_ptr = &object_type_body; /* Make a missile, identify it, and drop it near the player. */ object_prep(o_ptr, lookup_kind(tval, sval), MINIMISE); object_aware(o_ptr); object_known(o_ptr); drop_near(o_ptr, -1, y, x, TRUE); break; } /* falling tree branch */ case FEAT_TRAP_HEAD + 0x0A: { /* determine if the missile hits. */ if (check_trap_hit(75 + p_ptr->depth)) { /* Take damage */ dam = damroll(3, 5); msg_print("A branch hits you from above."); Rand_quick = FALSE; /* critical hits. */ if (randint1(2) == 1) { msg_print("It was heavy!"); dam = 3 * dam / 2; /* stun the player. */ (void) inc_timed(TMD_STUN, randint1(dam), TRUE); } Rand_quick = TRUE; take_hit(dam, name); } /* Explain what just happened. */ else msg_print("A falling branch just misses you."); /* No more */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_TREE); break; } /* falling tree branch */ case FEAT_TRAP_HEAD + 0x0B: { /* determine if the missile hits. */ if (check_trap_hit(75 + p_ptr->depth)) { /* Take damage */ dam = damroll(3, 5); msg_print("A branch hits you from above."); Rand_quick = FALSE; /* critical hits. */ if (randint1(2) == 1) { msg_print("It was heavy!"); dam = 3 * dam / 2; /* stun the player. */ (void) inc_timed(TMD_STUN, randint1(dam), TRUE); } Rand_quick = TRUE; take_hit(dam, name); } /* Explain what just happened. */ else msg_print("A falling branch just misses you."); /* No more */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_TREE2); break; } /* undefined trap. */ case FEAT_TRAP_HEAD + 0x0C: { msg_print("A dagger is thrown at you from the shadows!"); dam = damroll(3, 4); take_hit(dam, name); break; } /* undefined trap. */ case FEAT_TRAP_HEAD + 0x0D: { msg_print("A dagger is thrown at you from the shadows!"); dam = damroll(3, 4); take_hit(dam, name); break; } /* undefined trap. */ case FEAT_TRAP_HEAD + 0x0E: { msg_print("A dagger is thrown at you from the shadows!"); dam = damroll(3, 4); take_hit(dam, name); break; } /* undefined trap. */ case FEAT_TRAP_HEAD + 0x0F: { msg_print("A dagger is thrown at you from the shadows!"); dam = damroll(3, 4); take_hit(dam, name); break; } } /* Revert to usage of the complex RNG. */ Rand_quick = FALSE; }
bool quest_poison_gen_hook(char *fmt) { int cy = 1, cx = 1, x, y, try = 10000, r_idx; bool (*old_get_mon_num_hook)(int r_idx); if (cquest.status != QUEST_STATUS_TAKEN) return FALSE; if (p_ptr->wilderness_y != wild_locs[cquest.data[0]][0]) return FALSE; if (p_ptr->wilderness_x != wild_locs[cquest.data[0]][1]) return FALSE; if (p_ptr->wild_mode) return FALSE; /* Find a good position */ while (try) { /* Get a random spot */ cy = randint(cur_hgt - 24) + 22; cx = randint(cur_wid - 34) + 32; /* Is it a good spot ? */ if (cave_empty_bold(cy, cx)) break; /* One less try */ try--; } /* Place the baddies */ /* Backup the old hook */ old_get_mon_num_hook = get_mon_num_hook; /* Require "okay" monsters */ get_mon_num_hook = create_molds_hook; /* Prepare allocation table */ get_mon_num_prep(); /* Pick a monster, using the level calculation */ for (x = cx - 25; x <= cx + 25; x++) for (y = cy - 25; y <= cy + 25; y++) { if (!in_bounds(y, x)) continue; if (distance(cy, cx, y, x) > 25) continue; if (magik(80) && ((cave[y][x].feat == FEAT_DEEP_WATER) || (cave[y][x].feat == FEAT_SHAL_WATER))) cave_set_feat(y, x, FEAT_TAINTED_WATER); if (distance(cy, cx, y, x) > 10) continue; if (magik(60)) { int m_idx; r_idx = get_mon_num(30); m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY); /* Sometimes make it up some levels */ if (magik(80) && m_idx) { monster_type *m_ptr = &m_list[m_idx]; if (m_ptr->level < p_ptr->lev) { m_ptr->exp = MONSTER_EXP(m_ptr->level + randint(p_ptr->lev - m_ptr->level)); monster_check_experience(m_idx, TRUE); } } } } /* Reset restriction */ get_mon_num_hook = old_get_mon_num_hook; /* Prepare allocation table */ get_mon_num_prep(); return FALSE; } bool quest_poison_finish_hook(char *fmt) { object_type forge, *q_ptr; s32b q_idx; q_idx = get_next_arg(fmt); if (q_idx != QUEST_POISON) return FALSE; c_put_str(TERM_YELLOW, "The water is clean again! Thank you so much.", 8, 0); c_put_str(TERM_YELLOW, "The beautiful Mallorns are safe. Take this as a proof of our gratitude.", 9, 0); q_ptr = &forge; object_prep(q_ptr, lookup_kind(TV_DRAG_ARMOR, SV_DRAGON_BLUE)); q_ptr->found = OBJ_FOUND_REWARD; q_ptr->number = 1; q_ptr->name2 = EGO_ELVENKIND; apply_magic(q_ptr, 1, FALSE, FALSE, FALSE); object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; (void)inven_carry(q_ptr, FALSE); /* Continue the plot */ *(quest[q_idx].plot) = QUEST_NULL; del_hook(HOOK_QUEST_FINISH, quest_poison_finish_hook); process_hooks_restart = TRUE; return TRUE; }
/* * Become unaware of objects, monster memory, and the map */ static void do_cmd_wiz_forget(void) { int i; /* Forget info about objects on the map */ for (i = 1; i < o_max; i++) { object_type *o_ptr = &o_list[i]; object_kind *k_ptr = &k_info[o_ptr->k_idx]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; // identify non-special non-artefact weapons/armour switch (o_ptr->tval) { case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_BOW: case TV_ARROW: case TV_MAIL: case TV_SOFT_ARMOR: case TV_SHIELD: case TV_HELM: case TV_CROWN: case TV_CLOAK: case TV_GLOVES: case TV_BOOTS: case TV_LIGHT: { if (!o_ptr->name1 && !o_ptr->name2) { /* Identify it */ object_aware(o_ptr); object_known(o_ptr); break; } } default: { if (!(k_ptr->flags3 & (TR3_EASY_KNOW))) { o_ptr->ident &= ~(IDENT_KNOWN); } } } /* Hack -- Clear the "empty" flag */ o_ptr->ident &= ~(IDENT_EMPTY); // re pseudo id pseudo_id(o_ptr); } /* Forget info about carried objects */ for (i = 0; i < INVEN_TOTAL; i++) { object_type *o_ptr = &inventory[i]; object_kind *k_ptr = &k_info[o_ptr->k_idx]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; // identify non-special non-artefact weapons/armour switch (o_ptr->tval) { case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_BOW: case TV_ARROW: case TV_MAIL: case TV_SOFT_ARMOR: case TV_SHIELD: case TV_HELM: case TV_CROWN: case TV_CLOAK: case TV_GLOVES: case TV_BOOTS: case TV_LIGHT: { if (!o_ptr->name1 && !o_ptr->name2) { /* Identify it */ object_aware(o_ptr); object_known(o_ptr); break; } } default: { if (!(k_ptr->flags3 & (TR3_EASY_KNOW))) { o_ptr->ident &= ~(IDENT_KNOWN); } } } /* Hack -- Clear the "empty" flag */ o_ptr->ident &= ~(IDENT_EMPTY); // re pseudo id pseudo_id(o_ptr); } /* Reset the object kinds */ for (i = 1; i < z_info->k_max; i++) { object_kind *k_ptr = &k_info[i]; /* Reset "tried" */ k_ptr->tried = FALSE; /* Reset "aware" */ k_ptr->aware = FALSE; } /* Reset the special objects */ for (i = 1; i < z_info->e_max; i++) { ego_item_type *e_ptr = &e_info[i]; /* Reset "aware" */ e_ptr->aware = FALSE; } /* Forget encountered monsters */ for (i = 1; i < mon_max; i++) { monster_type *m_ptr = &mon_list[i]; m_ptr->encountered = FALSE; } /* Reset the monster memory */ for (i = 1; i < z_info->r_max; i++) { monster_lore *l_ptr = &l_list[i]; WIPE(l_ptr, monster_lore); } /* Mega-Hack -- Forget the map */ wiz_dark(); // lose all spare experience //lose_exp(10000); // clear the cheat flags p_ptr->noscore = 0x0000; /* Forget turns */ turn = 1; playerturn = 1; // forget all messages -- currently a bit buggy messages_init(); // clear target target_set_monster(0); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0); }