/* Is the player capable of casting a spell? */ bool player_can_cast(void) { /* Races without Horns or Hands cannot cast arcane spells */ if((!rp_ptr->num_rings) && p_ptr->cumber_glove) { msg("You need a horn or hands to cast arcane spells."); return FALSE; } if (player_has(PF_PROBE)) { if (p_ptr->lev < 35) { msg("You do not know how to probe monsters yet."); return FALSE; } else if ((p_ptr->timed[TMD_CONFUSED]) || (p_ptr->timed[TMD_IMAGE])) { msg("You feel awfully confused."); return FALSE; } } if (p_ptr->timed[TMD_BLIND] || no_light()) { msg("You cannot see!"); return FALSE; } if (p_ptr->timed[TMD_CONFUSED]) { msg("You are too confused!"); return FALSE; } return TRUE; }
/* Determine if the player can read scrolls. */ bool player_can_read(void) { if (p_ptr->timed[TMD_BLIND]) { msg_print("You can't see anything."); return FALSE; } if (no_light()) { msg_print("You have no light to read by."); return FALSE; } if (p_ptr->timed[TMD_CONFUSED]) { msg_print("You are too confused to read!"); return FALSE; } if (p_ptr->timed[TMD_AMNESIA]) { msg_print("You can't remember how to read!"); return FALSE; } return TRUE; }
/** * Turn a basic monster trap into an advanced one -BR- */ extern bool py_modify_trap(int y, int x) { if (p_ptr->timed[TMD_BLIND] || no_light()) { msg_print("You can not see to modify your trap."); return FALSE; } if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) { msg_print("You are too confused."); return FALSE; } /* No setting traps while shapeshifted */ if (SCHANGE) { msg_print("You can not set traps while shapechanged."); msg_print("Use the ']' command to return to your normal form."); return FALSE; } trap_y = y; trap_x = x; /* get choice */ if (trap_menu()) { /* Notify the player. */ msg_print("You modify the monster trap."); } /* Trap was modified */ return TRUE; }
/* Is the player capable of casting a spell? */ bool player_can_cast(void) { if (player_has(PF_PROBE)) { if (p_ptr->lev < 35) { msg("You do not know how to probe monsters yet."); return FALSE; } else if ((p_ptr->timed[TMD_CONFUSED]) || (p_ptr->timed[TMD_IMAGE])) { msg("You feel awfully confused."); return FALSE; } } if (p_ptr->timed[TMD_BLIND] || no_light()) { msg("You cannot see!"); return FALSE; } if (p_ptr->timed[TMD_CONFUSED]) { msg("You are too confused!"); return FALSE; } return TRUE; }
/** * Perform the basic "disarm" command * * Assume there is no monster blocking the destination * * Returns true if repeated commands may continue */ static bool do_cmd_disarm_aux(int y, int x) { int skill, power, chance; struct trap *trap = cave->squares[y][x].trap; bool more = false; /* Verify legality */ if (!do_cmd_disarm_test(y, x)) return (false); /* Choose first player trap */ while (trap) { if (trf_has(trap->flags, TRF_TRAP)) break; trap = trap->next; } if (!trap) return false; /* Get the base disarming skill */ if (trf_has(trap->flags, TRF_MAGICAL)) skill = player->state.skills[SKILL_DISARM_MAGIC]; else skill = player->state.skills[SKILL_DISARM_PHYS]; /* Penalize some conditions */ if (player->timed[TMD_BLIND] || no_light() || player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) skill = skill / 10; /* Extract trap power */ power = cave->depth / 5; /* Extract the percentage success */ chance = skill - power; /* Always have a small chance of success */ if (chance < 2) chance = 2; /* Two chances - one to disarm, one not to set the trap off */ if (randint0(100) < chance) { msgt(MSG_DISARM, "You have disarmed the %s.", trap->kind->name); player_exp_gain(player, power); /* Trap is gone */ square_forget(cave, y, x); square_destroy_trap(cave, y, x); } else if (randint0(100) < chance) { event_signal(EVENT_INPUT_FLUSH); msg("You failed to disarm the %s.", trap->kind->name); /* Player can try again */ more = true; } else { msg("You set off the %s!", trap->kind->name); hit_trap(y, x); } /* Result */ return (more); }
/** * Attempt to disarm the chest at the given location * * Assume there is no monster blocking the destination * * Returns true if repeated commands may continue */ bool do_cmd_disarm_chest(int y, int x, struct object *obj) { int i, j; bool more = false; /* Get the "disarm" factor */ if (obj->pval > 0 && (chest_traps[obj->pval] & CHEST_SUMMON)) i = player->state.skills[SKILL_DISARM_MAGIC]; else i = player->state.skills[SKILL_DISARM_PHYS]; /* Penalize some conditions */ if (player->timed[TMD_BLIND] || no_light()) i = i / 10; if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) i = i / 10; /* Extract the difficulty */ j = i - obj->pval; /* Always have a small chance of success */ if (j < 2) j = 2; /* Must find the trap first. */ if (!obj->known->pval) { msg("I don't see any traps."); } else if (!is_trapped_chest(obj)) { /* Already disarmed/unlocked or no traps */ msg("The chest is not trapped."); } else if (randint0(100) < j) { /* Success (get a lot of experience) */ msgt(MSG_DISARM, "You have disarmed the chest."); player_exp_gain(player, obj->pval); obj->pval = (0 - obj->pval); } else if (randint0(100) < j) { /* Failure -- Keep trying */ more = true; event_signal(EVENT_INPUT_FLUSH); msg("You failed to disarm the chest."); } else { /* Failure -- Set off the trap */ msg("You set off a trap!"); chest_trap(y, x, obj); } /* Result */ return (more); }
/** * Perform the command "lock door" * * Assume there is no monster blocking the destination * * Returns true if repeated commands may continue */ static bool do_cmd_lock_door(int y, int x) { int i, j, power; bool more = false; /* Verify legality */ if (!do_cmd_disarm_test(y, x)) return false; /* Get the "disarm" factor */ i = player->state.skills[SKILL_DISARM_PHYS]; /* Penalize some conditions */ if (player->timed[TMD_BLIND] || no_light()) i = i / 10; if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) i = i / 10; /* Calculate lock "power" */ power = m_bonus(7, player->depth); /* Extract the difficulty */ j = i - power; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success */ if (randint0(100) < j) { msg("You lock the door."); square_set_door_lock(cave, y, x, power); } /* Failure -- Keep trying */ else if ((i > 5) && (randint1(i) > 5)) { event_signal(EVENT_INPUT_FLUSH); msg("You failed to lock the door."); /* We may keep trying */ more = true; } /* Failure */ else msg("You failed to lock the door."); /* Result */ return more; }
/* * Perform the command "lock door" * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ static bool do_cmd_lock_door(int y, int x) { int i, j, power; bool more = FALSE; /* Verify legality */ if (!do_cmd_disarm_test(y, x)) return FALSE; /* Get the "disarm" factor */ i = p_ptr->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10; if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10; /* Calculate lock "power" */ power = m_bonus(7, p_ptr->depth); /* Extract the difficulty */ j = i - power; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success */ if (randint0(100) < j) { msg("You lock the door."); cave_set_feat(cave, y, x, FEAT_DOOR_HEAD + power); } /* Failure -- Keep trying */ else if ((i > 5) && (randint1(i) > 5)) { flush(); msg("You failed to lock the door."); /* We may keep trying */ more = TRUE; } /* Failure */ else msg("You failed to lock the door."); /* Result */ return more; }
/** * Search for traps or secret doors */ static void search(void) { int py = player->py; int px = player->px; int y, x; struct object *obj; /* Various conditions mean no searching */ if (player->timed[TMD_BLIND] || no_light() || player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) return; /* Search the nearby grids, which are always in bounds */ for (y = (py - 1); y <= (py + 1); y++) { for (x = (px - 1); x <= (px + 1); x++) { /* Traps */ if (square_issecrettrap(cave, y, x)) { if (square_reveal_trap(cave, y, x, true)) disturb(player, 0); } /* Secret doors */ if (square_issecretdoor(cave, y, x)) { msg("You have found a secret door."); place_closed_door(cave, y, x); disturb(player, 0); } /* Traps on chests */ for (obj = square_object(cave, y, x); obj; obj = obj->next) { if (!obj->known || !is_trapped_chest(obj)) continue; if (obj->known->pval != obj->pval) { msg("You have discovered a trap on the chest!"); obj->known->pval = obj->pval; disturb(player, 0); } } } } }
/* Is the player capable of casting a spell? */ bool player_can_cast(void) { if (!cp_ptr->spell_book) { msg_print("You cannot pray or produce magics."); return FALSE; } if (p_ptr->timed[TMD_BLIND] || no_light()) { msg_print("You cannot see!"); return FALSE; } if (p_ptr->timed[TMD_CONFUSED]) { msg_print("You are too confused!"); return FALSE; } return TRUE; }
/* * Attempt to open the given chest at the given location * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ bool do_cmd_open_chest(int y, int x, s16b o_idx) { int i, j; bool flag = TRUE; bool more = FALSE; object_type *o_ptr = object_byid(o_idx); /* Attempt to unlock it */ if (o_ptr->pval[DEFAULT_PVAL] > 0) { /* Assume locked, and thus not open */ flag = FALSE; /* Get the "disarm" factor */ i = p_ptr->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10; if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10; /* Extract the difficulty */ j = i - o_ptr->pval[DEFAULT_PVAL]; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success -- May still have traps */ if (randint0(100) < j) { msgt(MSG_LOCKPICK, "You have picked the lock."); player_exp_gain(p_ptr, 1); flag = TRUE; } /* Failure -- Keep trying */ else { /* We may continue repeating */ more = TRUE; flush(); msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock."); } } /* Allowed to open */ if (flag) { /* Apply chest traps, if any */ chest_trap(y, x, o_idx); /* Let the Chest drop items */ chest_death(y, x, o_idx); /* Squelch chest if autosquelch calls for it */ p_ptr->notice |= PN_SQUELCH; } /* * empty chests were always squelched in squelch_item_okay so we * might as well squelch it here */ if (o_ptr->pval[DEFAULT_PVAL] == 0) { o_ptr->ignore = TRUE; } /* Redraw chest, to be on the safe side (it may have been squelched) */ cave_light_spot(cave, y, x); /* Refresh */ Term_fresh(); /* Result */ return (more); }
/** * Attempt to open the given chest at the given location * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ bool do_cmd_open_chest(int y, int x, struct object *obj) { int i, j; bool flag = TRUE; bool more = FALSE; /* Attempt to unlock it */ if (obj->pval > 0) { /* Assume locked, and thus not open */ flag = FALSE; /* Get the "disarm" factor */ i = player->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (player->timed[TMD_BLIND] || no_light()) i = i / 10; if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) i = i / 10; /* Extract the difficulty */ j = i - obj->pval; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success -- May still have traps */ if (randint0(100) < j) { msgt(MSG_LOCKPICK, "You have picked the lock."); player_exp_gain(player, 1); flag = TRUE; } else { /* We may continue repeating */ more = TRUE; event_signal(EVENT_INPUT_FLUSH); msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock."); } } /* Allowed to open */ if (flag) { /* Apply chest traps, if any */ chest_trap(y, x, obj); /* Let the Chest drop items */ chest_death(y, x, obj); /* Ignore chest if autoignore calls for it */ player->upkeep->notice |= PN_IGNORE; } /* Empty chests were always ignored in ignore_item_okay so we * might as well ignore it here */ if (obj->pval == 0) obj->ignore = TRUE; /* Redraw chest, to be on the safe side (it may have been ignored) */ square_light_spot(cave, y, x); /* Result */ return (more); }
/* * Perform the basic "open" command on doors * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ static bool do_cmd_open_aux(int y, int x) { int i, j; bool more = FALSE; /* Verify legality */ if (!do_cmd_open_test(y, x)) return (FALSE); /* Locked door */ if (cave_islockeddoor(cave, y, x)) { /* Disarm factor */ i = p_ptr->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10; if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10; /* Extract the lock power */ j = cave_door_power(cave, y, x); /* Extract the difficulty XXX XXX XXX */ j = i - (j * 4); /* Always have a small chance of success */ if (j < 2) j = 2; /* Success */ if (randint0(100) < j) { /* Message */ msgt(MSG_LOCKPICK, "You have picked the lock."); /* Open the door */ cave_open_door(cave, y, x); /* Update the visuals */ p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Experience */ /* Removed to avoid exploit by repeatedly locking and unlocking door */ /* player_exp_gain(p_ptr, 1); */ } /* Failure */ else { flush(); /* Message */ msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock."); /* We may keep trying */ more = TRUE; } } /* Closed door */ else { /* Open the door */ cave_open_door(cave, y, x); /* Update the visuals */ p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Sound */ sound(MSG_OPENDOOR); } /* Result */ return (more); }
/** * Search for hidden things. Returns true if a search was attempted, returns * false when the player has a 0% chance of finding anything. Prints messages * for negative confirmation when verbose mode is requested. */ bool search(bool verbose) { int py = player->py; int px = player->px; int y, x, chance; bool found = false; struct object *obj; /* Start with base search ability */ chance = player->state.skills[SKILL_SEARCH]; /* Penalize various conditions */ if (player->timed[TMD_BLIND] || no_light()) chance = chance / 10; if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) chance = chance / 10; /* Prevent fruitless searches */ if (chance <= 0) { if (verbose) { msg("You can't make out your surroundings well enough to search."); /* Cancel repeat */ disturb(player, 0); } return false; } /* Search the nearby grids, which are always in bounds */ for (y = (py - 1); y <= (py + 1); y++) { for (x = (px - 1); x <= (px + 1); x++) { /* Sometimes, notice things */ if (randint0(100) < chance) { if (square_issecrettrap(cave, y, x)) { found = true; /* Reveal trap, display a message */ if (square_reveal_trap(cave, y, x, chance, true)) /* Disturb */ disturb(player, 0); } /* Secret door */ if (square_issecretdoor(cave, y, x)) { found = true; /* Message */ msg("You have found a secret door."); /* Pick a door */ place_closed_door(cave, y, x); /* Disturb */ disturb(player, 0); } /* Scan all objects in the grid */ for (obj = square_object(cave, y, x); obj; obj = obj->next) { /* Skip if not a trapped chest */ if (!is_trapped_chest(obj)) continue; /* Identify once */ if (!object_is_known(obj)) { found = true; /* Message */ msg("You have discovered a trap on the chest!"); /* Know the trap */ object_notice_everything(obj); /* Notice it */ disturb(player, 0); } } } } } if (verbose && !found) { if (chance >= 100) msg("There are no secrets here."); else msg("You found nothing."); } return true; }
/** * Perform the basic "disarm" command * * Assume there is no monster blocking the destination * * Returns true if repeated commands may continue */ static bool do_cmd_disarm_aux(int y, int x) { int i, j, power; struct trap *trap = cave->squares[y][x].trap; bool more = false; /* Verify legality */ if (!do_cmd_disarm_test(y, x)) return (false); /* Choose first player trap */ while (trap) { if (trf_has(trap->flags, TRF_TRAP)) break; trap = trap->next; } if (!trap) return false; /* Get the "disarm" factor */ i = player->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (player->timed[TMD_BLIND] || no_light()) i = i / 10; if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) i = i / 10; /* XXX XXX XXX Variable power? */ /* Extract trap "power" */ power = 5; /* Extract the difficulty */ j = i - power; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success */ if (randint0(100) < j) { /* Message */ msgt(MSG_DISARM, "You have disarmed the %s.", trap->kind->name); /* Reward */ player_exp_gain(player, power); /* Forget the trap */ square_forget(cave, y, x); /* Remove the trap */ square_destroy_trap(cave, y, x); } else if ((i > 5) && (randint1(i) > 5)) { /* Failure -- Keep trying */ event_signal(EVENT_INPUT_FLUSH); msg("You failed to disarm the %s.", trap->kind->name); more = true; } else { /* Failure -- Set off the trap */ msg("You set off the %s!", trap->kind->name); hit_trap(y, x); } /* Result */ return (more); }
/* * Attempt to disarm the chest at the given location * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ bool do_cmd_disarm_chest(int y, int x, s16b o_idx) { int i, j; bool more = FALSE; object_type *o_ptr = object_byid(o_idx); /* Get the "disarm" factor */ i = p_ptr->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10; if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10; /* Extract the difficulty */ j = i - o_ptr->pval[DEFAULT_PVAL]; /* Always have a small chance of success */ if (j < 2) j = 2; /* Must find the trap first. */ if (!object_is_known(o_ptr)) { msg("I don't see any traps."); } /* Already disarmed/unlocked or no traps */ else if (!is_trapped_chest(o_ptr)) { msg("The chest is not trapped."); } /* Success (get a lot of experience) */ else if (randint0(100) < j) { msgt(MSG_DISARM, "You have disarmed the chest."); player_exp_gain(p_ptr, o_ptr->pval[DEFAULT_PVAL]); o_ptr->pval[DEFAULT_PVAL] = (0 - o_ptr->pval[DEFAULT_PVAL]); } /* Failure -- Keep trying */ else if ((i > 5) && (randint1(i) > 5)) { /* We may keep trying */ more = TRUE; flush(); msg("You failed to disarm the chest."); } /* Failure -- Set off the trap */ else { msg("You set off a trap!"); chest_trap(y, x, o_idx); } /* Result */ return (more); }
/** * Rogues may steal gold from monsters. The monster needs to have * something to steal (it must drop some form of loot), and should * preferably be asleep. Humanoids and dragons are a rogue's favorite * targets. Steal too often on a level, and monsters will be more wary, * and the hue and cry will be eventually be raised. Having every * monster on the level awake and aggravated is not pleasant. -LM- */ extern void py_steal(int y, int x) { cptr act = NULL; monster_type *m_ptr = &m_list[cave_m_idx[y][x]]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; char m_name[80]; int i; int effect, theft_protection; int filching_power = 0; int purse = 0; bool thief = FALSE; bool success = FALSE; /* Check intent */ if ((m_ptr->hostile != -1) && !get_check("Do you want to steal from this being?")) { py_attack(y, x, FALSE); return; } /* Hard limit on theft. */ if (number_of_thefts_on_level > 4) { msg_print ("Everyone is keeping a lookout for you. You can steal nothing here."); return; } /* Determine the cunning of the thief. */ filching_power = 2 * p_ptr->lev; /* Penalize some conditions */ if (p_ptr->timed[TMD_BLIND] || no_light()) filching_power = filching_power / 10; if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) filching_power = filching_power / 10; /* Determine how much protection the monster has. */ theft_protection = (7 * (r_ptr->level + 2) / 4); theft_protection += (m_ptr->mspeed - p_ptr->state.pspeed); if (theft_protection < 1) theft_protection = 1; /* Send a thief to catch a thief. */ for (i = 0; i < 4; i++) { /* Extract infomation about the blow effect */ effect = r_ptr->blow[i].effect; if (effect == RBE_EAT_GOLD) thief = TRUE; if (effect == RBE_EAT_ITEM) thief = TRUE; } if (thief) theft_protection += 30; if (m_ptr->csleep) theft_protection = 3 * theft_protection / 5; /* Special player stealth magics aid stealing, but are lost in the process */ if (p_ptr->timed[TMD_SSTEALTH]) { theft_protection = 3 * theft_protection / 5; (void) clear_timed(TMD_SSTEALTH, TRUE); } /* The more you steal on a level, the more wary the monsters. */ theft_protection += number_of_thefts_on_level * 15; /* Did the theft succeed? */ if (randint1(theft_protection) < filching_power) success = TRUE; /* If the theft succeeded, determine the value of the purse. */ if (success) { purse = (r_ptr->level + 1) + randint1(3 * (r_ptr->level + 1) / 2); /* Uniques are juicy targets. */ if (rf_has(r_ptr->flags, RF_UNIQUE)) purse *= 3; /* But some monsters are dirt poor. */ if (!(rf_has(r_ptr->flags, RF_DROP_60)) || rf_has(r_ptr->flags, RF_DROP_90) || rf_has(r_ptr->flags, RF_DROP_1D2) || rf_has(r_ptr->flags, RF_DROP_2D2) || rf_has(r_ptr->flags, RF_DROP_3D2) || rf_has(r_ptr->flags, RF_DROP_4D2)) purse = 0; /* Some monster races are far better to steal from than others. */ if ((r_ptr->d_char == 'D') || (r_ptr->d_char == 'd') || (r_ptr->d_char == 'p') || (r_ptr->d_char == 'h')) purse *= 2 + randint1(3) + randint1(r_ptr->level / 20); else if ((r_ptr->d_char == 'P') || (r_ptr->d_char == 'o') || (r_ptr->d_char == 'O') || (r_ptr->d_char == 'T') || (r_ptr->d_char == 'n') || (r_ptr->d_char == 'W') || (r_ptr->d_char == 'k') || (r_ptr->d_char == 'L') || (r_ptr->d_char == 'V') || (r_ptr->d_char == 'y')) purse *= 1 + randint1(3) + randint1(r_ptr->level / 30); /* Pickings are scarce in a land of many thieves. */ purse = purse * (p_ptr->depth + 5) / (p_ptr->recall[0] + 5); /* Increase player gold. */ p_ptr->au += purse; /* Limit to avoid buffer overflow */ if (p_ptr->au > PY_MAX_GOLD) p_ptr->au = PY_MAX_GOLD; /* Redraw gold */ p_ptr->redraw |= (PR_GOLD); /* Announce the good news. */ if (purse) msg_format("You burgle %d gold.", purse); /* Pockets are empty. */ else msg_print("You burgle only dust."); } /* The victim normally, but not always, wakes up and is aggravated. */ if (randint1(4) != 1) { m_ptr->csleep = 0; m_ptr->mflag |= (MFLAG_ACTV); if (m_ptr->mspeed < r_ptr->speed + 3) m_ptr->mspeed += 10; /* Become hostile */ m_ptr->hostile = -1; /* Occasionally, amuse the player with a message. */ if ((randint1(5) == 1) && (purse) && (rf_has(r_ptr->flags, RF_SMART))) { monster_desc(m_name, sizeof(m_name), m_ptr, 0); act = desc_victim_outcry[randint0(20)]; msg_format("%^s cries out %s", m_name, act); } /* Otherwise, simply explain what happened. */ else { monster_desc(m_name, sizeof(m_name), m_ptr, 0); msg_format("You have aroused %s.", m_name); } } /* The thief also speeds up, but only for just long enough to escape. */ if (!p_ptr->timed[TMD_FAST]) p_ptr->timed[TMD_FAST] += 2; /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Handle stuff */ handle_stuff(); /* Increment the number of thefts, and possibly raise the hue and cry. */ number_of_thefts_on_level++; if (number_of_thefts_on_level > 4) { /* Notify the player of the trouble he's in. */ msg_print("All the level is in an uproar over your misdeeds!"); /* Aggravate and speed up all monsters on level. */ (void) aggravate_monsters(1, TRUE); } else if ((number_of_thefts_on_level > 2) || (randint1(8) == 1)) { msg_print ("You hear hunting parties scouring the area for a notorious burgler."); /* Aggravate monsters nearby. */ (void) aggravate_monsters(1, FALSE); } /* Rogue "Hit and Run" attack. */ if (p_ptr->special_attack & (ATTACK_FLEE)) { /* Cancel the fleeing spell */ p_ptr->special_attack &= ~(ATTACK_FLEE); /* Message */ msg_print("You escape into the shadows!"); /* Teleport. */ teleport_player(6 + p_ptr->lev / 5, TRUE); /* Redraw the state */ p_ptr->redraw |= (PR_STATUS); } }
/** * Rogues may set traps. Only one such trap may exist at any one time, * but an old trap can be disarmed to free up equipment for a new trap. * -LM- */ extern bool py_set_trap(int y, int x) { int max_traps; s16b this_o_idx, next_o_idx = 0; object_type *o_ptr; bool destroy_message = FALSE; max_traps = 1 + ((p_ptr->lev >= 25) ? 1 : 0) + (player_has(PF_EXTRA_TRAP) ? 1 : 0); if (p_ptr->timed[TMD_BLIND] || no_light()) { msg_print("You can not see to set a trap."); return FALSE; } if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) { msg_print("You are too confused."); return FALSE; } /* Paranoia -- Forbid more than max_traps being set. */ if (num_trap_on_level >= max_traps) { msg_print ("You must disarm your existing trap to free up your equipment."); return FALSE; } /* No setting traps while shapeshifted */ if (SCHANGE) { msg_print("You can not set traps while shapechanged."); msg_print("Use the ']' command to return to your normal form."); return FALSE; } /* Scan all objects in the grid */ for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) { /* Acquire object */ o_ptr = &o_list[this_o_idx]; /* Acquire next object */ next_o_idx = o_ptr->next_o_idx; /* Artifact */ if (o_ptr->name1) { msg_print("There is an indestructible object here."); return FALSE; } /* Visible object to be destroyed */ if (!squelch_hide_item(o_ptr)) destroy_message = TRUE; } /* Verify */ if (cave_o_idx[y][x]) { if (destroy_message) if (!get_check("Destroy all items and set a trap?")) return FALSE; for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) { /* Acquire object */ o_ptr = &o_list[this_o_idx]; /* Acquire next object */ next_o_idx = o_ptr->next_o_idx; /* Delete the object */ delete_object_idx(this_o_idx); } /* Redraw */ light_spot(y, x); } /* Set the trap, and draw it. */ cave_set_feat(y, x, FEAT_MTRAP_BASE); /* Notify the player. */ msg_print("You set a monster trap."); /* Increment the number of monster traps. */ num_trap_on_level++; /* A trap has been set */ return TRUE; }
/* * Search for hidden things. Returns true if a search was attempted, returns * false when the player has a 0% chance of finding anything. Prints messages * for negative confirmation when verbose mode is requested. */ bool search(bool verbose) { int py = p_ptr->py; int px = p_ptr->px; int y, x, chance; bool found = FALSE; object_type *o_ptr; /* Start with base search ability */ chance = p_ptr->state.skills[SKILL_SEARCH]; /* Penalize various conditions */ if (p_ptr->timed[TMD_BLIND] || no_light()) chance = chance / 10; if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) chance = chance / 10; /* Prevent fruitless searches */ if (chance <= 0) { if (verbose) { msg("You can't make out your surroundings well enough to search."); /* Cancel repeat */ disturb(p_ptr, 0, 0); } return FALSE; } /* Search the nearby grids, which are always in bounds */ for (y = (py - 1); y <= (py + 1); y++) { for (x = (px - 1); x <= (px + 1); x++) { /* Sometimes, notice things */ if (randint0(100) < chance) { /* Invisible trap */ if (cave->feat[y][x] == FEAT_INVIS) { found = TRUE; /* Pick a trap */ pick_trap(y, x); /* Message */ msg("You have found a trap."); /* Disturb */ disturb(p_ptr, 0, 0); } /* Secret door */ if (cave->feat[y][x] == FEAT_SECRET) { found = TRUE; /* Message */ msg("You have found a secret door."); /* Pick a door */ place_closed_door(cave, y, x); /* Disturb */ disturb(p_ptr, 0, 0); } /* Scan all objects in the grid */ for (o_ptr = get_first_object(y, x); o_ptr; o_ptr = get_next_object(o_ptr)) { /* Skip non-chests */ if (o_ptr->tval != TV_CHEST) continue; /* Skip disarmed chests */ if (o_ptr->pval[DEFAULT_PVAL] <= 0) continue; /* Skip non-trapped chests */ if (!chest_traps[o_ptr->pval[DEFAULT_PVAL]]) continue; /* Identify once */ if (!object_is_known(o_ptr)) { found = TRUE; /* Message */ msg("You have discovered a trap on the chest!"); /* Know the trap */ object_notice_everything(o_ptr); /* Notice it */ disturb(p_ptr, 0, 0); } } } } } if (verbose && !found) { if (chance >= 100) msg("There are no secrets here."); else msg("You found nothing."); } return TRUE; }
/** * Pick up objects and treasure on the floor, now also used for telekinesis. * * Called with pickup: * 0 to grab gold and describe non-gold objects. * 1 to pick up objects either with or without displaying a menu. * 2 to pick up objects, forcing a menu for multiple objects. * 3 to pick up objects, forcing a menu for any number of objects. * * Scan the list of objects in that floor grid. Pick up gold automatically. * Pick up objects automatically until pile or backpack space is full if * auto-pickup option is on, carry_query_floor option is not, and menus are * not forced (which the "get" command does). Otherwise, store objects on * floor in an array, and tally both how many there are and can be picked up. * * If the player is not picking up objects, describe a single object or * indicate the presence of a floor stack. If player is picking up objects, * name a single object, or indicate a stack of objects, that cannot go in * the backpack. * * Pick up a single object without menus, unless menus for single items are * forced. Confirm pickup if that option is on. * * Pick up multiple objects (unless using autopickup, no confirm) using Tim * Baker's menu system. Recursively call this function (forcing menus for any * number of objects) until objects are gone, backpack is full, or player is * satisfied. * * Keep track of number of objects picked up (to calculate time spent). */ byte py_pickup(int pickup, int y, int x) { s16b this_o_idx, next_o_idx = 0; char o_name[120]; object_type *o_ptr; /* Objects picked up. Used to determine time cost of command. */ byte objs_picked_up = 0; size_t floor_num = 0; int floor_list[MAX_FLOOR_STACK + 1], floor_o_idx = 0; int can_pickup = 0; bool call_function_again = FALSE; bool blind = ((p_ptr->timed[TMD_BLIND]) || (no_light())); bool msg = TRUE; bool telekinesis = (!(y == p_ptr->py) || !(x == p_ptr->px)); /* Nothing to pick up -- return */ if (!cave_o_idx[y][x]) return (0); /* Always pickup gold, effortlessly */ if (!telekinesis) py_pickup_gold(); /* Scan the pile of objects */ for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) { /* Access the object */ o_ptr = &o_list[this_o_idx]; /* Access the next object */ next_o_idx = o_ptr->next_o_idx; /* Ordinary pickup */ if (!telekinesis) { /* Ignore all hidden objects and non-objects */ if (squelch_hide_item(o_ptr) || !o_ptr->k_idx) continue; /* Hack -- disturb */ disturb(0, 0); /* Automatically pick up some items */ if (auto_pickup_okay(o_ptr)) { /* Pick up the object */ py_pickup_aux(this_o_idx, TRUE); objs_picked_up++; /* Check the next object */ continue; } } /* Tally objects and store them in an array. */ /* Remember this object index */ floor_list[floor_num] = this_o_idx; /* Count non-gold objects that remain on the floor. */ floor_num++; /* Tally objects that can be picked up.*/ if (inven_carry_okay(o_ptr)) can_pickup++; } /* There are no non-gold objects */ if (!floor_num) return (objs_picked_up); /* Get hold of the last floor index */ floor_o_idx = floor_list[floor_num - 1]; /* Mention the objects if player is not picking them up. */ if (pickup == 0 || !(can_pickup || telekinesis)) { const char *p = "see"; /* One object */ if (floor_num == 1) { if (!can_pickup) p = "have no room for"; else if (blind) p = "feel"; /* Get the object */ o_ptr = &o_list[floor_o_idx]; /* Describe the object. Less detail if blind. */ if (blind) object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_BASE); else object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Message */ message_flush(); msg_format("You %s %s.", p, o_name); } else { /* Optionally, display more information about floor items */ if (OPT(pickup_detail)) { ui_event_data e; if (!can_pickup) p = "have no room for the following objects"; else if (blind) p = "feel something on the floor"; /* Scan all marked objects in the grid */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03); /* Save screen */ screen_save(); /* Display objects on the floor */ show_floor(floor_list, floor_num, (OLIST_WEIGHT)); /* Display prompt */ prt(format("You %s: ", p), 0, 0); /* Move cursor back to character, if needed */ if (OPT(highlight_player)) move_cursor_relative(p_ptr->py, p_ptr->px); /* Wait for it. Use key as next command. */ e = inkey_ex(); Term_event_push(&e); /* Restore screen */ screen_load(); } /* Show less detail */ else { message_flush(); if (!can_pickup) msg_print("You have no room for any of the items on the floor."); else msg_format("You %s a pile of %d items.", (blind ? "feel" : "see"), floor_num); } } /* Done */ return (objs_picked_up); } /* We can pick up objects. Menus are not requested (yet). */ if (pickup == 1) { /* Scan floor (again) */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03); /* Use a menu interface for multiple objects, or get single objects */ if (floor_num > 1) pickup = 2; else this_o_idx = floor_o_idx; } /* Display a list if requested. */ if (pickup == 2) { cptr q, s; int item; /* Get an object or exit. */ q = "Get which item?"; s = "You see nothing there."; /* Telekinesis */ if (telekinesis) { item_tester_hook = inven_carry_okay; if (!get_item(&item, q, s, CMD_PICKUP, USE_TARGET)) return (objs_picked_up); this_o_idx = 0 - item; } else { /* Restrict the choices */ item_tester_hook = inven_carry_okay; if (!get_item(&item, q, s, CMD_PICKUP, USE_FLOOR)) return (objs_picked_up); this_o_idx = 0 - item; call_function_again = TRUE; } /* With a list, we do not need explicit pickup messages */ msg = FALSE; } /* Pick up object, if legal */ if (this_o_idx) { /* Regular pickup or telekinesis with pack not full */ if (can_pickup) { /* Pick up the object */ py_pickup_aux(this_o_idx, msg); } /* Telekinesis with pack full */ else { /* Access the object */ o_ptr = &o_list[this_o_idx]; /* Drop it */ drop_near(o_ptr, -1, p_ptr->py, p_ptr->px, TRUE); /* Delete the old object */ delete_object_idx(this_o_idx); } } /* Indicate an object picked up. */ objs_picked_up = 1; /* If requested, call this function recursively. Count objects picked up. * Force the display of a menu in all cases. */ if (call_function_again) objs_picked_up += py_pickup(3, y, x); /* Indicate how many objects have been picked up. */ return (objs_picked_up); }
/** * Perform the basic "open" command on doors * * Assume there is no monster blocking the destination * * Returns true if repeated commands may continue */ static bool do_cmd_open_aux(int y, int x) { int i, j; bool more = false; /* Verify legality */ if (!do_cmd_open_test(y, x)) return (false); /* Locked door */ if (square_islockeddoor(cave, y, x)) { /* Disarm factor */ i = player->state.skills[SKILL_DISARM_PHYS]; /* Penalize some conditions */ if (player->timed[TMD_BLIND] || no_light()) i = i / 10; if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) i = i / 10; /* Extract the lock power */ j = square_door_power(cave, y, x); /* Extract the difficulty XXX XXX XXX */ j = i - (j * 4); /* Always have a small chance of success */ if (j < 2) j = 2; if (randint0(100) < j) { /* Message */ msgt(MSG_LOCKPICK, "You have picked the lock."); /* Open the door */ square_open_door(cave, y, x); /* Update the visuals */ square_memorize(cave, y, x); square_light_spot(cave, y, x); player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Experience */ /* Removed to avoid exploit by repeatedly locking and unlocking */ /* player_exp_gain(player, 1); */ } else { event_signal(EVENT_INPUT_FLUSH); /* Message */ msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock."); /* We may keep trying */ more = true; } } else { /* Closed door */ square_open_door(cave, y, x); square_memorize(cave, y, x); square_light_spot(cave, y, x); player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS); sound(MSG_OPENDOOR); } /* Result */ return (more); }
/* * Perform the basic "disarm" command * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ static bool do_cmd_disarm_aux(int y, int x) { int i, j, power; cptr name; bool more = FALSE; /* Verify legality */ if (!do_cmd_disarm_test(y, x)) return (FALSE); /* Get the trap name */ name = f_info[cave_feat[y][x]].name; /* Get the "disarm" factor */ i = p_ptr->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10; if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10; /* XXX XXX XXX Variable power? */ /* Extract trap "power" */ power = 5; /* Extract the difficulty */ j = i - power; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success */ if (randint0(100) < j) { /* Message */ message_format(MSG_DISARM, 0, "You have disarmed the %s.", name); /* Reward */ gain_exp(power); /* Forget the trap */ cave_info[y][x] &= ~(CAVE_MARK); /* Remove the trap */ cave_set_feat(y, x, FEAT_FLOOR); } /* Failure -- Keep trying */ else if ((i > 5) && (randint1(i) > 5)) { flush(); /* Message */ msg_format("You failed to disarm the %s.", name); /* We may keep trying */ more = TRUE; } /* Failure -- Set off the trap */ else { /* Message */ msg_format("You set off the %s!", name); /* Hit the trap */ hit_trap(y, x); } /* Result */ return (more); }
/* * Perform the basic "open" command on doors * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ static bool do_cmd_open_aux(int y, int x) { int i, j; bool more = FALSE; /* Verify legality */ if (!do_cmd_open_test(y, x)) return (FALSE); /* Jammed door */ if (cave_feat[y][x] >= FEAT_DOOR_HEAD + 0x08) { /* Stuck */ msg_print("The door appears to be stuck."); } /* Locked door */ else if (cave_feat[y][x] >= FEAT_DOOR_HEAD + 0x01) { /* Disarm factor */ i = p_ptr->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10; if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10; /* Extract the lock power */ j = cave_feat[y][x] - FEAT_DOOR_HEAD; /* Extract the difficulty XXX XXX XXX */ j = i - (j * 4); /* Always have a small chance of success */ if (j < 2) j = 2; /* Success */ if (randint0(100) < j) { /* Message */ message(MSG_LOCKPICK, 0, "You have picked the lock."); /* Open the door */ cave_set_feat(y, x, FEAT_OPEN); /* Update the visuals */ p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Experience */ gain_exp(1); } /* Failure */ else { flush(); /* Message */ message(MSG_LOCKPICK_FAIL, 0, "You failed to pick the lock."); /* We may keep trying */ more = TRUE; } } /* Closed door */ else { /* Open the door */ cave_set_feat(y, x, FEAT_OPEN); /* Update the visuals */ p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Sound */ sound(MSG_OPENDOOR); } /* Result */ return (more); }
/* Scrolls for the reading -RAK- */ void read_scroll() { int32u i; int j, k, item_val, y, x; int tmp[6], flag, used_up; bigvtype out_val, tmp_str; register int ident, l; register inven_type *i_ptr; register struct misc *m_ptr; free_turn_flag = TRUE; if (py.flags.blind > 0) msg_print("You can't see to read the scroll."); else if (no_light()) msg_print("You have no light to read by."); else if (py.flags.confused > 0) msg_print("You are too confused to read a scroll."); else if (inven_ctr == 0) msg_print("You are not carrying anything!"); else if (!find_range(TV_SCROLL1, TV_SCROLL2, &j, &k)) msg_print ("You are not carrying any scrolls!"); else if (get_item(&item_val, "Read which scroll?", j, k, 0)) { i_ptr = &inventory[item_val]; free_turn_flag = FALSE; used_up = TRUE; i = i_ptr->flags; ident = FALSE; while (i != 0) { j = bit_pos(&i) + 1; if (i_ptr->tval == TV_SCROLL2) j += 32; /* Scrolls. */ switch(j) { case 1: i_ptr = &inventory[INVEN_WIELD]; if (i_ptr->tval != TV_NOTHING) { objdes(tmp_str, i_ptr, FALSE); (void) sprintf(out_val, "Your %s glows faintly!", tmp_str); msg_print(out_val); if (enchant(&i_ptr->tohit)) { i_ptr->flags &= ~TR_CURSED; calc_bonuses(); } else msg_print("The enchantment fails."); ident = TRUE; } break; case 2: i_ptr = &inventory[INVEN_WIELD]; if (i_ptr->tval != TV_NOTHING) { objdes(tmp_str, i_ptr, FALSE); (void) sprintf(out_val, "Your %s glows faintly!", tmp_str); msg_print(out_val); if (enchant(&i_ptr->todam)) { i_ptr->flags &= ~TR_CURSED; calc_bonuses (); } else msg_print("The enchantment fails."); ident = TRUE; } break; case 3: k = 0; l = 0; if (inventory[INVEN_BODY].tval != TV_NOTHING) tmp[k++] = INVEN_BODY; if (inventory[INVEN_ARM].tval != TV_NOTHING) tmp[k++] = INVEN_ARM; if (inventory[INVEN_OUTER].tval != TV_NOTHING) tmp[k++] = INVEN_OUTER; if (inventory[INVEN_HANDS].tval != TV_NOTHING) tmp[k++] = INVEN_HANDS; if (inventory[INVEN_HEAD].tval != TV_NOTHING) tmp[k++] = INVEN_HEAD; /* also enchant boots */ if (inventory[INVEN_FEET].tval != TV_NOTHING) tmp[k++] = INVEN_FEET; if (k > 0) l = tmp[randint(k)-1]; if (TR_CURSED & inventory[INVEN_BODY].flags) l = INVEN_BODY; else if (TR_CURSED & inventory[INVEN_ARM].flags) l = INVEN_ARM; else if (TR_CURSED & inventory[INVEN_OUTER].flags) l = INVEN_OUTER; else if (TR_CURSED & inventory[INVEN_HEAD].flags) l = INVEN_HEAD; else if (TR_CURSED & inventory[INVEN_HANDS].flags) l = INVEN_HANDS; else if (TR_CURSED & inventory[INVEN_FEET].flags) l = INVEN_FEET; if (l > 0) { i_ptr = &inventory[l]; objdes(tmp_str, i_ptr, FALSE); (void) sprintf(out_val, "Your %s glows faintly!", tmp_str); msg_print(out_val); if (enchant(&i_ptr->toac)) { i_ptr->flags &= ~TR_CURSED; calc_bonuses (); } else msg_print("The enchantment fails."); ident = TRUE; } break; case 4: msg_print("This is an identify scroll."); ident = TRUE; used_up = ident_spell(); /* the identify may merge objects, causing the identify scroll to move to a different place. Check for that here. */ if (i_ptr->tval != TV_SCROLL1 || i_ptr->flags != 0x00000008) { item_val--; i_ptr = &inventory[item_val]; if (i_ptr->tval != TV_SCROLL1 || i_ptr->flags != 0x00000008) { msg_print("internal error with identify spell."); msg_print("Please tell the wizard!"); return; } } break; case 5: if (remove_curse()) { msg_print("You feel as if someone is watching over you."); ident = TRUE; } break; case 6: ident = light_area(char_row, char_col); break; case 7: for (k = 0; k < randint(3); k++) { y = char_row; x = char_col; ident |= summon_monster(&y, &x, FALSE); } break; case 8: teleport(10); ident = TRUE; break; case 9: teleport(100); ident = TRUE; break; case 10: (void) tele_level(); ident = TRUE; break; case 11: if (py.flags.confuse_monster == 0) { msg_print("Your hands begin to glow."); py.flags.confuse_monster = TRUE; ident = TRUE; } break; case 12: ident = TRUE; map_area(); break; case 13: ident = sleep_monsters1(char_row, char_col); break; case 14: ident = TRUE; warding_glyph(); break; case 15: ident = detect_treasure(); break; case 16: ident = detect_object(); break; case 17: ident = detect_trap(); break; case 18: ident = detect_sdoor(); break; case 19: msg_print("This is a mass genocide scroll."); ident = mass_genocide(TRUE); break; case 20: ident = detect_invisible(); break; case 21: ident = aggravate_monster(20); if (ident) msg_print("There is a high pitched humming noise."); break; case 22: ident = trap_creation(); break; case 23: ident = td_destroy(); break; case 24: /* Not Used , used to be door creation */ break; case 25: msg_print("This is a Recharge-Item scroll."); ident = TRUE; used_up = recharge(60); break; case 26: msg_print("This is a genocide scroll."); ident = genocide(TRUE); break; case 27: ident = unlight_area(char_row, char_col); break; case 28: ident = protect_evil(); break; case 29: ident = TRUE; create_food(); break; case 30: ident = dispel_creature(UNDEAD, 60); break; case 31: remove_all_curse(); ident = TRUE; break; case 33: i_ptr = &inventory[INVEN_WIELD]; if (i_ptr->tval != TV_NOTHING) { objdes(tmp_str, i_ptr, FALSE); (void) sprintf(out_val, "Your %s glows brightly!", tmp_str); msg_print(out_val); flag = FALSE; for (k = 0; k < randint(2); k++) if (enchant(&i_ptr->tohit)) flag = TRUE; for (k = 0; k < randint(2); k++) if (enchant(&i_ptr->todam)) flag = TRUE; if (flag) { i_ptr->flags &= ~TR_CURSED; calc_bonuses (); } else msg_print("The enchantment fails."); ident = TRUE; } break; case 34: i_ptr = &inventory[INVEN_WIELD]; if (i_ptr->tval != TV_NOTHING) { objdes(tmp_str, i_ptr, FALSE); (void)sprintf(out_val,"Your %s glows black, fades.",tmp_str); msg_print(out_val); unmagic_name(i_ptr); i_ptr->tohit = -randint(5) - randint(5); i_ptr->todam = -randint(5) - randint(5); i_ptr->flags = TR_CURSED; py_bonuses(i_ptr, -1); calc_bonuses (); ident = TRUE; } break; case 35: k = 0; l = 0; if (inventory[INVEN_BODY].tval != TV_NOTHING) tmp[k++] = INVEN_BODY; if (inventory[INVEN_ARM].tval != TV_NOTHING) tmp[k++] = INVEN_ARM; if (inventory[INVEN_OUTER].tval != TV_NOTHING) tmp[k++] = INVEN_OUTER; if (inventory[INVEN_HANDS].tval != TV_NOTHING) tmp[k++] = INVEN_HANDS; if (inventory[INVEN_HEAD].tval != TV_NOTHING) tmp[k++] = INVEN_HEAD; /* also enchant boots */ if (inventory[INVEN_FEET].tval != TV_NOTHING) tmp[k++] = INVEN_FEET; if (k > 0) l = tmp[randint(k)-1]; if (TR_CURSED & inventory[INVEN_BODY].flags) l = INVEN_BODY; else if (TR_CURSED & inventory[INVEN_ARM].flags) l = INVEN_ARM; else if (TR_CURSED & inventory[INVEN_OUTER].flags) l = INVEN_OUTER; else if (TR_CURSED & inventory[INVEN_HEAD].flags) l = INVEN_HEAD; else if (TR_CURSED & inventory[INVEN_HANDS].flags) l = INVEN_HANDS; else if (TR_CURSED & inventory[INVEN_FEET].flags) l = INVEN_FEET; if (l > 0) { i_ptr = &inventory[l]; objdes(tmp_str, i_ptr, FALSE); (void) sprintf(out_val,"Your %s glows brightly!", tmp_str); msg_print(out_val); flag = FALSE; for (k = 0; k < randint(2) + 1; k++) if (enchant(&i_ptr->toac)) flag = TRUE; if (flag) { i_ptr->flags &= ~TR_CURSED; calc_bonuses (); } else msg_print("The enchantment fails."); ident = TRUE; } break; case 36: if ((inventory[INVEN_BODY].tval != TV_NOTHING) && (randint(4) == 1)) k = INVEN_BODY; else if ((inventory[INVEN_ARM].tval != TV_NOTHING) && (randint(3) ==1)) k = INVEN_ARM; else if ((inventory[INVEN_OUTER].tval != TV_NOTHING) && (randint(3) ==1)) k = INVEN_OUTER; else if ((inventory[INVEN_HEAD].tval != TV_NOTHING) && (randint(3) ==1)) k = INVEN_HEAD; else if ((inventory[INVEN_HANDS].tval != TV_NOTHING) && (randint(3) ==1)) k = INVEN_HANDS; else if ((inventory[INVEN_FEET].tval != TV_NOTHING) && (randint(3) ==1)) k = INVEN_FEET; else if (inventory[INVEN_BODY].tval != TV_NOTHING) k = INVEN_BODY; else if (inventory[INVEN_ARM].tval != TV_NOTHING) k = INVEN_ARM; else if (inventory[INVEN_OUTER].tval != TV_NOTHING) k = INVEN_OUTER; else if (inventory[INVEN_HEAD].tval != TV_NOTHING) k = INVEN_HEAD; else if (inventory[INVEN_HANDS].tval != TV_NOTHING) k = INVEN_HANDS; else if (inventory[INVEN_FEET].tval != TV_NOTHING) k = INVEN_FEET; else k = 0; if (k > 0) { i_ptr = &inventory[k]; objdes(tmp_str, i_ptr, FALSE); (void)sprintf(out_val,"Your %s glows black, fades.",tmp_str); msg_print(out_val); unmagic_name(i_ptr); i_ptr->flags = TR_CURSED; i_ptr->toac = -randint(5) - randint(5); calc_bonuses (); ident = TRUE; } break; case 37: ident = FALSE; for (k = 0; k < randint(3); k++) { y = char_row; x = char_col; ident |= summon_undead(&y, &x); } break; case 38: ident = TRUE; bless(randint(12)+6); break; case 39: ident = TRUE; bless(randint(24)+12); break; case 40: ident = TRUE; bless(randint(48)+24); break; case 41: ident = TRUE; if (py.flags.word_recall == 0) py.flags.word_recall = 25 + randint(30); msg_print("The air about you becomes charged."); break; case 42: destroy_area(char_row, char_col); ident = TRUE; break; case 43: place_special(char_row, char_col, SPECIAL); prt_map(); break; case 44: special_random_object(char_row, char_col, 1); prt_map(); break; default: msg_print("Internal error in scroll()"); break; } /* End of Scrolls. */ } i_ptr = &inventory[item_val]; if (ident) { if (!known1_p(i_ptr)) { m_ptr = &py.misc; /* round half-way case up */ m_ptr->exp += (i_ptr->level +(m_ptr->lev >> 1)) / m_ptr->lev; prt_experience(); identify(&item_val); i_ptr = &inventory[item_val]; } }