*/
#include "angband.h"
+#include "bldg.h"
+#include "core.h"
+#include "term.h"
+#include "util.h"
+#include "object-ego.h"
+
+#include "creature.h"
+
+#include "dungeon.h"
#include "floor.h"
+#include "floor-town.h"
+#include "object-boost.h"
+#include "object-flavor.h"
#include "object-hook.h"
#include "melee.h"
+#include "player-move.h"
#include "player-status.h"
-#include "projection.h"
+#include "player-class.h"
+#include "player-damage.h"
#include "spells-summon.h"
#include "quest.h"
#include "artifact.h"
#include "avatar.h"
+#include "spells.h"
#include "spells-floor.h"
+#include "grid.h"
+#include "monster-process.h"
+#include "monster-status.h"
+#include "monster-spell.h"
+#include "cmd-spell.h"
+#include "cmd-dump.h"
+#include "snipe.h"
+#include "floor-save.h"
+#include "files.h"
+#include "player-effects.h"
+#include "player-skill.h"
+#include "player-personality.h"
+#include "view-mainwindow.h"
+#include "mind.h"
+#include "wild.h"
+#include "world.h"
+#include "objectkind.h"
+#include "autopick.h"
+#include "targeting.h"
/*! テレポート先探索の試行数 / Maximum number of tries for teleporting */
bool look = TRUE;
monster_type *m_ptr = ¤t_floor_ptr->m_list[m_idx];
-
- /* Paranoia */
- if (!m_ptr->r_idx) return (FALSE);
+ if (!monster_is_valid(m_ptr)) return (FALSE);
oy = m_ptr->fy;
ox = m_ptr->fx;
POSITION dis = 2;
bool look = TRUE;
monster_type *m_ptr = ¤t_floor_ptr->m_list[m_idx];
-
- /* Paranoia */
if(!m_ptr->r_idx) return;
/* "Skill" test */
sound(SOUND_TELEPORT);
#ifdef JP
- if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
+ if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON))
msg_format("『こっちだぁ、%s』", p_ptr->name);
#endif
for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
{
- o_ptr = &inventory[i];
+ o_ptr = &p_ptr->inventory_list[i];
if (o_ptr->k_idx && !object_is_cursed(o_ptr))
{
object_flags(o_ptr, flgs);
{
prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
}
-
- /* Leaving */
p_ptr->leaving = TRUE;
}
}
prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
leave_quest_check();
-
- /* Leaving */
p_ptr->inside_quest = 0;
p_ptr->leaving = TRUE;
}
if (autosave_l) do_cmd_save_game(TRUE);
prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
-
- /* Leaving */
p_ptr->leaving = TRUE;
}
}
{
/* Never reach this code on the surface */
/* if (!current_floor_ptr->dun_level) p_ptr->dungeon_idx = p_ptr->recall_dungeon; */
-
if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, 1, NULL);
-
if (autosave_l) do_cmd_save_game(TRUE);
prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
-
- /* Leaving */
p_ptr->leaving = TRUE;
}
}
{
monster_type *m_ptr = ¤t_floor_ptr->m_list[m_idx];
- /* Check for quest completion */
check_quest_completion(m_ptr);
if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname)
{
/* Extract request */
dummy = atoi(tmp_val);
-
- /* Paranoia */
if (dummy < 1) dummy = 1;
-
- /* Paranoia */
if (dummy > max_dlv[select_dungeon]) dummy = max_dlv[select_dungeon];
if (dummy < d_info[select_dungeon].mindepth) dummy = d_info[select_dungeon].mindepth;
case 8: t = INVEN_FEET; break;
}
- o_ptr = &inventory[t];
+ o_ptr = &p_ptr->inventory_list[t];
/* No item, nothing happens */
if (!o_ptr->k_idx) return (FALSE);
/* Awake monster */
if (g_ptr->m_idx && MON_CSLEEP(m_ptr))
{
- /* Reset sleep counter */
(void)set_monster_csleep(g_ptr->m_idx, 0);
/* Notice the "waking up" */
return;
}
-
-/*!
- * @brief 守りのルーン設置処理 /
- * Leave a "glyph of warding" which prevents monster movement
- * @return 実際に設置が行われた場合TRUEを返す
- */
-bool warding_glyph(void)
-{
- if (!cave_clean_bold(p_ptr->y, p_ptr->x))
- {
- msg_print(_("床上のアイテムが呪文を跳ね返した。", "The object resists the spell."));
- return FALSE;
- }
-
- /* Create a glyph */
- current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info |= CAVE_OBJECT;
- current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].mimic = feat_glyph;
-
- note_spot(p_ptr->y, p_ptr->x);
- lite_spot(p_ptr->y, p_ptr->x);
-
- return TRUE;
-}
-
-/*!
- * @brief 鏡設置処理
- * @return 実際に設置が行われた場合TRUEを返す
- */
-bool place_mirror(void)
-{
- if (!cave_clean_bold(p_ptr->y, p_ptr->x))
- {
- msg_print(_("床上のアイテムが呪文を跳ね返した。", "The object resists the spell."));
- return FALSE;
- }
-
- /* Create a mirror */
- current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info |= CAVE_OBJECT;
- current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].mimic = feat_mirror;
-
- /* Turn on the light */
- current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info |= CAVE_GLOW;
-
- note_spot(p_ptr->y, p_ptr->x);
- lite_spot(p_ptr->y, p_ptr->x);
- update_local_illumination(p_ptr->y, p_ptr->x);
-
- return TRUE;
-}
-
-
-/*!
- * @brief 爆発のルーン設置処理 /
- * Leave an "explosive rune" which prevents monster movement
- * @return 実際に設置が行われた場合TRUEを返す
- */
-bool explosive_rune(void)
-{
- if (!cave_clean_bold(p_ptr->y, p_ptr->x))
- {
- msg_print(_("床上のアイテムが呪文を跳ね返した。", "The object resists the spell."));
- return FALSE;
- }
-
- /* Create a glyph */
- current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info |= CAVE_OBJECT;
- current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].mimic = feat_explosive_rune;
-
- note_spot(p_ptr->y, p_ptr->x);
- lite_spot(p_ptr->y, p_ptr->x);
-
- return TRUE;
-}
-
-
/*!
* @brief 全所持アイテム鑑定処理 /
* Identify everything being carried.
/* Simply identify and know every item */
for (i = 0; i < INVEN_TOTAL; i++)
{
- object_type *o_ptr = &inventory[i];
-
- /* Skip non-objects */
+ object_type *o_ptr = &p_ptr->inventory_list[i];
if (!o_ptr->k_idx) continue;
identify_item(o_ptr);
/*!
* @brief 装備の解呪処理 /
- * Removes curses from items in inventory
+ * Removes curses from items in p_ptr->inventory_list
* @param all 軽い呪いまでの解除ならば0
* @return 解呪されたアイテムの数
* @details
/* Attempt to uncurse items being worn */
for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
{
- object_type *o_ptr = &inventory[i];
-
- /* Skip non-objects */
+ object_type *o_ptr = &p_ptr->inventory_list[i];
if (!o_ptr->k_idx) continue;
/* Uncursed already */
/*!
* @brief 装備修正強化処理のメインルーチン /
- * Enchant an item (in the inventory or on the floor)
+ * Enchant an item (in the p_ptr->inventory_list or on the floor)
* @param num_hit 命中修正量
* @param num_dam ダメージ修正量
* @param num_ac AC修正量
/*!
* @brief アイテム鑑定のメインルーチン処理 /
- * Identify an object in the inventory (or on the floor)
+ * Identify an object in the p_ptr->inventory_list (or on the floor)
* @param only_equip 装備品のみを対象とするならばTRUEを返す
* @return 実際に鑑定を行ったならばTRUEを返す
* @details
/*!
* @brief アイテム凡庸化のメインルーチン処理 /
- * Identify an object in the inventory (or on the floor)
+ * Identify an object in the p_ptr->inventory_list (or on the floor)
* @param only_equip 装備品のみを対象とするならばTRUEを返す
* @return 実際に凡庸化をを行ったならばTRUEを返す
* @details
* <pre>
- * Mundanify an object in the inventory (or on the floor)
+ * Mundanify an object in the p_ptr->inventory_list (or on the floor)
* This routine does *not* automatically combine objects.
* Returns TRUE if something was mundanified, else FALSE.
* </pre>
/*!
* @brief アイテム*鑑定*のメインルーチン処理 /
- * Identify an object in the inventory (or on the floor)
+ * Identify an object in the p_ptr->inventory_list (or on the floor)
* @param only_equip 装備品のみを対象とするならばTRUEを返す
* @return 実際に鑑定を行ったならばTRUEを返す
* @details
- * Fully "identify" an object in the inventory -BEN-
+ * Fully "identify" an object in the p_ptr->inventory_list -BEN-
* This routine returns TRUE if an item was identified.
*/
bool identify_fully(bool only_equip)
/* All staffs, unstacked wands. */
else recharge_strength = (100 + power - lev - (8 * o_ptr->pval)) / 15;
-
- /* Paranoia */
if (recharge_strength < 0) recharge_strength = 0;
/* Back-fire */
if (o_ptr->tval == TV_ROD) o_ptr->timeout = (o_ptr->number - 1) * k_ptr->pval;
if (o_ptr->tval == TV_WAND) o_ptr->pval = 0;
- /* Reduce and describe inventory */
+ /* Reduce and describe p_ptr->inventory_list */
if (item >= 0)
{
inven_item_increase(item, -1);
else
msg_format(_("乱暴な魔法のために%sが壊れた!", "Wild magic consumes your %s!"), o_name);
- /* Reduce and describe inventory */
+ /* Reduce and describe p_ptr->inventory_list */
if (item >= 0)
{
inven_item_increase(item, -999);
/*!
- * @brief 薬の破損効果処理 /
- * Potions "smash open" and cause an area effect when
- * @param who 薬破損の主体ID(プレイヤー所持アイテムが壊れた場合0、床上のアイテムの場合モンスターID)
- * @param y 破壊時のY座標
- * @param x 破壊時のX座標
- * @param k_idx 破損した薬のアイテムID
- * @return 薬を浴びたモンスターが起こるならばTRUEを返す
- * @details
- * <pre>
- * (1) they are shattered while in the player's inventory,
- * due to cold (etc) attacks;
- * (2) they are thrown at a monster, or obstacle;
- * (3) they are shattered by a "cold ball" or other such spell
- * while lying on the floor.
- *
- * Arguments:
- * who --- who caused the potion to shatter (0=player)
- * potions that smash on the floor are assumed to
- * be caused by no-one (who = 1), as are those that
- * shatter inside the player inventory.
- * (Not anymore -- I changed this; TY)
- * y, x --- coordinates of the potion (or player if
- * the potion was in her inventory);
- * o_ptr --- pointer to the potion object.
- * </pre>
- */
-bool potion_smash_effect(MONSTER_IDX who, POSITION y, POSITION x, KIND_OBJECT_IDX k_idx)
-{
- int radius = 2;
- int dt = 0;
- int dam = 0;
- bool angry = FALSE;
-
- object_kind *k_ptr = &k_info[k_idx];
-
- switch (k_ptr->sval)
- {
- case SV_POTION_SALT_WATER:
- case SV_POTION_SLIME_MOLD:
- case SV_POTION_LOSE_MEMORIES:
- case SV_POTION_DEC_STR:
- case SV_POTION_DEC_INT:
- case SV_POTION_DEC_WIS:
- case SV_POTION_DEC_DEX:
- case SV_POTION_DEC_CON:
- case SV_POTION_DEC_CHR:
- case SV_POTION_WATER: /* perhaps a 'water' attack? */
- case SV_POTION_APPLE_JUICE:
- return TRUE;
-
- case SV_POTION_INFRAVISION:
- case SV_POTION_DETECT_INVIS:
- case SV_POTION_SLOW_POISON:
- case SV_POTION_CURE_POISON:
- case SV_POTION_BOLDNESS:
- case SV_POTION_RESIST_HEAT:
- case SV_POTION_RESIST_COLD:
- case SV_POTION_HEROISM:
- case SV_POTION_BESERK_STRENGTH:
- case SV_POTION_RES_STR:
- case SV_POTION_RES_INT:
- case SV_POTION_RES_WIS:
- case SV_POTION_RES_DEX:
- case SV_POTION_RES_CON:
- case SV_POTION_RES_CHR:
- case SV_POTION_INC_STR:
- case SV_POTION_INC_INT:
- case SV_POTION_INC_WIS:
- case SV_POTION_INC_DEX:
- case SV_POTION_INC_CON:
- case SV_POTION_INC_CHR:
- case SV_POTION_AUGMENTATION:
- case SV_POTION_ENLIGHTENMENT:
- case SV_POTION_STAR_ENLIGHTENMENT:
- case SV_POTION_SELF_KNOWLEDGE:
- case SV_POTION_EXPERIENCE:
- case SV_POTION_RESISTANCE:
- case SV_POTION_INVULNERABILITY:
- case SV_POTION_NEW_LIFE:
- /* All of the above potions have no effect when shattered */
- return FALSE;
- case SV_POTION_SLOWNESS:
- dt = GF_OLD_SLOW;
- dam = 5;
- angry = TRUE;
- break;
- case SV_POTION_POISON:
- dt = GF_POIS;
- dam = 3;
- angry = TRUE;
- break;
- case SV_POTION_BLINDNESS:
- dt = GF_DARK;
- angry = TRUE;
- break;
- case SV_POTION_BOOZE: /* Booze */
- dt = GF_OLD_CONF;
- angry = TRUE;
- break;
- case SV_POTION_SLEEP:
- dt = GF_OLD_SLEEP;
- angry = TRUE;
- break;
- case SV_POTION_RUINATION:
- case SV_POTION_DETONATIONS:
- dt = GF_SHARDS;
- dam = damroll(25, 25);
- angry = TRUE;
- break;
- case SV_POTION_DEATH:
- dt = GF_DEATH_RAY; /* !! */
- dam = k_ptr->level * 10;
- angry = TRUE;
- radius = 1;
- break;
- case SV_POTION_SPEED:
- dt = GF_OLD_SPEED;
- break;
- case SV_POTION_CURE_LIGHT:
- dt = GF_OLD_HEAL;
- dam = damroll(2, 3);
- break;
- case SV_POTION_CURE_SERIOUS:
- dt = GF_OLD_HEAL;
- dam = damroll(4, 3);
- break;
- case SV_POTION_CURE_CRITICAL:
- case SV_POTION_CURING:
- dt = GF_OLD_HEAL;
- dam = damroll(6, 3);
- break;
- case SV_POTION_HEALING:
- dt = GF_OLD_HEAL;
- dam = damroll(10, 10);
- break;
- case SV_POTION_RESTORE_EXP:
- dt = GF_STAR_HEAL;
- dam = 0;
- radius = 1;
- break;
- case SV_POTION_LIFE:
- dt = GF_STAR_HEAL;
- dam = damroll(50, 50);
- radius = 1;
- break;
- case SV_POTION_STAR_HEALING:
- dt = GF_OLD_HEAL;
- dam = damroll(50, 50);
- radius = 1;
- break;
- case SV_POTION_RESTORE_MANA: /* MANA */
- dt = GF_MANA;
- dam = damroll(10, 10);
- radius = 1;
- break;
- default:
- /* Do nothing */ ;
- }
-
- (void)project(who, radius, y, x, dam, dt, (PROJECT_JUMP | PROJECT_ITEM | PROJECT_KILL), -1);
-
- /* XXX those potions that explode need to become "known" */
- return angry;
-}
-
-
-/*!
* @brief プレイヤーの全既知呪文を表示する /
* Hack -- Display all known spells in a window
* return なし
(p_ptr->pclass == CLASS_MIRROR_MASTER) ||
(p_ptr->pclass == CLASS_FORCETRAINER))
{
- int minfail = 0;
+ PERCENTAGE minfail = 0;
PLAYER_LEVEL plev = p_ptr->lev;
- int chance = 0;
+ PERCENTAGE chance = 0;
mind_type spell;
char comment[80];
char psi_desc[80];
{
/* All staffs, wands. */
recharge_strength = (100 + power - lev) / 15;
-
- /* Paranoia */
if (recharge_strength < 0) recharge_strength = 0;
/* Back-fire */
msg_format(_("乱暴な魔法のために%sが何本か壊れた!", "Wild magic consumes your %s!"), o_name);
}
- /* Reduce and describe inventory */
+ /* Reduce and describe p_ptr->inventory_list */
if (item >= 0)
{
inven_item_increase(item, -1);
else
msg_format(_("乱暴な魔法のために%sが壊れた!", "Wild magic consumes your %s!"), o_name);
- /* Reduce and describe inventory */
+ /* Reduce and describe p_ptr->inventory_list */
if (item >= 0)
{
inven_item_increase(item, -999);
if (pet) mode |= PM_FORCE_PET;
else mode |= (PM_NO_PET | PM_FORCE_FRIENDLY);
- count += summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, (pet ? p_ptr->lev * 2 / 3 + randint1(p_ptr->lev / 2) : current_floor_ptr->dun_level), 0, mode, '\0');
+ count += summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, (pet ? p_ptr->lev * 2 / 3 + randint1(p_ptr->lev / 2) : current_floor_ptr->dun_level), 0, mode);
if (!one_in_(6)) break;
}
case 23: case 24: case 25:
return TRUE;
}
+
+/*!
+ * @brief 町間のテレポートを行うメインルーチン。
+ * @return テレポート処理を決定したか否か
+ */
+bool tele_town(void)
+{
+ int i;
+ POSITION x, y;
+ int num = 0;
+
+ if (current_floor_ptr->dun_level)
+ {
+ msg_print(_("この魔法は地上でしか使えない!", "This spell can only be used on the surface!"));
+ return FALSE;
+ }
+
+ if (p_ptr->inside_arena || p_ptr->inside_battle)
+ {
+ msg_print(_("この魔法は外でしか使えない!", "This spell can only be used outside!"));
+ return FALSE;
+ }
+
+ screen_save();
+ clear_bldg(4, 10);
+
+ for (i = 1; i < max_towns; i++)
+ {
+ char buf[80];
+
+ if ((i == NO_TOWN) || (i == SECRET_TOWN) || (i == p_ptr->town_num) || !(p_ptr->visit & (1L << (i - 1)))) continue;
+
+ sprintf(buf, "%c) %-20s", I2A(i - 1), town_info[i].name);
+ prt(buf, 5 + i, 5);
+ num++;
+ }
+
+ if (!num)
+ {
+ msg_print(_("まだ行けるところがない。", "You have not yet visited any town."));
+ msg_print(NULL);
+ screen_load();
+ return FALSE;
+ }
+
+ prt(_("どこに行きますか:", "Which town you go: "), 0, 0);
+ while (1)
+ {
+ i = inkey();
+
+ if (i == ESCAPE)
+ {
+ screen_load();
+ return FALSE;
+ }
+ else if ((i < 'a') || (i > ('a' + max_towns - 2))) continue;
+ else if (((i - 'a' + 1) == p_ptr->town_num) || ((i - 'a' + 1) == NO_TOWN) || ((i - 'a' + 1) == SECRET_TOWN) || !(p_ptr->visit & (1L << (i - 'a')))) continue;
+ break;
+ }
+
+ for (y = 0; y < current_world_ptr->max_wild_y; y++)
+ {
+ for (x = 0; x < current_world_ptr->max_wild_x; x++)
+ {
+ if (wilderness[y][x].town == (i - 'a' + 1))
+ {
+ p_ptr->wilderness_y = y;
+ p_ptr->wilderness_x = x;
+ }
+ }
+ }
+
+ p_ptr->leaving = TRUE;
+ p_ptr->leave_bldg = TRUE;
+ p_ptr->teleport_town = TRUE;
+ screen_load();
+ return TRUE;
+}