2 #include "inventory/inventory-curse.h"
3 #include "object-flavor.h"
4 #include "spells-summon.h"
5 #include "player-damage.h"
6 #include "player-move.h"
7 #include "spell/spells2.h"
8 #include "spell/spells3.h"
10 #include "object-curse.h"
12 #include "object-hook.h"
13 #include "player-effects.h"
14 #include "object/object-kind.h"
16 static bool is_specific_curse(BIT_FLAGS flag)
18 return (flag == TRC_ADD_L_CURSE) ||
19 (flag == TRC_ADD_H_CURSE) ||
20 (flag == TRC_DRAIN_HP) ||
21 (flag == TRC_DRAIN_MANA) ||
22 (flag == TRC_CALL_ANIMAL) ||
23 (flag == TRC_CALL_DEMON) ||
24 (flag == TRC_CALL_DRAGON) ||
25 (flag == TRC_CALL_UNDEAD) ||
26 (flag == TRC_COWARDICE) ||
27 (flag == TRC_LOW_MELEE) ||
28 (flag == TRC_LOW_AC) ||
29 (flag == TRC_LOW_MAGIC) ||
30 (flag == TRC_FAST_DIGEST) ||
31 (flag == TRC_SLOW_REGEN);
34 static void choise_cursed_item(BIT_FLAGS flag, object_type *o_ptr, int *choices, int *number, int item_num)
36 if (!is_specific_curse(flag))
40 BIT_FLAGS flgs[TR_FLAG_SIZE];
41 object_flags(o_ptr, flgs);
89 if (!have_flag(flgs, cf))
92 choices[*number] = item_num;
97 * @brief 現在呪いを保持している装備品を一つランダムに探し出す / Choose one of items that have cursed flag
98 * @param flag 探し出したい呪いフラグ配列
99 * @return 該当の呪いが一つでもあった場合にランダムに選ばれた装備品のオブジェクト構造体参照ポインタを返す。\n
102 object_type *choose_cursed_obj_name(player_type* player_ptr, BIT_FLAGS flag)
104 int choices[INVEN_TOTAL - INVEN_RARM];
106 if (!(player_ptr->cursed & flag))
109 for (int i = INVEN_RARM; i < INVEN_TOTAL; i++) {
110 object_type* o_ptr = &player_ptr->inventory_list[i];
111 if (o_ptr->curse_flags & flag) {
117 choise_cursed_item(flag, o_ptr, choices, &number, i);
120 return &player_ptr->inventory_list[choices[randint0(number)]];
124 * @brief 呪われている、トランプエゴ等による装備品由来のテレポートを実行する
125 * @param creature_ptr プレーヤーへの参照ポインタ
128 static void curse_teleport(player_type* creature_ptr)
130 if (((creature_ptr->cursed & TRC_TELEPORT_SELF) == 0) || !one_in_(200))
133 GAME_TEXT o_name[MAX_NLEN];
135 int i_keep = 0, count = 0;
136 for (int i = INVEN_RARM; i < INVEN_TOTAL; i++) {
137 BIT_FLAGS flgs[TR_FLAG_SIZE];
138 o_ptr = &creature_ptr->inventory_list[i];
142 object_flags(o_ptr, flgs);
144 if (!have_flag(flgs, TR_TELEPORT))
147 if (o_ptr->inscription && my_strchr(quark_str(o_ptr->inscription), '.'))
155 o_ptr = &creature_ptr->inventory_list[i_keep];
156 object_desc(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
157 msg_format(_("%sがテレポートの能力を発動させようとしている。", "Your %s is activating teleportation."), o_name);
158 if (get_check_strict(_("テレポートしますか?", "Teleport? "), CHECK_OKAY_CANCEL)) {
159 disturb(creature_ptr, FALSE, TRUE);
160 teleport_player(creature_ptr, 50, TELEPORT_SPONTANEOUS);
162 msg_format(_("%sに{.}(ピリオド)と銘を刻むと発動を抑制できます。",
163 "You can inscribe {.} on your %s to disable random teleportation. "), o_name);
164 disturb(creature_ptr, TRUE, TRUE);
169 * @details 元々呪い効果の発揮ルーチン中にいたので、整合性保持のためここに置いておく
171 static void occur_chainsword_effect(player_type* creature_ptr)
173 if (((creature_ptr->cursed & TRC_CHAINSWORD) == 0) || !one_in_(CHAINSWORD_NOISE))
177 if (!get_rnd_line(_("chainswd_j.txt", "chainswd.txt"), 0, noise))
179 disturb(creature_ptr, FALSE, FALSE);
182 static void curse_drain_exp(player_type *creature_ptr)
184 if ((creature_ptr->prace == RACE_ANDROID) || ((creature_ptr->cursed & TRC_DRAIN_EXP) == 0) || !one_in_(4))
187 creature_ptr->exp -= (creature_ptr->lev + 1) / 2;
188 if (creature_ptr->exp < 0)
189 creature_ptr->exp = 0;
191 creature_ptr->max_exp -= (creature_ptr->lev + 1) / 2;
192 if (creature_ptr->max_exp < 0)
193 creature_ptr->max_exp = 0;
195 check_experience(creature_ptr);
198 static void multiply_low_curse(player_type* creature_ptr)
200 if (((creature_ptr->cursed & TRC_ADD_L_CURSE) == 0) || !one_in_(2000))
204 o_ptr = choose_cursed_obj_name(creature_ptr, TRC_ADD_L_CURSE);
205 BIT_FLAGS new_curse = get_curse(0, o_ptr);
206 if ((o_ptr->curse_flags & new_curse))
209 GAME_TEXT o_name[MAX_NLEN];
210 object_desc(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
211 o_ptr->curse_flags |= new_curse;
212 msg_format(_("悪意に満ちた黒いオーラが%sをとりまいた...", "There is a malignant black aura surrounding your %s..."), o_name);
213 o_ptr->feeling = FEEL_NONE;
214 creature_ptr->update |= (PU_BONUS);
217 static void multiply_high_curse(player_type* creature_ptr)
219 if (((creature_ptr->cursed & TRC_ADD_H_CURSE) == 0) || !one_in_(2000))
223 o_ptr = choose_cursed_obj_name(creature_ptr, TRC_ADD_H_CURSE);
224 BIT_FLAGS new_curse = get_curse(1, o_ptr);
225 if ((o_ptr->curse_flags & new_curse))
228 GAME_TEXT o_name[MAX_NLEN];
229 object_desc(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
230 o_ptr->curse_flags |= new_curse;
231 msg_format(_("悪意に満ちた黒いオーラが%sをとりまいた...", "There is a malignant black aura surrounding your %s..."), o_name);
232 o_ptr->feeling = FEEL_NONE;
233 creature_ptr->update |= (PU_BONUS);
236 static void occur_curse_effects(player_type *creature_ptr)
238 if (((creature_ptr->cursed & TRC_P_FLAG_MASK) == 0) || creature_ptr->phase_out || creature_ptr->wild_mode)
241 curse_teleport(creature_ptr);
242 occur_chainsword_effect(creature_ptr);
243 if ((creature_ptr->cursed & TRC_TY_CURSE) && one_in_(TY_CURSE_CHANCE)) {
245 (void)activate_ty_curse(creature_ptr, FALSE, &count);
248 curse_drain_exp(creature_ptr);
249 multiply_low_curse(creature_ptr);
250 multiply_high_curse(creature_ptr);
251 if ((creature_ptr->cursed & TRC_CALL_ANIMAL) && one_in_(2500)) {
252 if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_ANIMAL, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET))) {
253 GAME_TEXT o_name[MAX_NLEN];
254 object_desc(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_CALL_ANIMAL), (OD_OMIT_PREFIX | OD_NAME_ONLY));
255 msg_format(_("%sが動物を引き寄せた!", "Your %s has attracted an animal!"), o_name);
256 disturb(creature_ptr, FALSE, TRUE);
260 if ((creature_ptr->cursed & TRC_CALL_DEMON) && one_in_(1111)) {
261 if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_DEMON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET))) {
262 GAME_TEXT o_name[MAX_NLEN];
263 object_desc(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_CALL_DEMON), (OD_OMIT_PREFIX | OD_NAME_ONLY));
264 msg_format(_("%sが悪魔を引き寄せた!", "Your %s has attracted a demon!"), o_name);
265 disturb(creature_ptr, FALSE, TRUE);
269 if ((creature_ptr->cursed & TRC_CALL_DRAGON) && one_in_(800)) {
270 if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_DRAGON,
271 (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET))) {
272 GAME_TEXT o_name[MAX_NLEN];
273 object_desc(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_CALL_DRAGON), (OD_OMIT_PREFIX | OD_NAME_ONLY));
274 msg_format(_("%sがドラゴンを引き寄せた!", "Your %s has attracted an dragon!"), o_name);
275 disturb(creature_ptr, FALSE, TRUE);
279 if ((creature_ptr->cursed & TRC_CALL_UNDEAD) && one_in_(1111)) {
280 if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_UNDEAD,
281 (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET))) {
282 GAME_TEXT o_name[MAX_NLEN];
283 object_desc(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_CALL_UNDEAD), (OD_OMIT_PREFIX | OD_NAME_ONLY));
284 msg_format(_("%sが死霊を引き寄せた!", "Your %s has attracted an undead!"), o_name);
285 disturb(creature_ptr, FALSE, TRUE);
289 if ((creature_ptr->cursed & TRC_COWARDICE) && one_in_(1500)) {
290 if (!creature_ptr->resist_fear) {
291 disturb(creature_ptr, FALSE, TRUE);
292 msg_print(_("とても暗い... とても恐い!", "It's so dark... so scary!"));
293 set_afraid(creature_ptr, creature_ptr->afraid + 13 + randint1(26));
297 if ((creature_ptr->cursed & TRC_TELEPORT) && one_in_(200) && !creature_ptr->anti_tele) {
298 disturb(creature_ptr, FALSE, TRUE);
299 teleport_player(creature_ptr, 40, TELEPORT_PASSIVE);
302 if ((creature_ptr->cursed & TRC_DRAIN_HP) && one_in_(666)) {
303 GAME_TEXT o_name[MAX_NLEN];
304 object_desc(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_DRAIN_HP), (OD_OMIT_PREFIX | OD_NAME_ONLY));
305 msg_format(_("%sはあなたの体力を吸収した!", "Your %s drains HP from you!"), o_name);
306 take_hit(creature_ptr, DAMAGE_LOSELIFE, MIN(creature_ptr->lev * 2, 100), o_name, -1);
309 if ((creature_ptr->cursed & TRC_DRAIN_MANA) && creature_ptr->csp && one_in_(666)) {
310 GAME_TEXT o_name[MAX_NLEN];
311 object_desc(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_DRAIN_MANA), (OD_OMIT_PREFIX | OD_NAME_ONLY));
312 msg_format(_("%sはあなたの魔力を吸収した!", "Your %s drains mana from you!"), o_name);
313 creature_ptr->csp -= MIN(creature_ptr->lev, 50);
314 if (creature_ptr->csp < 0) {
315 creature_ptr->csp = 0;
316 creature_ptr->csp_frac = 0;
319 creature_ptr->redraw |= PR_MANA;
324 * @brief 10ゲームターンが進行するごとに装備効果の発動判定を行う処理
325 * / Handle curse effects once every 10 game turns
326 * @param creature_ptr プレーヤーへの参照ポインタ
329 void execute_cursed_items_effect(player_type* creature_ptr)
331 occur_curse_effects(creature_ptr);
332 if (!one_in_(999) || creature_ptr->anti_magic)
335 object_type* o_ptr = &creature_ptr->inventory_list[INVEN_LITE];
336 if (o_ptr->name1 != ART_JUDGE)
339 if (object_is_known(o_ptr))
340 msg_print(_("『審判の宝石』はあなたの体力を吸収した!", "The Jewel of Judgement drains life from you!"));
342 msg_print(_("なにかがあなたの体力を吸収した!", "Something drains life from you!"));
344 take_hit(creature_ptr, DAMAGE_LOSELIFE, MIN(creature_ptr->lev, 50), _("審判の宝石", "the Jewel of Judgement"), -1);