2 * @brief 読むことができるアイテム群の内、巻物を読んだ時の効果や処理を記述する.
7 #include "object-use/read/scroll-read-executor.h"
8 #include "monster-floor/monster-summon.h"
9 #include "monster-floor/place-monster-types.h"
10 #include "player-base/player-class.h"
11 #include "player-info/equipment-info.h"
12 #include "player/attack-defense-types.h"
13 #include "player/digestion-processor.h"
14 #include "player/player-damage.h"
15 #include "player/player-status-flags.h"
16 #include "spell-kind/magic-item-recharger.h"
17 #include "spell-kind/spells-curse-removal.h"
18 #include "spell-kind/spells-detection.h"
19 #include "spell-kind/spells-enchant.h"
20 #include "spell-kind/spells-floor.h"
21 #include "spell-kind/spells-genocide.h"
22 #include "spell-kind/spells-grid.h"
23 #include "spell-kind/spells-launcher.h"
24 #include "spell-kind/spells-lite.h"
25 #include "spell-kind/spells-neighbor.h"
26 #include "spell-kind/spells-perception.h"
27 #include "spell-kind/spells-sight.h"
28 #include "spell-kind/spells-teleport.h"
29 #include "spell-kind/spells-world.h"
30 #include "spell/spells-object.h"
31 #include "spell/spells-summon.h"
32 #include "spell/summon-types.h"
33 #include "status/bad-status-setter.h"
34 #include "status/body-improvement.h"
35 #include "status/buff-setter.h"
36 #include "status/element-resistance.h"
37 #include "store/rumor.h"
38 #include "sv-definition/sv-scroll-types.h"
39 #include "system/floor-type-definition.h"
40 #include "system/item-entity.h"
41 #include "system/player-type-definition.h"
42 #include "system/redrawing-flags-updater.h"
43 #include "util/bit-flags-calculator.h"
44 #include "view/display-messages.h"
46 ScrollReadExecutor::ScrollReadExecutor(PlayerType *player_ptr, ItemEntity *o_ptr, bool known)
47 : player_ptr(player_ptr)
53 bool ScrollReadExecutor::is_identified() const
58 bool ScrollReadExecutor::read()
61 auto *floor_ptr = this->player_ptr->current_floor_ptr;
62 switch (this->o_ptr->bi_key.sval().value()) {
63 case SV_SCROLL_DARKNESS:
64 if (!has_resist_blind(this->player_ptr) && !has_resist_dark(this->player_ptr)) {
65 (void)BadStatusSetter(this->player_ptr).mod_blindness(3 + randint1(5));
68 if (unlite_area(this->player_ptr, 10, 3)) {
73 case SV_SCROLL_AGGRAVATE_MONSTER:
74 msg_print(_("カン高くうなる様な音が辺りを覆った。", "There is a high pitched humming noise."));
75 aggravate_monsters(this->player_ptr, 0);
78 case SV_SCROLL_CURSE_ARMOR:
79 if (curse_armor(this->player_ptr)) {
84 case SV_SCROLL_CURSE_WEAPON: {
86 if (has_melee_weapon(this->player_ptr, INVEN_MAIN_HAND)) {
88 if (has_melee_weapon(this->player_ptr, INVEN_SUB_HAND) && one_in_(2)) {
91 } else if (has_melee_weapon(this->player_ptr, INVEN_SUB_HAND)) {
95 if (k && curse_weapon_object(this->player_ptr, false, &this->player_ptr->inventory_list[k])) {
101 case SV_SCROLL_SUMMON_MONSTER:
102 for (auto k = 0; k < randint1(3); k++) {
103 if (summon_specific(this->player_ptr, 0, this->player_ptr->y, this->player_ptr->x, floor_ptr->dun_level, SUMMON_NONE,
104 PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)) {
110 case SV_SCROLL_SUMMON_UNDEAD:
111 for (auto k = 0; k < randint1(3); k++) {
112 if (summon_specific(this->player_ptr, 0, this->player_ptr->y, this->player_ptr->x, floor_ptr->dun_level, SUMMON_UNDEAD,
113 PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)) {
119 case SV_SCROLL_SUMMON_PET:
121 this->player_ptr, -1, this->player_ptr->y, this->player_ptr->x, floor_ptr->dun_level, SUMMON_NONE, PM_ALLOW_GROUP | PM_FORCE_PET)) {
126 case SV_SCROLL_SUMMON_KIN:
127 if (summon_kin_player(this->player_ptr, this->player_ptr->lev, this->player_ptr->y, this->player_ptr->x, PM_FORCE_PET | PM_ALLOW_GROUP)) {
132 case SV_SCROLL_TRAP_CREATION:
133 if (trap_creation(this->player_ptr, this->player_ptr->y, this->player_ptr->x)) {
138 case SV_SCROLL_PHASE_DOOR:
139 teleport_player(this->player_ptr, 10, TELEPORT_SPONTANEOUS);
142 case SV_SCROLL_TELEPORT:
143 teleport_player(this->player_ptr, 100, TELEPORT_SPONTANEOUS);
146 case SV_SCROLL_TELEPORT_LEVEL: {
147 (void)teleport_level(this->player_ptr, 0);
151 case SV_SCROLL_WORD_OF_RECALL:
152 if (!recall_player(this->player_ptr, randint0(21) + 15)) {
158 case SV_SCROLL_IDENTIFY:
159 if (!ident_spell(this->player_ptr, false)) {
165 case SV_SCROLL_STAR_IDENTIFY:
166 if (!identify_fully(this->player_ptr, false)) {
172 case SV_SCROLL_REMOVE_CURSE:
173 if (remove_curse(this->player_ptr)) {
178 case SV_SCROLL_STAR_REMOVE_CURSE:
179 if (remove_all_curse(this->player_ptr)) {
184 case SV_SCROLL_ENCHANT_ARMOR:
186 if (!enchant_spell(this->player_ptr, 0, 0, 1)) {
191 case SV_SCROLL_ENCHANT_WEAPON_TO_HIT:
192 if (!enchant_spell(this->player_ptr, 1, 0, 0)) {
198 case SV_SCROLL_ENCHANT_WEAPON_TO_DAM:
199 if (!enchant_spell(this->player_ptr, 0, 1, 0)) {
205 case SV_SCROLL_STAR_ENCHANT_ARMOR:
206 if (!enchant_spell(this->player_ptr, 0, 0, randint1(3) + 2)) {
212 case SV_SCROLL_STAR_ENCHANT_WEAPON:
213 if (!enchant_spell(this->player_ptr, randint1(3), randint1(3), 0)) {
219 case SV_SCROLL_RECHARGING:
220 if (!recharge(this->player_ptr, 130)) {
226 case SV_SCROLL_MUNDANITY:
228 if (!mundane_spell(this->player_ptr, false)) {
233 case SV_SCROLL_LIGHT:
234 if (lite_area(this->player_ptr, damroll(2, 8), 2)) {
239 case SV_SCROLL_MAPPING:
240 map_area(this->player_ptr, DETECT_RAD_MAP);
243 case SV_SCROLL_DETECT_GOLD:
244 if (detect_treasure(this->player_ptr, DETECT_RAD_DEFAULT) || detect_objects_gold(this->player_ptr, DETECT_RAD_DEFAULT)) {
249 case SV_SCROLL_DETECT_ITEM:
250 if (detect_objects_normal(this->player_ptr, DETECT_RAD_DEFAULT)) {
255 case SV_SCROLL_DETECT_TRAP:
256 if (detect_traps(this->player_ptr, DETECT_RAD_DEFAULT, this->known)) {
261 case SV_SCROLL_DETECT_DOOR:
262 if (detect_doors(this->player_ptr, DETECT_RAD_DEFAULT) || detect_stairs(this->player_ptr, DETECT_RAD_DEFAULT)) {
267 case SV_SCROLL_DETECT_INVIS:
268 if (detect_monsters_invis(this->player_ptr, DETECT_RAD_DEFAULT)) {
273 case SV_SCROLL_SATISFY_HUNGER: {
274 if (set_food(this->player_ptr, PY_FOOD_MAX - 1)) {
280 case SV_SCROLL_BLESSING:
281 if (set_blessed(this->player_ptr, this->player_ptr->blessed + randint1(12) + 6, false)) {
286 case SV_SCROLL_HOLY_CHANT:
287 if (set_blessed(this->player_ptr, this->player_ptr->blessed + randint1(24) + 12, false)) {
292 case SV_SCROLL_HOLY_PRAYER:
293 if (set_blessed(this->player_ptr, this->player_ptr->blessed + randint1(48) + 24, false)) {
298 case SV_SCROLL_MONSTER_CONFUSION:
299 if (any_bits(this->player_ptr->special_attack, ATTACK_CONFUSE)) {
303 msg_print(_("手が輝き始めた。", "Your hands begin to glow."));
304 this->player_ptr->special_attack |= ATTACK_CONFUSE;
305 RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
308 case SV_SCROLL_PROTECTION_FROM_EVIL: {
309 auto k = 3 * this->player_ptr->lev;
310 if (set_protevil(this->player_ptr, this->player_ptr->protevil + randint1(25) + k, false)) {
316 case SV_SCROLL_RUNE_OF_PROTECTION:
317 create_rune_protection_one(this->player_ptr);
320 case SV_SCROLL_TRAP_DOOR_DESTRUCTION:
321 if (destroy_doors_touch(this->player_ptr)) {
326 case SV_SCROLL_STAR_DESTRUCTION:
327 if (destroy_area(this->player_ptr, this->player_ptr->y, this->player_ptr->x, 13 + randint0(5), false)) {
330 msg_print(_("ダンジョンが揺れた...", "The dungeon trembles..."));
334 case SV_SCROLL_DISPEL_UNDEAD:
335 if (dispel_undead(this->player_ptr, 80)) {
340 case SV_SCROLL_SPELL:
341 if (!PlayerClass(this->player_ptr).has_number_of_spells_learned()) {
345 this->player_ptr->add_spells++;
346 RedrawingFlagsUpdater::get_instance().set_flag(StatusRedrawingFlag::SPELLS);
349 case SV_SCROLL_GENOCIDE:
350 (void)symbol_genocide(this->player_ptr, 300, true);
353 case SV_SCROLL_MASS_GENOCIDE:
354 (void)mass_genocide(this->player_ptr, 300, true);
357 case SV_SCROLL_ACQUIREMENT:
358 acquirement(this->player_ptr, this->player_ptr->y, this->player_ptr->x, 1, true, false, false);
361 case SV_SCROLL_STAR_ACQUIREMENT:
362 acquirement(this->player_ptr, this->player_ptr->y, this->player_ptr->x, randint1(2) + 1, true, false, false);
366 fire_ball(this->player_ptr, AttributeType::FIRE, 0, 666, 4);
367 if (!(is_oppose_fire(this->player_ptr) || has_resist_fire(this->player_ptr) || has_immune_fire(this->player_ptr))) {
368 take_hit(this->player_ptr, DAMAGE_NOESCAPE, 50 + randint1(50), _("炎の巻物", "a Scroll of Fire"));
374 fire_ball(this->player_ptr, AttributeType::ICE, 0, 777, 4);
375 if (!(is_oppose_cold(this->player_ptr) || has_resist_cold(this->player_ptr) || has_immune_cold(this->player_ptr))) {
376 take_hit(this->player_ptr, DAMAGE_NOESCAPE, 100 + randint1(100), _("氷の巻物", "a Scroll of Ice"));
381 case SV_SCROLL_CHAOS:
382 fire_ball(this->player_ptr, AttributeType::CHAOS, 0, 1000, 4);
383 if (!has_resist_chaos(this->player_ptr)) {
384 take_hit(this->player_ptr, DAMAGE_NOESCAPE, 111 + randint1(111), _("ログルスの巻物", "a Scroll of Logrus"));
389 case SV_SCROLL_RUMOR:
390 msg_print(_("巻物にはメッセージが書かれている:", "There is message on the scroll. It says:"));
392 display_rumor(this->player_ptr, true);
394 msg_print(_("巻物は煙を立てて消え去った!", "The scroll disappears in a puff of smoke!"));
397 case SV_SCROLL_ARTIFACT:
399 if (!artifact_scroll(this->player_ptr)) {
404 case SV_SCROLL_RESET_RECALL:
406 if (!reset_recall(this->player_ptr)) {
411 case SV_SCROLL_AMUSEMENT:
413 generate_amusement(this->player_ptr, 1, false);
415 case SV_SCROLL_STAR_AMUSEMENT:
417 generate_amusement(this->player_ptr, randint1(2) + 1, false);