static void _detect_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Detect Weapons"); break; case SPELL_DESC: var_set_string(res, "Locate nearby weapons, animated or not."); break; case SPELL_CAST: { int rng = DETECT_RAD_DEFAULT; int i, y, x; bool detect = FALSE; if (d_info[dungeon_type].flags1 & DF1_DARKNESS) rng /= 3; for (i = 1; i < o_max; i++) { object_type *o_ptr = &o_list[i]; if (!o_ptr->k_idx) continue; if (o_ptr->held_m_idx) continue; y = o_ptr->iy; x = o_ptr->ix; if (distance(py, px, y, x) > rng) continue; if (!object_is_melee_weapon(o_ptr)) continue; o_ptr->marked |= OM_FOUND; lite_spot(y, x); detect = TRUE; } if (detect_monsters_string(DETECT_RAD_DEFAULT, "|/")) detect = TRUE; if (detect) msg_print("You sense your kind."); var_set_bool(res, TRUE); break; } default: default_spell(cmd, res); break; } }
static bool _mirror_place(void) { if (!cave_clean_bold(py, px)) { msg_print("The object resists the spell."); return FALSE; } cave[py][px].info |= CAVE_OBJECT; cave[py][px].mimic = feat_mirror; cave[py][px].info |= CAVE_GLOW; note_spot(py, px); lite_spot(py, px); update_local_illumination(py, px); return TRUE; }
static bool _sense_great_discovery(int range) { int i, y, x; int range2 = range; bool detect = FALSE; if (d_info[dungeon_type].flags1 & DF1_DARKNESS) range2 /= 3; /* Scan objects */ for (i = 1; i < o_max; i++) { object_type *o_ptr = &o_list[i]; /* Skip dead objects */ if (!o_ptr->k_idx) continue; /* Skip held objects */ if (o_ptr->held_m_idx) continue; /* Only alert to great discoveries */ if (!object_is_artifact(o_ptr)) continue; /* Only alert to new discoveries */ if (object_is_known(o_ptr)) continue; /* Location */ y = o_ptr->iy; x = o_ptr->ix; /* Only detect nearby objects */ if (distance(py, px, y, x) > range2) continue; /* Hack -- memorize it */ o_ptr->marked |= OM_FOUND; p_ptr->window |= PW_OBJECT_LIST; /* Redraw */ lite_spot(y, x); /* Detect */ detect = TRUE; } return (detect); }
void remove_mirror(int y, int x) { cave_type *c_ptr = &cave[y][x]; c_ptr->info &= ~(CAVE_OBJECT); c_ptr->mimic = 0; if (d_info[dungeon_type].flags1 & DF1_DARKNESS) { c_ptr->info &= ~(CAVE_GLOW); if (!view_torch_grids) c_ptr->info &= ~(CAVE_MARK); if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE); update_local_illumination(y, x); } note_spot(y, x); lite_spot(y, x); }
static bool _detect_objects_ego(int range) { int i, y, x; bool detect = FALSE; if (d_info[dungeon_type].flags1 & DF1_DARKNESS) range /= 3; /* Scan all objects */ for (i = 1; i < o_max; i++) { object_type *o_ptr = &o_list[i]; if (!o_ptr->k_idx) continue; if (o_ptr->held_m_idx) continue; y = o_ptr->iy; x = o_ptr->ix; if (distance(py, px, y, x) > range) continue; if (object_is_artifact(o_ptr) || object_is_ego(o_ptr) ) { o_ptr->marked |= OM_FOUND; p_ptr->window |= PW_OBJECT_LIST; lite_spot(y, x); detect = TRUE; } } if (detect) msg_print("You sense the presence of magic objects!"); return detect; }
/* * Create desired feature */ static void do_cmd_wiz_create_feature(void) { static int prev_feat = 0; static int prev_mimic = 0; cave_type *c_ptr; feature_type *f_ptr; char tmp_val[160]; int tmp_feat, tmp_mimic; int y, x; if (!tgt_pt(&x, &y)) return; c_ptr = &cave[y][x]; /* Default */ sprintf(tmp_val, "%d", prev_feat); /* Query */ #ifdef JP if (!get_string("地形: ", tmp_val, 3)) return; #else if (!get_string("Feature: ", tmp_val, 3)) return; #endif /* Extract */ tmp_feat = atoi(tmp_val); if (tmp_feat < 0) tmp_feat = 0; else if (tmp_feat >= max_f_idx) tmp_feat = max_f_idx - 1; /* Default */ sprintf(tmp_val, "%d", prev_mimic); /* Query */ #ifdef JP if (!get_string("地形 (mimic): ", tmp_val, 3)) return; #else if (!get_string("Feature (mimic): ", tmp_val, 3)) return; #endif /* Extract */ tmp_mimic = atoi(tmp_val); if (tmp_mimic < 0) tmp_mimic = 0; else if (tmp_mimic >= max_f_idx) tmp_mimic = max_f_idx - 1; cave_set_feat(y, x, tmp_feat); c_ptr->mimic = tmp_mimic; f_ptr = &f_info[get_feat_mimic(c_ptr)]; if (have_flag(f_ptr->flags, FF_GLYPH) || have_flag(f_ptr->flags, FF_MINOR_GLYPH)) c_ptr->info |= (CAVE_OBJECT); else if (have_flag(f_ptr->flags, FF_MIRROR)) c_ptr->info |= (CAVE_GLOW | CAVE_OBJECT); /* Notice */ note_spot(y, x); /* Redraw */ lite_spot(y, x); /* Update some things */ p_ptr->update |= (PU_FLOW); prev_feat = tmp_feat; prev_mimic = tmp_mimic; }
/*! * @brief 移動先のフロアに伴ったペットを配置する / Place preserved pet monsters on new floor * @return なし */ static void place_pet(void) { int i; int max_num = p_ptr->wild_mode ? 1 : MAX_PARTY_MON; for (i = 0; i < max_num; i++) { POSITION cy = 0, cx = 0; MONSTER_IDX m_idx; if (!(party_mon[i].r_idx)) continue; if (i == 0) { m_idx = m_pop(); p_ptr->riding = m_idx; if (m_idx) { cy = p_ptr->y; cx = p_ptr->x; } } else { int j; POSITION d; for (d = 1; d < 6; d++) { for (j = 1000; j > 0; j--) { scatter(&cy, &cx, p_ptr->y, p_ptr->x, d, 0); if (monster_can_enter(cy, cx, &r_info[party_mon[i].r_idx], 0)) break; } if (j) break; } m_idx = (d == 6) ? 0 : m_pop(); } if (m_idx) { monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr; cave[cy][cx].m_idx = m_idx; m_ptr->r_idx = party_mon[i].r_idx; /* Copy all member of the structure */ *m_ptr = party_mon[i]; r_ptr = real_r_ptr(m_ptr); m_ptr->fy = cy; m_ptr->fx = cx; m_ptr->ml = TRUE; m_ptr->mtimed[MTIMED_CSLEEP] = 0; /* Paranoia */ m_ptr->hold_o_idx = 0; m_ptr->target_y = 0; if ((r_ptr->flags1 & RF1_FORCE_SLEEP) && !ironman_nightmare) { /* Monster is still being nice */ m_ptr->mflag |= (MFLAG_NICE); /* Must repair monsters */ repair_monsters = TRUE; } /* Update the monster */ update_mon(m_idx, TRUE); lite_spot(cy, cx); /* Pre-calculated in precalc_cur_num_of_pet() */ /* r_ptr->cur_num++; */ /* Hack -- Count the number of "reproducers" */ if (r_ptr->flags2 & RF2_MULTIPLY) num_repro++; /* Hack -- Notice new multi-hued monsters */ { monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx]; if (ap_r_ptr->flags1 & (RF1_ATTR_MULTI | RF1_SHAPECHANGER)) shimmer_monsters = TRUE; } } else { monster_type *m_ptr = &party_mon[i]; monster_race *r_ptr = real_r_ptr(m_ptr); char m_name[80]; monster_desc(m_name, m_ptr, 0); #ifdef JP msg_format("%sとはぐれてしまった。", m_name); #else msg_format("You have lost sight of %s.", m_name); #endif if (record_named_pet && m_ptr->nickname) { monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE); do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_LOST_SIGHT, m_name); } /* Pre-calculated in precalc_cur_num_of_pet(), but need to decrease */ if (r_ptr->cur_num) r_ptr->cur_num--; } } /* For accuracy of precalc_cur_num_of_pet() */ (void)C_WIPE(party_mon, MAX_PARTY_MON, monster_type); }
/********************************************************************** * Spells: Note, we are still using the old "Book Spell System" **********************************************************************/ cptr do_necromancy_spell(int spell, int mode) { bool name = (mode == SPELL_NAME) ? TRUE : FALSE; bool desc = (mode == SPELL_DESC) ? TRUE : FALSE; bool info = (mode == SPELL_INFO) ? TRUE : FALSE; bool cast = (mode == SPELL_CAST) ? TRUE : FALSE; bool fail = (mode == SPELL_FAIL) ? TRUE : FALSE; int plev = p_ptr->lev; switch (spell) { /* Stench of Death */ case 0: if (name) return "Cold Touch"; if (desc) return "Damage an adjacent monster with a chilling touch."; if (info) return _necro_info_damage(2, 6, plev + p_ptr->to_d_spell); if (cast && !_necro_do_touch(GF_COLD, 2, 6, plev + p_ptr->to_d_spell)) return NULL; break; case 1: if (name) return "Summon Rat"; if (desc) return "Summons a rat to feast on the dead!"; if (cast || fail) _necro_do_summon(SUMMON_RAT, 1, fail); break; case 2: if (name) return "Detect Life"; if (desc) return "Detects all living monsters in your vicinity."; if (info) return info_radius(DETECT_RAD_DEFAULT); if (cast) detect_monsters_living(DETECT_RAD_DEFAULT, "You sense the presence of life around you."); break; case 3: if (name) return "Detect Unlife"; if (desc) return "Detects all nonliving monsters in your vicinity."; if (info) return info_radius(DETECT_RAD_DEFAULT); if (cast) detect_monsters_nonliving(DETECT_RAD_DEFAULT); break; case 4: if (name) return "Poison Touch"; if (desc) return "Damage an adjacent monster with a venomous touch."; if (info) return _necro_info_damage(4, 6, plev + p_ptr->to_d_spell); if (cast && !_necro_do_touch(GF_POIS, 4, 6, plev + p_ptr->to_d_spell)) return NULL; break; case 5: if (name) return "Summon Bats"; if (desc) return "Summons bats to feast on the living!"; if (cast || fail) _necro_do_summon(SUMMON_BAT, 1 + randint1(2), fail); break; case 6: if (name) return "Eldritch Howl"; if (desc) return "Emit a terrifying howl."; if (cast) project_hack(GF_ELDRITCH_HOWL, spell_power(plev * 3)); break; case 7: if (name) return "Black Touch"; if (desc) return "Damage an adjacent monster with a dark touch."; if (info) return _necro_info_damage(6, 6, plev * 3 / 2 + p_ptr->to_d_spell); if (cast && !_necro_do_touch(GF_DARK, 6, 6, plev * 3 / 2 + p_ptr->to_d_spell)) return NULL; break; /* Sepulchral Ways */ case 8: if (name) return "Summon Wolves"; if (desc) return "Summons wolves to feast on the living!"; if (cast || fail) _necro_do_summon(SUMMON_WOLF, 1 + randint1(2), fail); break; case 9: if (name) return "Black Cloak"; if (desc) return "You become shrouded in darkness."; if (cast) { set_tim_dark_stalker(spell_power(randint1(plev) + plev), FALSE); } break; case 10: if (name) return "Undead Sight"; if (desc) return "Learn about your nearby surroundings by communing with the dead."; if (info) return info_radius(DETECT_RAD_MAP); if (cast) { map_area(DETECT_RAD_MAP); detect_traps(DETECT_RAD_DEFAULT, TRUE); detect_doors(DETECT_RAD_DEFAULT); detect_stairs(DETECT_RAD_DEFAULT); } break; case 11: if (name) return "Undead Lore"; if (desc) return "Ask the dead to examine an object for you."; if (cast) ident_spell(NULL); break; case 12: if (name) return "Repelling Touch"; if (desc) return "Conjure a foul wind to blow an adjacent monster away."; if (cast) { int y, x, dir; if (!_necro_check_touch()) return NULL; if (!get_rep_dir2(&dir)) return NULL; if (dir == 5) return NULL; y = py + ddy[dir]; x = px + ddx[dir]; if (!cave[y][x].m_idx) { msg_print("There is no monster."); return NULL; } else { int i; int ty = y, tx = x; int oy = y, ox = x; int m_idx = cave[y][x].m_idx; monster_type *m_ptr = &m_list[m_idx]; char m_name[80]; monster_desc(m_name, m_ptr, 0); touch_zap_player(cave[y][x].m_idx); for (i = 0; i < 10; i++) { y += ddy[dir]; x += ddx[dir]; if (cave_empty_bold(y, x)) { ty = y; tx = x; } else break; } if ((ty != oy) || (tx != ox)) { msg_format("A foul wind blows %s away!", m_name); cave[oy][ox].m_idx = 0; cave[ty][tx].m_idx = m_idx; m_ptr->fy = ty; m_ptr->fx = tx; update_mon(m_idx, TRUE); lite_spot(oy, ox); lite_spot(ty, tx); if (r_info[m_ptr->r_idx].flags7 & (RF7_LITE_MASK | RF7_DARK_MASK)) p_ptr->update |= (PU_MON_LITE); } } } break; case 13: if (name) return "Vampiric Touch"; if (desc) return "Steal life from an adjacent foe."; if (info) return _necro_info_damage(0, 0, plev * 4 + p_ptr->to_d_spell); if (cast && !_necro_do_touch(GF_OLD_DRAIN, 0, 0, plev * 4 + p_ptr->to_d_spell)) return NULL; break; case 14: if (name) return "Dread of Night"; if (desc) return "Summons Dread to do your bidding. Beware of failure!"; if (cast || fail) _necro_do_summon(SUMMON_DREAD, 1 + randint0(3), fail); break; case 15: if (name) return "Entomb"; if (desc) return "Entombs chosen foe."; if (cast) { int dir; if (!get_fire_dir(&dir)) return NULL; fire_ball_hide(GF_ENTOMB, dir, plev, 0); p_ptr->update |= (PU_FLOW); p_ptr->redraw |= (PR_MAP); } break; /* Return of the Dead */ case 16: if (name) return "Summon Zombies"; if (desc) return "The dead are back and hungry for brains!"; if (cast || fail) _necro_do_summon(SUMMON_ZOMBIE, 2 + randint1(3), fail); break; case 17: if (name) return "Summon Skeletons"; if (desc) return "Summon skeletal assistance."; if (cast || fail) _necro_do_summon(SUMMON_SKELETON, 1 + randint0(3), fail); break; case 18: if (name) return "Summon Ghosts"; if (desc) return "Recall the spirits of slain warriors for unholy servitude."; if (cast || fail) _necro_do_summon(SUMMON_GHOST, 1 + randint0(3), fail); break; case 19: if (name) return "Summon Vampires"; if (desc) return "Its time to command the commanders!"; if (cast || fail) _necro_do_summon(SUMMON_VAMPIRE, 1 + randint0(2), fail); break; case 20: if (name) return "Summon Wraiths"; if (desc) return "Summon wights and wraiths to do your bidding."; if (cast || fail) _necro_do_summon(SUMMON_WIGHT, 1 + randint0(2), fail); break; case 21: if (name) return "Summon Liches"; if (desc) return "Call forth former necromancers."; if (cast || fail) _necro_do_summon(SUMMON_LICH, 1 + randint0(2), fail); break; case 22: if (name) return "Unholy Word"; if (desc) return "Utter an unspeakable word. The morale of your visible evil pets is temporarily boosted and they will serve you with renewed enthusiasm."; if (cast) project_hack(GF_UNHOLY_WORD, plev * 6); break; case 23: if (name) return "Lost Cause"; if (desc) return "Make a last ditch Kamikaze effort for victory!"; if (cast) discharge_minion(); break; /* Necromatic Tome */ case 24: if (name) return "Draining Touch"; if (desc) return "Steal mana from an adjacent foe."; if (info) return _necro_info_damage(5, 5, plev/2 + p_ptr->to_d_spell); if (cast && !_necro_do_touch(GF_DRAINING_TOUCH, 5, 5, plev/2 + p_ptr->to_d_spell)) return NULL; break; case 25: if (name) return "Unhallow Ground"; if (desc) return "Makes the current square unholy."; if (cast) warding_glyph(); /* TODO: Add new cave feature! */ break; case 26: { int base = spell_power(20); if (name) return "Shield of the Dead"; if (desc) return "Grants temporary protection"; if (info) return info_duration(base, base); if (cast) { set_tim_res_nether(randint1(base) + base, FALSE); set_oppose_pois(randint1(base) + base, FALSE); set_oppose_cold(randint1(base) + base, FALSE); set_shield(randint1(base) + base, FALSE); } break; } case 27: if (name) return "Rending Touch"; if (desc) return "Damage an adjacent monster with a disintegrating touch."; if (info) return _necro_info_damage(20, 20, plev + p_ptr->to_d_spell); if (cast && !_necro_do_touch(GF_DISINTEGRATE, 20, 20, plev + p_ptr->to_d_spell)) return NULL; break; case 28: if (name) return "Repose of the Dead"; if (desc) return "Sleep the sleep of the dead for a few rounds, during which time nothing can awaken you, except perhaps death. When (if?) you wake up, you will be thoroughly refreshed!"; if (cast) { if (!get_check("You will enter a deep slumber. Are you sure?")) return NULL; repose_of_the_dead = TRUE; set_paralyzed(4 + randint1(4), FALSE); } break; case 29: if (name) return "Sepulchral Wind"; if (desc) return "You call forth the wind of the dead. All nearby monsters are blown away!"; { int power = spell_power(plev * 4); if (info) return info_power(power); if (cast) banish_monsters(power); } break; case 30: if (name) return "Deadly Touch"; if (desc) return "Attempt to kill an adjacent monster."; if (cast && !_necro_do_touch(GF_DEATH_TOUCH, 0, 0, plev * 200)) return NULL; break; case 31: if (name) return "Necromancy"; if (desc) return "Bridge the world of the living with the world of the dead! Vast hordes of undead will come forth to serve the one true necromancer!"; if (cast) { int i; int sp_sides = 20 + plev; int sp_base = plev; int power = spell_power(plev); power += randint1(power); for (i = 0; i < 18; i++) { int attempt = 10; int my, mx, what; while (attempt--) { scatter(&my, &mx, py, px, 4, 0); /* Require empty grids */ if (cave_empty_bold2(my, mx)) break; } if (attempt < 0) continue; switch (randint1(4)) { case 1: what = SUMMON_LICH; break; case 2: what = SUMMON_WIGHT; break; case 3: what = SUMMON_VAMPIRE; break; case 4: default: what = SUMMON_GHOST; break; } summon_specific(-1, my, mx, power, what, (PM_ALLOW_GROUP | PM_FORCE_PET | PM_HASTE)); } set_fast(randint1(sp_sides) + sp_base, FALSE); } break; } return ""; }
/* * Let an object fall to the ground at or near a location. * * The initial location is assumed to be "in_bounds()". * * This function takes a parameter "chance". This is the percentage * chance that the item will "disappear" instead of drop. If the object * has been thrown, then this is the chance of disappearance on contact. * * Hack -- this function uses "chance" to determine if it should produce * some form of "description" of the drop event (under the player). * * We check several locations to see if we can find a location at which * the object can combine, stack, or be placed. Artifacts will try very * hard to be placed, including "teleporting" to a useful grid if needed. */ s16b drop_near(object_type *j_ptr, s32b chance, s32b y, s32b x) { s32b i, k, d, s; s32b bs, bn; s32b by, bx; s32b dy, dx; s32b ty, tx; s16b o_idx = 0; cave_type *c_ptr; char o_name[80]; bool flag = FALSE; bool plural = FALSE; /* Extract plural */ if (j_ptr->number != 1) plural = TRUE; /* Describe object */ object_desc(o_name, j_ptr, FALSE, 0); /* Handle normal "breakage" */ if (!(j_ptr->art_name || artifact_p(j_ptr)) && (rand_int(100) < chance)) { /* Message */ msg_format("The %s disappear%s.", o_name, (plural ? "" : "s")); /* Debug */ if (wizard) msg_print("(breakage)"); delete_object(j_ptr); /* Failure */ return (0); } /* Score */ bs = -1; /* Picker */ bn = 0; /* Default */ by = y; bx = x; /* Scan local grids */ for (dy = -3; dy <= 3; dy++) { /* Scan local grids */ for (dx = -3; dx <= 3; dx++) { bool comb = FALSE; /* Calculate actual distance */ d = (dy * dy) + (dx * dx); /* Ignore distant grids */ if (d > 10) continue; /* Location */ ty = y + dy; tx = x + dx; /* Skip illegal grids */ if (!in_bounds(ty, tx)) continue; /* Require line of sight */ if (!los(y, x, ty, tx)) continue; /* Obtain grid */ c_ptr = &cave[ty][tx]; /* Require floor space (or shallow terrain) -KMW- */ if (!has_flag(&f_info[c_ptr->feat], FLAG_FLOOR)) continue; /* No traps */ if (flag_used(&c_ptr->activations)) continue; /* No objects */ k = 0; /* Scan objects in that grid */ for_inventory_slot(&c_ptr->inventory, o_ptr); { /* Check for possible combination */ if (object_similar(o_ptr, j_ptr)) comb = TRUE; /* Count objects */ k++; } end_inventory_slot(); /* Add new object */ if (!comb) k++; /* Paranoia */ if (k >= inventory_limit_inven(&c_ptr->inventory)) continue; /* Calculate score */ s = 1000 - (d + k * 5); /* Skip bad values */ if (s < bs) continue; /* New best value */ if (s > bs) bn = 0; /* Apply the randomizer to equivalent values */ if ((++bn >= 2) && (rand_int(bn) != 0)) continue; /* Keep score */ bs = s; /* Track it */ by = ty; bx = tx; /* Okay */ flag = TRUE; } } /* Handle lack of space */ if (!flag && !(artifact_p(j_ptr) || j_ptr->art_name)) { /* Message */ msg_format("The %s disappear%s.", o_name, (plural ? "" : "s")); /* Debug */ if (wizard) msg_print("(no floor space)"); delete_object(j_ptr); /* Failure */ return (0); } /* Find a grid */ for (i = 0; !flag; i++) { /* Bounce around */ if (i < 1000) { ty = rand_spread(by, 1); tx = rand_spread(bx, 1); } /* Random locations */ else { ty = rand_int(cur_hgt); tx = rand_int(cur_wid); } /* Grid */ c_ptr = &cave[ty][tx]; /* Require floor space */ if (!has_flag(&f_info[c_ptr->feat], FLAG_FLOOR) || has_flag(&f_info[c_ptr->feat], FLAG_NO_WALK)) continue; /* Bounce to that location */ by = ty; bx = tx; /* Require floor space */ if (!cave_clean_bold(by, bx)) continue; /* Okay */ flag = TRUE; } j_ptr->iy = by; j_ptr->ix = bx; j_ptr->held_m_idx = 0; /* Grid */ c_ptr = &cave[by][bx]; /* Carry */ o_idx = inven_carry_inven(&c_ptr->inventory, j_ptr, FALSE); /* * j_ptr might have been merged into an existing object and then * deleted, so re-get the object. */ j_ptr = get_object(item_slot_to_item(o_idx)); /* Note the spot */ note_spot(by, bx); /* Draw the spot */ lite_spot(by, bx); /* Mega-Hack -- no message if "dropped" by player */ /* Message when an object falls under the player */ if (chance && (by == p_ptr->py) && (bx == p_ptr->px)) { msg_print("You feel something roll beneath your feet."); /* Sound */ sound(SOUND_DROP); } process_hooks(HOOK_DROPPED_NEAR, "(O,b,d,d,d,d)", j_ptr, chance, y, x, by, bx); /* XXX XXX XXX */ /* Result */ return (o_idx); }
static void _greater_whirlwind_attack_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Greater Ambush"); break; case SPELL_DESC: var_set_string(res, "Perform a massive ambush on nearby monsters."); break; case SPELL_CAST: { int i, x, y; cave_type *c_ptr; monster_type *m_ptr; /* cba d218l e3@7k f456j ghi */ typedef struct _offset_t { int dx; int dy; } _offset; static _offset offsets[] = { { 0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, { 0, 1}, { 1, 1}, { 1, 0}, { 1, -1}, { 1, -2}, { 0, -2}, {-1, -2}, {-2, -1}, {-2, 0}, {-2, 1}, {-1, 2}, { 0, 2}, { 1, 2}, { 2, 1}, { 2, 0}, { 2, -1}, { 0, 0}, /* sentinel */ }; for (i = 0;; i++) { _offset offset = offsets[i]; if (offset.dx == 0 && offset.dy == 0) break; y = py + offset.dy; x = px + offset.dx; if (!in_bounds(y, x)) continue; if (!projectable(py, px, y, x)) continue; c_ptr = &cave[y][x]; if (!c_ptr->m_idx) continue; m_ptr = &m_list[c_ptr->m_idx]; if (m_ptr->ml || cave_have_flag_bold(y, x, FF_PROJECT)) { int msec = delay_factor * delay_factor * delay_factor; if (panel_contains(y, x) && player_can_see_bold(y, x)) { char c = 0x30; byte a = TERM_WHITE; print_rel(c, a, y, x); move_cursor_relative(y, x); Term_fresh(); Term_xtra(TERM_XTRA_DELAY, msec); lite_spot(y, x); Term_fresh(); } else Term_xtra(TERM_XTRA_DELAY, msec); py_attack(y, x, 0); } } var_set_bool(res, TRUE); break; } default: default_spell(cmd, res); break; } }
/* * Wield or wear a single item from the pack or floor */ void do_cmd_wield(void) { int i, item, slot; object_type forge; object_type *q_ptr; object_type *o_ptr; cptr act; char o_name[MAX_NLEN]; cptr q, s; bool newrace = FALSE; /* Restrict the choices */ item_tester_hook = item_tester_hook_wear; /* Get an item */ #ifdef JP q = "どれを装備しますか? "; s = "装備可能なアイテムがない。"; #else q = "Wear/Wield which item? "; s = "You have nothing you can wear or wield."; #endif if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Check the slot */ slot = wield_slot(o_ptr); /* Where is the item now */ if (slot == INVEN_WIELD) { #ifdef JP act = "を打撃用に装備した"; #else act = "You are wielding"; #endif } else if (slot == INVEN_BOW) { #ifdef JP act = "を射撃用に装備した"; #else act = "You are shooting with"; #endif } else if (slot == INVEN_LITE) { #ifdef JP act = "を光源にした"; #else act = "Your light source is"; #endif } else { #ifdef JP act = "を装備した"; #else act = "You are wearing"; #endif } if ((o_ptr->tval == TV_RING) && inventory[INVEN_LEFT].k_idx && inventory[INVEN_RIGHT].k_idx) { /* Restrict the choices */ item_tester_tval = TV_RING; /* Choose a ring from the equipment only */ #ifdef JP q = "どちらの指輪と取り替えますか?"; s = "おっと。"; #else q = "Replace which ring? "; s = "Oops."; #endif if (!get_item(&slot, q, s, (USE_EQUIP))) return; } if (slot == INVEN_WIELD) { if (is_two_handed()) { /* Restrict the choices */ item_tester_hook = item_tester_hook_melee_weapon; /* Choose a ring from the equipment only */ #ifdef JP q = "どちらの武器と取り替えますか?"; s = "おっと。"; #else q = "Replace which weapon? "; s = "Oops."; #endif if (!get_item(&slot, q, s, (USE_EQUIP))) return; } else if (inventory[slot].k_idx) { /* Confirm doing two handed combat */ #ifdef JP if (get_check("二刀流を行いますか?")) #else if (get_check("Do you want to do two handed combat?")) #endif { slot = INVEN_ARM; } } } /* Prevent wielding into a cursed slot */ if (cursed_p(&inventory[slot])) { /* Describe it */ object_desc(o_name, &inventory[slot], OD_OMIT_PREFIX | OD_NAME_ONLY); /* Message */ #ifdef JP msg_format("%s%sは呪われているようだ。", describe_use(slot) , o_name ); #else msg_format("The %s you are %s appears to be cursed.", o_name, describe_use(slot)); #endif /* Cancel the command */ return; } if (cursed_p(o_ptr) && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE))) { char dummy[512]; /* Describe it */ object_desc(o_name, o_ptr, OD_OMIT_PREFIX | OD_NAME_ONLY); #ifdef JP sprintf(dummy, "本当に%s{呪われている}を使いますか?", o_name); #else sprintf(dummy, "Really use the %s {cursed}? ", o_name); #endif if (!get_check(dummy)) return; } #if 0 if ((o_ptr->name1 == ART_STONEMASK) && object_known_p(o_ptr) && (p_ptr->prace != RACE_VAMPIRE)) { char dummy[MAX_NLEN+80]; /* Describe it */ object_desc(o_name, o_ptr, OD_OMIT_PREFIX | OD_NAME_ONLY); #ifdef JP sprintf(dummy, "%sを装備すると吸血鬼になります。よろしいですか?", o_name); #else msg_format("%s will transforms you into a vampire permanently when equiped.", o_name); sprintf(dummy, "Do you become a vampire?"); #endif if (!get_check(dummy)) return; } #endif /* Check if completed a quest */ for (i = 0; i < max_quests; i++) { if ((quest[i].type == QUEST_TYPE_FIND_ARTIFACT) && (quest[i].status == QUEST_STATUS_TAKEN) && (quest[i].k_idx == o_ptr->name1)) { quest[i].status = QUEST_STATUS_COMPLETED; quest[i].complev = (byte)p_ptr->lev; #ifdef JP msg_print("クエストを達成した!"); #else msg_print("You completed your quest!"); #endif sound(SOUND_LEVEL); /* (Sound substitute) No quest sound */ msg_print(NULL); } } /* Take a turn */ energy_use = 100; /* Get local object */ q_ptr = &forge; /* Obtain local object */ object_copy(q_ptr, o_ptr); /* Modify quantity */ q_ptr->number = 1; /* Decrease the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -1); inven_item_optimize(item); } /* Decrease the item (from the floor) */ else { floor_item_increase(0 - item, -1); floor_item_optimize(0 - item); } /* Access the wield slot */ o_ptr = &inventory[slot]; /* Take off existing item */ if (o_ptr->k_idx) { /* Take off existing item */ (void)inven_takeoff(slot, 255); } /* Wear the new stuff */ object_copy(o_ptr, q_ptr); /* Player touches it */ o_ptr->marked |= OM_TOUCHED; /* Forget stack */ o_ptr->next_o_idx = 0; /* Forget location */ o_ptr->iy = o_ptr->ix = 0; /* Increase the weight */ p_ptr->total_weight += q_ptr->weight; /* Increment the equip counter by hand */ equip_cnt++; /* Describe the result */ object_desc(o_name, o_ptr, 0); /* Message */ #ifdef JP msg_format("%s(%c)%s。", o_name, index_to_label(slot), act ); #else msg_format("%s %s (%c).", act, o_name, index_to_label(slot)); #endif sound(SOUND_WIELD); /* Cursed! */ if (cursed_p(o_ptr)) { /* Warn the player */ #ifdef JP msg_print("うわ! すさまじく冷たい!"); #else msg_print("Oops! It feels deathly cold!"); #endif sound(SOUND_CURSED); /* Note the curse */ o_ptr->ident |= (IDENT_SENSE); } #if 0 /* if you weild stonemask, you morph into vampire */ if ((o_ptr->name1 == ART_STONEMASK) && (!is_undead())) { p_ptr->prace = RACE_VAMPIRE; newrace = TRUE; #ifdef JP msg_format("あなたは吸血鬼に変化した!"); #else msg_format("You polymorphed into a vampire!"); #endif } #endif if (newrace) { rp_ptr = &race_info[p_ptr->prace]; /* Experience factor */ calc_expfact(); /* Get new height and weight */ get_ahw(FALSE); check_experience(); /* Hitdice */ p_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp; do_cmd_rerate(TRUE); p_ptr->redraw |= (PR_BASIC); p_ptr->update |= (PU_BONUS); handle_stuff(); /* Load an autopick preference file */ autopick_load_pref(FALSE); lite_spot(py, px); } /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Recalculate torch */ p_ptr->update |= (PU_TORCH); /* Recalculate mana */ p_ptr->update |= (PU_MANA); p_ptr->redraw |= (PR_EQUIPPY); /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER | PW_STATS); }