6 #include "object/object-broken.h"
7 #include "effect/attribute-types.h"
8 #include "effect/effect-characteristics.h"
9 #include "effect/effect-processor.h"
10 #include "mind/snipe-types.h"
11 #include "object-enchant/tr-types.h"
12 #include "object/tval-types.h"
13 #include "sv-definition/sv-potion-types.h"
14 #include "system/baseitem-info.h"
15 #include "system/item-entity.h"
16 #include "system/player-type-definition.h"
17 #include "util/bit-flags-calculator.h"
19 ObjectBreaker::ObjectBreaker(tr_type ignore_flg)
20 : ignore_flg(ignore_flg)
24 BreakerAcid::BreakerAcid()
25 : ObjectBreaker(TR_IGNORE_ACID)
29 BreakerElec::BreakerElec()
30 : ObjectBreaker(TR_IGNORE_ELEC)
34 BreakerFire::BreakerFire()
35 : ObjectBreaker(TR_IGNORE_FIRE)
39 BreakerCold::BreakerCold()
40 : ObjectBreaker(TR_IGNORE_COLD)
45 * @brief アイテムが酸で破損するかどうかを判定する
46 * @param o_ptr アイテムの情報参照ポインタ
47 * @return 破損するならばTRUEを返す
48 * Note that amulets, rods, and high-level spell books are immune
49 * to "inventory damage" of any kind. Also sling ammo and shovels.
50 * Does a given class of objects (usually) hate acid?
51 * Note that acid can either melt or corrode something.
53 bool BreakerAcid::hates(ItemEntity *o_ptr) const
55 switch (o_ptr->bi_key.tval()) {
56 case ItemKindType::ARROW:
57 case ItemKindType::BOLT:
58 case ItemKindType::BOW:
59 case ItemKindType::SWORD:
60 case ItemKindType::HAFTED:
61 case ItemKindType::POLEARM:
62 case ItemKindType::HELM:
63 case ItemKindType::CROWN:
64 case ItemKindType::SHIELD:
65 case ItemKindType::BOOTS:
66 case ItemKindType::GLOVES:
67 case ItemKindType::CLOAK:
68 case ItemKindType::SOFT_ARMOR:
69 case ItemKindType::HARD_ARMOR:
70 case ItemKindType::DRAG_ARMOR:
71 case ItemKindType::STAFF:
72 case ItemKindType::SCROLL:
73 case ItemKindType::CHEST:
74 case ItemKindType::SKELETON:
75 case ItemKindType::BOTTLE:
76 case ItemKindType::JUNK:
84 * @brief アイテムが電撃で破損するかどうかを判定する /
85 * Does a given object (usually) hate electricity?
86 * @param o_ptr アイテムの情報参照ポインタ
87 * @return 破損するならばTRUEを返す
89 bool BreakerElec::hates(ItemEntity *o_ptr) const
91 switch (o_ptr->bi_key.tval()) {
92 case ItemKindType::RING:
93 case ItemKindType::WAND:
101 * @brief アイテムが火炎で破損するかどうかを判定する /
102 * Does a given object (usually) hate fire?
103 * @param o_ptr アイテムの情報参照ポインタ
104 * @return 破損するならばTRUEを返す
106 * Hafted/Polearm weapons have wooden shafts.
107 * Arrows/Bows are mostly wooden.
109 bool BreakerFire::hates(ItemEntity *o_ptr) const
111 switch (o_ptr->bi_key.tval()) {
112 case ItemKindType::LITE:
113 case ItemKindType::ARROW:
114 case ItemKindType::BOW:
115 case ItemKindType::HAFTED:
116 case ItemKindType::POLEARM:
117 case ItemKindType::BOOTS:
118 case ItemKindType::GLOVES:
119 case ItemKindType::CLOAK:
120 case ItemKindType::SOFT_ARMOR:
121 case ItemKindType::LIFE_BOOK:
122 case ItemKindType::SORCERY_BOOK:
123 case ItemKindType::NATURE_BOOK:
124 case ItemKindType::CHAOS_BOOK:
125 case ItemKindType::DEATH_BOOK:
126 case ItemKindType::TRUMP_BOOK:
127 case ItemKindType::ARCANE_BOOK:
128 case ItemKindType::CRAFT_BOOK:
129 case ItemKindType::DEMON_BOOK:
130 case ItemKindType::CRUSADE_BOOK:
131 case ItemKindType::MUSIC_BOOK:
132 case ItemKindType::HISSATSU_BOOK:
133 case ItemKindType::HEX_BOOK:
134 case ItemKindType::CHEST:
135 case ItemKindType::STAFF:
136 case ItemKindType::SCROLL:
144 * @brief アイテムが冷気で破損するかどうかを判定する /
145 * Does a given object (usually) hate cold?
146 * @param o_ptr アイテムの情報参照ポインタ
147 * @return 破損するならばTRUEを返す
149 bool BreakerCold::hates(ItemEntity *o_ptr) const
151 switch (o_ptr->bi_key.tval()) {
152 case ItemKindType::POTION:
153 case ItemKindType::FLASK:
154 case ItemKindType::BOTTLE:
162 * @brief アイテムが属性で破損するかどうかを判定する(メインルーチン) /
164 * @param o_ptr アイテムの情報参照ポインタ
165 * @return 破損するならばTRUEを返す
168 bool ObjectBreaker::can_destroy(ItemEntity *o_ptr) const
170 if (!this->hates(o_ptr)) {
174 return o_ptr->get_flags().has_not(this->ignore_flg);
179 * Potions "smash open" and cause an area effect when
180 * @param who 薬破損の主体ID(プレイヤー所持アイテムが壊れた場合0、床上のアイテムの場合モンスターID)
183 * @param bi_id 破損した薬のアイテムID
184 * @return 薬を浴びたモンスターが起こるならばTRUEを返す
187 * (1) they are shattered while in the player's p_ptr->inventory_list,
188 * due to cold (etc) attacks;
189 * (2) they are thrown at a monster, or obstacle;
190 * (3) they are shattered by a "cold ball" or other such spell
191 * while lying on the floor.
194 * who --- who caused the potion to shatter (0=player)
195 * potions that smash on the floor are assumed to
196 * be caused by no-one (who = 1), as are those that
197 * shatter inside the player inventory.
198 * (Not anymore -- I changed this; TY)
199 * y, x --- coordinates of the potion (or player if
200 * the potion was in her inventory);
201 * o_ptr --- pointer to the potion object.
204 bool potion_smash_effect(PlayerType *player_ptr, MONSTER_IDX who, POSITION y, POSITION x, short bi_id)
207 AttributeType dt = AttributeType::NONE;
210 const auto &baseitem = baseitems_info[bi_id];
211 switch (baseitem.bi_key.sval().value()) {
212 case SV_POTION_SALT_WATER:
213 case SV_POTION_SLIME_MOLD:
214 case SV_POTION_LOSE_MEMORIES:
215 case SV_POTION_DEC_STR:
216 case SV_POTION_DEC_INT:
217 case SV_POTION_DEC_WIS:
218 case SV_POTION_DEC_DEX:
219 case SV_POTION_DEC_CON:
220 case SV_POTION_DEC_CHR:
221 case SV_POTION_WATER: /* perhaps a 'water' attack? */
222 case SV_POTION_APPLE_JUICE:
224 case SV_POTION_INFRAVISION:
225 case SV_POTION_DETECT_INVIS:
226 case SV_POTION_SLOW_POISON:
227 case SV_POTION_CURE_POISON:
228 case SV_POTION_BOLDNESS:
229 case SV_POTION_RESIST_HEAT:
230 case SV_POTION_RESIST_COLD:
231 case SV_POTION_HEROISM:
232 case SV_POTION_BESERK_STRENGTH:
233 case SV_POTION_RES_STR:
234 case SV_POTION_RES_INT:
235 case SV_POTION_RES_WIS:
236 case SV_POTION_RES_DEX:
237 case SV_POTION_RES_CON:
238 case SV_POTION_RES_CHR:
239 case SV_POTION_INC_STR:
240 case SV_POTION_INC_INT:
241 case SV_POTION_INC_WIS:
242 case SV_POTION_INC_DEX:
243 case SV_POTION_INC_CON:
244 case SV_POTION_INC_CHR:
245 case SV_POTION_AUGMENTATION:
246 case SV_POTION_ENLIGHTENMENT:
247 case SV_POTION_STAR_ENLIGHTENMENT:
248 case SV_POTION_SELF_KNOWLEDGE:
249 case SV_POTION_EXPERIENCE:
250 case SV_POTION_RESISTANCE:
251 case SV_POTION_INVULNERABILITY:
252 case SV_POTION_NEW_LIFE:
253 /* All of the above potions have no effect when shattered */
255 case SV_POTION_SLOWNESS:
256 dt = AttributeType::OLD_SLOW;
260 case SV_POTION_POISON:
261 dt = AttributeType::POIS;
265 case SV_POTION_BLINDNESS:
266 dt = AttributeType::DARK;
269 case SV_POTION_BOOZE:
270 dt = AttributeType::OLD_CONF;
273 case SV_POTION_SLEEP:
274 dt = AttributeType::OLD_SLEEP;
277 case SV_POTION_RUINATION:
278 case SV_POTION_DETONATIONS:
279 dt = AttributeType::SHARDS;
280 dam = damroll(25, 25);
283 case SV_POTION_DEATH:
284 dt = AttributeType::DEATH_RAY;
285 dam = baseitem.level * 10;
289 case SV_POTION_SPEED:
290 dt = AttributeType::OLD_SPEED;
292 case SV_POTION_CURE_LIGHT:
293 dt = AttributeType::OLD_HEAL;
296 case SV_POTION_CURE_SERIOUS:
297 dt = AttributeType::OLD_HEAL;
300 case SV_POTION_CURE_CRITICAL:
301 case SV_POTION_CURING:
302 dt = AttributeType::OLD_HEAL;
305 case SV_POTION_HEALING:
306 dt = AttributeType::OLD_HEAL;
307 dam = damroll(10, 10);
309 case SV_POTION_RESTORE_EXP:
310 dt = AttributeType::STAR_HEAL;
315 dt = AttributeType::STAR_HEAL;
316 dam = damroll(50, 50);
319 case SV_POTION_STAR_HEALING:
320 dt = AttributeType::OLD_HEAL;
321 dam = damroll(50, 50);
324 case SV_POTION_RESTORE_MANA:
325 dt = AttributeType::MANA;
326 dam = damroll(10, 10);
329 case SV_POTION_POLY_SELF:
330 dt = AttributeType::NEXUS;
331 dam = damroll(20, 20);
338 (void)project(player_ptr, who, radius, y, x, dam, dt, (PROJECT_JUMP | PROJECT_ITEM | PROJECT_KILL));
343 * @brief 矢弾を射撃した場合の破損確率を返す /
344 * Determines the odds of an object breaking when thrown at a monster
345 * @param o_ptr 矢弾のオブジェクト構造体参照ポインタ
348 * Note that artifacts never break, see the "drop_near()" function.
350 PERCENTAGE breakage_chance(PlayerType *player_ptr, ItemEntity *o_ptr, bool has_archer_bonus, SPELL_IDX snipe_type)
352 /* Examine the snipe type */
354 if (snipe_type == SP_KILL_WALL) {
357 if (snipe_type == SP_EXPLODE) {
360 if (snipe_type == SP_PIERCE) {
363 if (snipe_type == SP_FINAL) {
366 if (snipe_type == SP_NEEDLE) {
369 if (snipe_type == SP_EVILNESS) {
372 if (snipe_type == SP_HOLYNESS) {
377 /* Examine the item type */
378 PERCENTAGE archer_bonus = (has_archer_bonus ? (PERCENTAGE)(player_ptr->lev - 1) / 7 + 4 : 0);
379 switch (o_ptr->bi_key.tval()) {
381 case ItemKindType::FLASK:
382 case ItemKindType::POTION:
383 case ItemKindType::BOTTLE:
384 case ItemKindType::FOOD:
385 case ItemKindType::JUNK:
389 case ItemKindType::LITE:
390 case ItemKindType::SCROLL:
391 case ItemKindType::SKELETON:
394 /* Sometimes break */
395 case ItemKindType::WAND:
396 case ItemKindType::SPIKE:
398 case ItemKindType::ARROW:
399 return 20 - archer_bonus * 2;
402 case ItemKindType::SHOT:
403 case ItemKindType::BOLT:
404 return 10 - archer_bonus;