3 * Summary: Misc functions.
4 * Written by: Brent Ross
24 #include "godpassive.h"
29 #include "mon-stuff.h"
41 // XXX: Name strings in most of the following are currently unused!
56 // Note: the Little-Giant range is used to make armours which are very
57 // flexible and adjustable and can be worn by any player character...
58 // providing they also pass the shape test, of course.
59 static int Armour_index
[NUM_ARMOURS
];
60 static armour_def Armour_prop
[NUM_ARMOURS
] =
62 { ARM_ANIMAL_SKIN
, "animal skin", 2, 0, 100,
63 true, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
64 { ARM_ROBE
, "robe", 2, 0, 60,
65 true, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_BIG
},
66 { ARM_LEATHER_ARMOUR
, "leather armour", 3, -1, 150,
67 true, EQ_BODY_ARMOUR
, SIZE_SMALL
, SIZE_MEDIUM
},
69 { ARM_RING_MAIL
, "ring mail", 4, -2, 250,
70 false, EQ_BODY_ARMOUR
, SIZE_SMALL
, SIZE_MEDIUM
},
71 { ARM_SCALE_MAIL
, "scale mail", 5, -3, 350,
72 false, EQ_BODY_ARMOUR
, SIZE_SMALL
, SIZE_MEDIUM
},
73 { ARM_CHAIN_MAIL
, "chain mail", 6, -4, 400,
74 false, EQ_BODY_ARMOUR
, SIZE_SMALL
, SIZE_MEDIUM
},
75 { ARM_BANDED_MAIL
, "banded mail", 7, -5, 500,
76 false, EQ_BODY_ARMOUR
, SIZE_SMALL
, SIZE_MEDIUM
},
77 { ARM_SPLINT_MAIL
, "splint mail", 8, -5, 550,
78 false, EQ_BODY_ARMOUR
, SIZE_SMALL
, SIZE_MEDIUM
},
79 { ARM_PLATE_MAIL
, "plate mail", 10, -6, 650,
80 false, EQ_BODY_ARMOUR
, SIZE_SMALL
, SIZE_MEDIUM
},
81 { ARM_CRYSTAL_PLATE_MAIL
, "crystal plate mail", 14, -8, 1200,
82 false, EQ_BODY_ARMOUR
, SIZE_SMALL
, SIZE_MEDIUM
},
84 { ARM_TROLL_HIDE
, "troll hide", 2, -1, 220,
85 true, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
86 { ARM_TROLL_LEATHER_ARMOUR
, "troll leather armour", 4, -1, 220,
87 true, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
88 { ARM_STEAM_DRAGON_HIDE
, "steam dragon hide", 2, 0, 120,
89 true, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
90 { ARM_STEAM_DRAGON_ARMOUR
, "steam dragon armour", 4, 0, 120,
91 true, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
92 { ARM_MOTTLED_DRAGON_HIDE
, "mottled dragon hide", 3, -1, 150,
93 true, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
94 { ARM_MOTTLED_DRAGON_ARMOUR
,"mottled dragon armour", 5, -1, 150,
95 true, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
97 { ARM_SWAMP_DRAGON_HIDE
, "swamp dragon hide", 3, -2, 200,
98 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
99 { ARM_SWAMP_DRAGON_ARMOUR
, "swamp dragon armour", 7, -2, 200,
100 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
101 { ARM_DRAGON_HIDE
, "dragon hide", 3, -3, 350,
102 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
103 { ARM_DRAGON_ARMOUR
, "dragon armour", 8, -3, 350,
104 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
105 { ARM_ICE_DRAGON_HIDE
, "ice dragon hide", 4, -3, 350,
106 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
107 { ARM_ICE_DRAGON_ARMOUR
, "ice dragon armour", 9, -3, 350,
108 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
109 { ARM_PEARL_DRAGON_HIDE
, "pearl dragon hide", 3, -3, 400,
110 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
111 { ARM_PEARL_DRAGON_ARMOUR
, "pearl dragon armour", 10, -3, 400,
112 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
113 { ARM_STORM_DRAGON_HIDE
, "storm dragon hide", 4, -3, 600,
114 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
115 { ARM_STORM_DRAGON_ARMOUR
, "storm dragon armour", 10, -5, 600,
116 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
117 { ARM_GOLD_DRAGON_HIDE
, "gold dragon hide", 4, -5, 1100,
118 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
119 { ARM_GOLD_DRAGON_ARMOUR
, "gold dragon armour", 11, -9, 1100,
120 false, EQ_BODY_ARMOUR
, SIZE_LITTLE
, SIZE_GIANT
},
122 { ARM_CLOAK
, "cloak", 1, 0, 40,
123 true, EQ_CLOAK
, SIZE_LITTLE
, SIZE_BIG
},
124 { ARM_GLOVES
, "gloves", 1, 0, 20,
125 true, EQ_GLOVES
, SIZE_SMALL
, SIZE_MEDIUM
},
127 { ARM_HELMET
, "helmet", 1, 0, 80,
128 false, EQ_HELMET
, SIZE_SMALL
, SIZE_MEDIUM
},
130 { ARM_CAP
, "cap", 0, 0, 40,
131 true, EQ_HELMET
, SIZE_LITTLE
, SIZE_LARGE
},
133 { ARM_WIZARD_HAT
, "wizard hat", 0, 0, 40,
134 true, EQ_HELMET
, SIZE_LITTLE
, SIZE_LARGE
},
136 // Note that barding size is compared against torso so it currently
137 // needs to fit medium, but that doesn't matter as much as race
138 // and shapeshift status.
139 { ARM_BOOTS
, "boots", 1, 0, 30,
140 true, EQ_BOOTS
, SIZE_SMALL
, SIZE_MEDIUM
},
141 // Changed max. barding size to large to allow for the appropriate
142 // monster types (monsters don't differentiate between torso and general).
143 { ARM_CENTAUR_BARDING
, "centaur barding", 4, -2, 100,
144 true, EQ_BOOTS
, SIZE_MEDIUM
, SIZE_LARGE
},
145 { ARM_NAGA_BARDING
, "naga barding", 4, -2, 100,
146 true, EQ_BOOTS
, SIZE_MEDIUM
, SIZE_LARGE
},
148 // Note: shields use ac-value as sh-value, EV pen is used as the basis
149 // to calculate adjusted shield penalty.
150 { ARM_BUCKLER
, "buckler", 5, -1, 90,
151 true, EQ_SHIELD
, SIZE_LITTLE
, SIZE_MEDIUM
},
152 { ARM_SHIELD
, "shield", 8, -3, 150,
153 false, EQ_SHIELD
, SIZE_SMALL
, SIZE_BIG
},
154 { ARM_LARGE_SHIELD
, "large shield", 13, -5, 230,
155 false, EQ_SHIELD
, SIZE_MEDIUM
, SIZE_GIANT
},
169 hands_reqd_type hands
;
170 size_type fit_size
; // actual size is one size smaller
171 missile_type ammo
; // MI_NONE for non-launchers
178 static int Weapon_index
[NUM_WEAPONS
];
179 static weapon_def Weapon_prop
[NUM_WEAPONS
] =
182 { WPN_CLUB
, "club", 5, 3, 13, 50, 7,
183 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, true,
185 { WPN_WHIP
, "whip", 6, 2, 11, 30, 2,
186 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
188 { WPN_HAMMER
, "hammer", 7, 3, 13, 90, 7,
189 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, false,
191 { WPN_MACE
, "mace", 8, 3, 14, 120, 8,
192 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, false,
194 { WPN_FLAIL
, "flail", 9, 2, 15, 130, 8,
195 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, false,
197 { WPN_ANKUS
, "ankus", 9, 2, 14, 120, 8,
198 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
199 DAMV_PIERCING
| DAM_BLUDGEON
, 10 },
200 { WPN_MORNINGSTAR
, "morningstar", 10, -1, 15, 140, 8,
201 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
202 DAMV_PIERCING
| DAM_BLUDGEON
, 10 },
203 { WPN_DEMON_WHIP
, "demon whip", 12, 1, 11, 30, 2,
204 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
206 { WPN_SACRED_SCOURGE
, "sacred scourge", 13, 0, 11, 30, 2,
207 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
209 { WPN_SPIKED_FLAIL
, "spiked flail", 12, -2, 16, 190, 8,
210 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
211 DAMV_PIERCING
| DAM_BLUDGEON
, 10 },
212 { WPN_DIRE_FLAIL
, "dire flail", 13, -3, 14, 240, 9,
213 SK_MACES_FLAILS
, HANDS_DOUBLE
, SIZE_LARGE
, MI_NONE
, false,
214 DAMV_PIERCING
| DAM_BLUDGEON
, 10 },
215 { WPN_EVENINGSTAR
, "eveningstar", 14, -1, 15, 180, 8,
216 SK_MACES_FLAILS
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
217 DAMV_PIERCING
| DAM_BLUDGEON
, 2 },
218 { WPN_GREAT_MACE
, "great mace", 17, -4, 17, 270, 9,
219 SK_MACES_FLAILS
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
221 { WPN_GIANT_CLUB
, "giant club", 20, -6, 17, 330, 10,
222 SK_MACES_FLAILS
, HANDS_TWO
, SIZE_BIG
, MI_NONE
, false,
224 { WPN_GIANT_SPIKED_CLUB
, "giant spiked club", 22, -7, 18, 350, 10,
225 SK_MACES_FLAILS
, HANDS_TWO
, SIZE_BIG
, MI_NONE
, false,
226 DAMV_PIERCING
| DAM_BLUDGEON
, 10 },
229 { WPN_KNIFE
, "knife", 3, 5, 10, 10, 1,
230 SK_SHORT_BLADES
, HANDS_ONE
, SIZE_LITTLE
, MI_NONE
, false,
231 DAMV_STABBING
| DAM_SLICE
, 0 },
232 { WPN_DAGGER
, "dagger", 4, 6, 10, 20, 1,
233 SK_SHORT_BLADES
, HANDS_ONE
, SIZE_LITTLE
, MI_NONE
, true,
234 DAMV_STABBING
| DAM_SLICE
, 10 },
235 { WPN_QUICK_BLADE
, "quick blade", 5, 6, 7, 50, 0,
236 SK_SHORT_BLADES
, HANDS_ONE
, SIZE_LITTLE
, MI_NONE
, false,
237 DAMV_STABBING
| DAM_SLICE
, 2 },
238 { WPN_SHORT_SWORD
, "short sword", 6, 4, 11, 80, 2,
239 SK_SHORT_BLADES
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, false,
240 DAMV_SLICING
| DAM_PIERCE
, 10 },
241 { WPN_SABRE
, "sabre", 7, 4, 12, 90, 2,
242 SK_SHORT_BLADES
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, false,
243 DAMV_SLICING
| DAM_PIERCE
, 10 },
246 { WPN_FALCHION
, "falchion", 8, 2, 13, 170, 4,
247 SK_LONG_BLADES
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, false,
248 DAMV_SLICING
, 10 }, // or perhaps DAMV_CHOPPING is more apt?
249 { WPN_BLESSED_FALCHION
, "blessed falchion", 10, 2, 11, 170, 4,
250 SK_LONG_BLADES
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, false,
251 DAMV_SLICING
, 10 }, // or perhaps DAMV_CHOPPING is more apt?
252 { WPN_LONG_SWORD
, "long sword", 10, 1, 14, 160, 3,
253 SK_LONG_BLADES
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
255 { WPN_BLESSED_LONG_SWORD
, "blessed long sword", 12, 0, 12, 160, 3,
256 SK_LONG_BLADES
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
258 { WPN_SCIMITAR
, "scimitar", 11, -1, 14, 170, 3,
259 SK_LONG_BLADES
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
261 { WPN_BLESSED_SCIMITAR
, "blessed scimitar", 13, -1, 13, 170, 3,
262 SK_LONG_BLADES
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
264 { WPN_KATANA
, "katana", 14, 3, 12, 160, 3,
265 SK_LONG_BLADES
, HANDS_HALF
, SIZE_MEDIUM
, MI_NONE
, false,
267 { WPN_BLESSED_KATANA
, "blessed katana", 15, 2, 12, 160, 3,
268 SK_LONG_BLADES
, HANDS_HALF
, SIZE_MEDIUM
, MI_NONE
, false,
270 { WPN_DEMON_BLADE
, "demon blade", 13, -1, 15, 200, 4,
271 SK_LONG_BLADES
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
273 { WPN_EUDEMON_BLADE
, "eudemon blade", 14, -2, 14, 200, 4,
274 SK_LONG_BLADES
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
276 { WPN_DOUBLE_SWORD
, "double sword", 16, -1, 15, 220, 5,
277 SK_LONG_BLADES
, HANDS_HALF
, SIZE_MEDIUM
, MI_NONE
, false,
279 { WPN_BLESSED_DOUBLE_SWORD
, "blessed double sword", 16, -1, 14, 220, 5,
280 SK_LONG_BLADES
, HANDS_HALF
, SIZE_MEDIUM
, MI_NONE
, false,
282 { WPN_GREAT_SWORD
, "great sword", 16, -3, 17, 250, 6,
283 SK_LONG_BLADES
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
285 { WPN_BLESSED_GREAT_SWORD
, "blessed great sword", 17, -3, 17, 250, 6,
286 SK_LONG_BLADES
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
288 { WPN_TRIPLE_SWORD
, "triple sword", 19, -4, 19, 260, 6,
289 SK_LONG_BLADES
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
291 { WPN_BLESSED_TRIPLE_SWORD
, "blessed triple sword", 19, -4, 18, 260, 6,
292 SK_LONG_BLADES
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
296 { WPN_HAND_AXE
, "hand axe", 7, 3, 13, 80, 6,
297 SK_AXES
, HANDS_ONE
, SIZE_SMALL
, MI_NONE
, true,
299 { WPN_WAR_AXE
, "war axe", 11, 0, 16, 180, 7,
300 SK_AXES
, HANDS_ONE
, SIZE_MEDIUM
, MI_NONE
, false,
302 { WPN_BROAD_AXE
, "broad axe", 14, -2, 16, 230, 8,
303 SK_AXES
, HANDS_HALF
, SIZE_MEDIUM
, MI_NONE
, false,
305 { WPN_BATTLEAXE
, "battleaxe", 17, -4, 18, 250, 8,
306 SK_AXES
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
308 { WPN_EXECUTIONERS_AXE
, "executioner\'s axe", 20, -6, 20, 280, 9,
309 SK_AXES
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
313 { WPN_SPEAR
, "spear", 7, 4, 11, 50, 3,
314 SK_POLEARMS
, HANDS_HALF
, SIZE_SMALL
, MI_NONE
, true,
316 { WPN_TRIDENT
, "trident", 10, 3, 13, 160, 4,
317 SK_POLEARMS
, HANDS_HALF
, SIZE_MEDIUM
, MI_NONE
, false,
319 { WPN_HALBERD
, "halberd", 13, -3, 16, 200, 5,
320 SK_POLEARMS
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
321 DAMV_CHOPPING
| DAM_PIERCE
, 10 },
322 { WPN_SCYTHE
, "scythe", 14, -4, 20, 220, 7,
323 SK_POLEARMS
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
325 { WPN_DEMON_TRIDENT
, "demon trident", 14, 1, 13, 160, 4,
326 SK_POLEARMS
, HANDS_HALF
, SIZE_MEDIUM
, MI_NONE
, false,
328 { WPN_TRISHULA
, "trishula", 15, 0, 13, 160, 4,
329 SK_POLEARMS
, HANDS_HALF
, SIZE_MEDIUM
, MI_NONE
, false,
331 { WPN_GLAIVE
, "glaive", 15, -3, 18, 200, 6,
332 SK_POLEARMS
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
334 { WPN_BARDICHE
, "bardiche", 18, -6, 20, 200, 8,
335 SK_POLEARMS
, HANDS_TWO
, SIZE_LARGE
, MI_NONE
, false,
339 { WPN_QUARTERSTAFF
, "quarterstaff", 7, 6, 12, 180, 7,
340 SK_STAVES
, HANDS_DOUBLE
, SIZE_LARGE
, MI_NONE
, false,
342 { WPN_LAJATANG
, "lajatang", 14, -3, 14, 200, 3,
343 SK_STAVES
, HANDS_DOUBLE
, SIZE_LARGE
, MI_NONE
, false,
348 // - HANDS_HALF means a reloading time penalty if using shield
349 // - damage field is used for bonus strength damage (string tension)
350 // - slings get a bonus from dex, not str (as tension is meaningless)
351 // - str weight is used for speed and applying dex to skill
352 { WPN_BLOWGUN
, "blowgun", 0, 2, 10, 20, 0,
353 SK_THROWING
, HANDS_HALF
, SIZE_LITTLE
, MI_NEEDLE
, false,
355 { WPN_SLING
, "sling", 0, 2, 11, 20, 1,
356 SK_SLINGS
, HANDS_ONE
, SIZE_LITTLE
, MI_STONE
, false,
357 DAMV_NON_MELEE
, 10 },
358 { WPN_CROSSBOW
, "crossbow", 5, 4, 15, 150, 8,
359 SK_CROSSBOWS
, HANDS_TWO
, SIZE_MEDIUM
, MI_BOLT
, false,
360 DAMV_NON_MELEE
, 10 },
361 { WPN_BOW
, "bow", 3, 1, 11, 90, 2,
362 SK_BOWS
, HANDS_TWO
, SIZE_MEDIUM
, MI_ARROW
, false,
363 DAMV_NON_MELEE
, 10 },
364 { WPN_LONGBOW
, "longbow", 6, 0, 12, 120, 3,
365 SK_BOWS
, HANDS_TWO
, SIZE_LARGE
, MI_ARROW
, false,
366 DAMV_NON_MELEE
, 10 },
378 static int Missile_index
[NUM_MISSILES
];
379 static missile_def Missile_prop
[NUM_MISSILES
] =
381 { MI_NEEDLE
, "needle", 0, 1, false },
382 { MI_STONE
, "stone", 4, 6, true },
383 { MI_DART
, "dart", 2, 3, true },
384 { MI_ARROW
, "arrow", 7, 5, false },
385 { MI_BOLT
, "bolt", 9, 5, false },
386 { MI_LARGE_ROCK
, "large rock", 20, 600, true },
387 { MI_SLING_BULLET
, "sling bullet", 6, 4, false },
388 { MI_JAVELIN
, "javelin", 10, 80, true },
389 { MI_THROWING_NET
, "throwing net", 0, 30, true },
410 // NOTE: Any food with special random messages or side effects
411 // currently only takes one turn to eat (except ghouls and chunks)...
412 // If this changes then those items will have to have special code
413 // (like ghoul chunks) to guarantee that the special thing is only
414 // done once. See the ghoul eating code over in food.cc.
415 static int Food_index
[NUM_FOODS
];
416 static food_def Food_prop
[NUM_FOODS
] =
418 { FOOD_MEAT_RATION
, "meat ration", 5000, 500, -1500, 80, 4, FFL_NONE
},
419 { FOOD_SAUSAGE
, "sausage", 1500, 150, -400, 40, 1, FFL_NONE
},
420 { FOOD_CHUNK
, "chunk", 1000, 100, -500, 100, 3, FFL_NONE
},
421 { FOOD_BEEF_JERKY
, "beef jerky", 800, 100, -250, 20, 1, FFL_NONE
},
423 { FOOD_BREAD_RATION
, "bread ration", 4400, -1500, 750, 80, 4, FFL_NONE
},
425 { FOOD_SNOZZCUMBER
, "snozzcumber", 1500, -500, 500, 50, 1, FFL_FRUIT
},
426 { FOOD_ORANGE
, "orange", 1000, -350, 400, 20, 1, FFL_FRUIT
},
427 { FOOD_BANANA
, "banana", 1000, -350, 400, 20, 1, FFL_FRUIT
},
428 { FOOD_LEMON
, "lemon", 1000, -350, 400, 20, 1, FFL_FRUIT
},
429 { FOOD_PEAR
, "pear", 700, -250, 300, 20, 1, FFL_FRUIT
},
430 { FOOD_APPLE
, "apple", 700, -250, 300, 20, 1, FFL_FRUIT
},
431 { FOOD_APRICOT
, "apricot", 700, -250, 300, 15, 1, FFL_FRUIT
},
432 { FOOD_CHOKO
, "choko", 600, -200, 250, 30, 1, FFL_FRUIT
},
433 { FOOD_RAMBUTAN
, "rambutan", 600, -200, 250, 10, 1, FFL_FRUIT
},
434 { FOOD_LYCHEE
, "lychee", 600, -200, 250, 10, 1, FFL_FRUIT
},
435 { FOOD_STRAWBERRY
, "strawberry", 200, -80, 100, 5, 1, FFL_FRUIT
},
436 { FOOD_GRAPE
, "grape", 100, -40, 50, 2, 1, FFL_FRUIT
},
437 { FOOD_SULTANA
, "sultana", 70, -30, 30, 1, 1, FFL_FRUIT
},
439 { FOOD_ROYAL_JELLY
, "royal jelly", 4000, 0, 0, 55, 1, FFL_NONE
},
440 { FOOD_HONEYCOMB
, "honeycomb", 2000, 0, 0, 40, 1, FFL_NONE
},
441 { FOOD_PIZZA
, "pizza", 1500, -100, 0, 40, 1, FFL_NONE
},
442 { FOOD_CHEESE
, "cheese", 1200, 100, 0, 40, 1, FFL_NONE
},
443 { FOOD_AMBROSIA
, "ambrosia", 2500, 0, 0, 40, 1, FFL_NONE
},
446 // Must call this functions early on so that the above tables can
447 // be accessed correctly.
448 void init_properties()
450 // Compare with enum comments, to catch changes.
451 COMPILE_CHECK(NUM_ARMOURS
== 39, c1
);
452 COMPILE_CHECK(NUM_WEAPONS
== 56, c2
);
453 COMPILE_CHECK(NUM_MISSILES
== 9, c3
);
454 COMPILE_CHECK(NUM_FOODS
== 23, c4
);
458 for (i
= 0; i
< NUM_ARMOURS
; i
++)
459 Armour_index
[ Armour_prop
[i
].id
] = i
;
461 for (i
= 0; i
< NUM_WEAPONS
; i
++)
462 Weapon_index
[ Weapon_prop
[i
].id
] = i
;
464 for (i
= 0; i
< NUM_MISSILES
; i
++)
465 Missile_index
[ Missile_prop
[i
].id
] = i
;
467 for (i
= 0; i
< NUM_FOODS
; i
++)
468 Food_index
[ Food_prop
[i
].id
] = i
;
472 // Some convenient functions to hide the bit operations and create
473 // an interface layer between the code and the data in case this
474 // gets changed again. - bwr
477 // Item cursed status functions:
479 bool item_known_cursed(const item_def
&item
)
481 return ((item
.flags
& ISFLAG_KNOW_CURSE
) && (item
.flags
& ISFLAG_CURSED
));
484 bool item_known_uncursed(const item_def
&item
)
486 return ((item
.flags
& ISFLAG_KNOW_CURSE
) && !(item
.flags
& ISFLAG_CURSED
));
489 void do_curse_item(item_def
&item
, bool quiet
)
492 if (item
.flags
& ISFLAG_CURSED
)
495 // Holy wrath weapons cannot be cursed.
496 if (item
.base_type
== OBJ_WEAPONS
497 && get_weapon_brand(item
) == SPWPN_HOLY_WRATH
)
501 mprf("Your %s glows black briefly, but repels the curse.",
502 item
.name(DESC_PLAIN
).c_str());
507 // Neither can pearl dragon hides
508 if (item
.base_type
== OBJ_ARMOUR
509 && (item
.sub_type
== ARM_PEARL_DRAGON_HIDE
|| item
.sub_type
== ARM_PEARL_DRAGON_ARMOUR
))
513 mprf("Your %s glows black briefly, but repels the curse.",
514 item
.name(DESC_PLAIN
).c_str());
521 mprf("Your %s glows black for a moment.",
522 item
.name(DESC_PLAIN
).c_str());
524 // If we get the message, we know the item is cursed now.
525 item
.flags
|= ISFLAG_KNOW_CURSE
;
526 item
.flags
|= ISFLAG_SEEN_CURSED
;
529 item
.flags
|= ISFLAG_CURSED
;
531 // Xom is amused by the player's items being cursed, especially if
532 // they're worn/equipped.
533 if (in_inventory(item
))
537 if (item_is_equipped(item
))
541 // Cursed cloaks prevent you from removing body armour,
542 // gloves from switching rings.
543 if (item
.base_type
== OBJ_ARMOUR
544 && (get_armour_slot(item
) == EQ_CLOAK
545 || get_armour_slot(item
) == EQ_GLOVES
))
549 else if (you
.equip
[EQ_WEAPON
] == item
.link
)
551 // Redraw the weapon.
552 you
.wield_change
= true;
557 xom_is_stimulated(amusement
);
561 void do_uncurse_item(item_def
&item
, bool inscribe
, bool no_ash
)
565 item
.flags
&= ~ISFLAG_SEEN_CURSED
;
566 if (in_inventory(item
))
567 item
.flags
|= ISFLAG_KNOW_CURSE
;
571 if (no_ash
&& you
.religion
== GOD_ASHENZARI
)
573 simple_god_message(" preserves the curse.");
577 if (inscribe
&& Options
.autoinscribe_cursed
578 && item
.inscription
.find("was cursed") == std::string::npos
579 && !item_ident(item
, ISFLAG_SEEN_CURSED
)
580 && !item_ident(item
, ISFLAG_IDENT_MASK
))
582 add_inscription(item
, "was cursed");
585 if (in_inventory(item
))
587 if (you
.equip
[EQ_WEAPON
] == item
.link
)
589 // Redraw the weapon.
590 you
.wield_change
= true;
592 item
.flags
|= ISFLAG_KNOW_CURSE
;
594 item
.flags
&= (~ISFLAG_CURSED
);
595 item
.flags
&= (~ISFLAG_SEEN_CURSED
);
600 // Is item stationary (cannot be picked up)?
601 void set_item_stationary(item_def
&item
)
603 if (item
.base_type
== OBJ_MISSILES
&& item
.sub_type
== MI_THROWING_NET
)
607 void remove_item_stationary(item_def
&item
)
609 if (item
.base_type
== OBJ_MISSILES
&& item
.sub_type
== MI_THROWING_NET
)
613 bool item_is_stationary(const item_def
&item
)
615 return (item
.base_type
== OBJ_MISSILES
616 && item
.sub_type
== MI_THROWING_NET
620 bool _is_affordable(const item_def
&item
)
622 // Temp items never count.
623 if (item
.flags
& ISFLAG_SUMMONED
)
626 // Already in our grubby mitts.
627 if (in_inventory(item
))
630 // Disregard shop stuff above your reach.
632 return (int)item_value(item
) < you
.gold
;
634 // An ugly special case for items on display.
635 if (in_bounds(item
.pos
))
637 for (adjacent_iterator
ai(item
.pos
); ai
; ++ai
)
638 if (you
.can_pass_through(*ai
))
640 dprf("Seen item %s seems to be un(easily)obtainable.",
641 item
.name(DESC_PLAIN
).c_str());
645 // A monster has it. Violence is the answer.
650 // Item identification status:
652 bool item_ident(const item_def
&item
, iflags_t flags
)
654 return ((item
.flags
& flags
) == flags
);
657 void set_ident_flags(item_def
&item
, iflags_t flags
)
659 preserve_quiver_slots p
;
660 if ((item
.flags
& flags
) != flags
)
663 request_autoinscribe();
665 if (in_inventory(item
))
666 shopping_list
.cull_identical_items(item
);
669 if (fully_identified(item
))
671 // Clear "was cursed" inscription once the item is identified.
672 if (Options
.autoinscribe_cursed
673 && item
.inscription
.find("was cursed") != std::string::npos
)
675 item
.inscription
= replace_all(item
.inscription
, ", was cursed", "");
676 item
.inscription
= replace_all(item
.inscription
, "was cursed, ", "");
677 item
.inscription
= replace_all(item
.inscription
, "was cursed", "");
678 trim_string(item
.inscription
);
681 if (notes_are_active() && !(item
.flags
& ISFLAG_NOTED_ID
)
682 && get_ident_type(item
) != ID_KNOWN_TYPE
683 && is_interesting_item(item
))
685 // Make a note of it.
686 take_note(Note(NOTE_ID_ITEM
, 0, 0, item
.name(DESC_NOCAP_A
).c_str(),
687 origin_desc(item
).c_str()));
689 // Sometimes (e.g. shops) you can ID an item before you get it;
690 // don't note twice in those cases.
691 item
.flags
|= (ISFLAG_NOTED_ID
| ISFLAG_NOTED_GET
);
695 if (item
.flags
& ISFLAG_KNOW_TYPE
&& !is_artefact(item
)
696 && _is_affordable(item
))
698 if (item
.base_type
== OBJ_WEAPONS
)
699 you
.seen_weapon
[item
.sub_type
] |= 1 << item
.special
;
700 if (item
.base_type
== OBJ_ARMOUR
)
701 you
.seen_armour
[item
.sub_type
] |= 1 << item
.special
;
705 void unset_ident_flags(item_def
&item
, iflags_t flags
)
707 preserve_quiver_slots p
;
708 item
.flags
&= (~flags
);
711 // Returns the mask of interesting identify bits for this item
712 // (e.g., scrolls don't have know-cursedness).
713 iflags_t
full_ident_mask(const item_def
& item
)
715 iflags_t flagset
= ISFLAG_IDENT_MASK
;
716 switch (item
.base_type
)
723 if (item
.sub_type
== MISC_RUNE_OF_ZOT
)
726 flagset
= ISFLAG_KNOW_TYPE
;
732 flagset
= ISFLAG_KNOW_TYPE
;
735 if (item_is_rod(item
))
736 flagset
= ISFLAG_KNOW_TYPE
| ISFLAG_KNOW_PLUSES
;
738 flagset
= ISFLAG_KNOW_TYPE
;
741 flagset
= (ISFLAG_KNOW_TYPE
| ISFLAG_KNOW_PLUSES
);
744 flagset
= (ISFLAG_KNOW_CURSE
| ISFLAG_KNOW_TYPE
);
745 if (ring_has_pluses(item
))
746 flagset
|= ISFLAG_KNOW_PLUSES
;
749 flagset
= ISFLAG_KNOW_PLUSES
| ISFLAG_KNOW_TYPE
;
750 if (get_ammo_brand(item
) == SPMSL_NORMAL
)
751 flagset
&= ~ISFLAG_KNOW_TYPE
;
755 // All flags necessary for full identification.
760 if (item_type_known(item
.base_type
, item
.sub_type
) && !is_artefact(item
))
761 flagset
&= (~ISFLAG_KNOW_TYPE
);
763 if (is_artefact(item
))
764 flagset
|= ISFLAG_KNOW_PROPERTIES
;
769 bool fully_identified(const item_def
& item
)
771 return item_ident(item
, full_ident_mask(item
));
775 // Equipment race and description:
777 iflags_t
get_equip_race(const item_def
&item
)
779 return (item
.flags
& ISFLAG_RACIAL_MASK
);
782 iflags_t
get_equip_desc(const item_def
&item
)
784 return (item
.flags
& ISFLAG_COSMETIC_MASK
);
787 void set_equip_race(item_def
&item
, iflags_t flags
)
789 ASSERT((flags
& ~ISFLAG_RACIAL_MASK
) == 0);
791 // first check for base-sub pairs that can't ever have racial types
792 switch (item
.base_type
)
795 if (item
.sub_type
> WPN_MAX_RACIAL
)
800 if (item
.sub_type
> ARM_MAX_RACIAL
)
805 if (item
.sub_type
> MI_MAX_RACIAL
)
813 // check that item is appropriate for racial type
817 switch (item
.base_type
)
820 if ((weapon_skill(item
) == SK_MACES_FLAILS
821 && item
.sub_type
!= WPN_WHIP
)
822 || (weapon_skill(item
) == SK_LONG_BLADES
823 && item
.sub_type
!= WPN_FALCHION
824 && item
.sub_type
!= WPN_LONG_SWORD
825 && item
.sub_type
!= WPN_SCIMITAR
)
826 || weapon_skill(item
) == SK_AXES
827 || (weapon_skill(item
) == SK_POLEARMS
828 && item
.sub_type
!= WPN_SPEAR
829 && item
.sub_type
!= WPN_TRIDENT
)
830 || item
.sub_type
== WPN_CROSSBOW
)
836 if (item
.sub_type
== ARM_SPLINT_MAIL
837 || item
.sub_type
== ARM_BANDED_MAIL
838 || item
.sub_type
== ARM_PLATE_MAIL
839 || is_hard_helmet(item
))
845 if (item
.sub_type
== MI_BOLT
)
854 switch (item
.base_type
)
857 if (item
.sub_type
== WPN_WHIP
858 || item
.sub_type
== WPN_CLUB
859 || item
.sub_type
== WPN_QUICK_BLADE
860 || (weapon_skill(item
) == SK_LONG_BLADES
861 && item
.sub_type
!= WPN_FALCHION
862 && item
.sub_type
!= WPN_LONG_SWORD
)
863 || weapon_skill(item
) == SK_POLEARMS
864 || item
.sub_type
== WPN_BLOWGUN
865 || item
.sub_type
== WPN_BOW
866 || item
.sub_type
== WPN_LONGBOW
)
872 if (item
.sub_type
== ARM_ROBE
873 || item
.sub_type
== ARM_LEATHER_ARMOUR
874 || get_armour_slot(item
) == EQ_HELMET
&& !is_hard_helmet(item
))
880 if (item
.sub_type
== MI_NEEDLE
881 || item
.sub_type
== MI_ARROW
882 || item
.sub_type
== MI_JAVELIN
)
893 switch (item
.base_type
)
896 if (item
.sub_type
== WPN_QUICK_BLADE
897 || item
.sub_type
== WPN_LONGBOW
)
903 if (get_armour_slot(item
) == EQ_HELMET
&& !is_hard_helmet(item
)
904 && item
.sub_type
!= ARM_WIZARD_HAT
)
917 item
.flags
&= ~ISFLAG_RACIAL_MASK
; // delete previous
921 void set_equip_desc(item_def
&item
, iflags_t flags
)
923 ASSERT((flags
& ~ISFLAG_COSMETIC_MASK
) == 0);
925 item
.flags
&= ~ISFLAG_COSMETIC_MASK
; // delete previous
930 // These functions handle the description and subtypes for helmets/caps.
932 short get_helmet_desc(const item_def
&item
)
934 ASSERT(is_helmet(item
));
939 void set_helmet_desc(item_def
&item
, helmet_desc_type type
)
941 ASSERT(is_helmet(item
));
943 if (!is_hard_helmet(item
) && type
> THELM_DESC_MAX_SOFT
)
944 type
= THELM_DESC_PLAIN
;
949 bool is_helmet(const item_def
& item
)
951 return (item
.base_type
== OBJ_ARMOUR
&& get_armour_slot(item
) == EQ_HELMET
);
954 bool is_hard_helmet(const item_def
&item
)
956 return (item
.base_type
== OBJ_ARMOUR
&& item
.sub_type
== ARM_HELMET
);
959 void set_helmet_random_desc(item_def
&item
)
961 ASSERT(is_helmet(item
));
963 if (is_hard_helmet(item
))
964 item
.plus2
= random2(THELM_NUM_DESCS
);
966 item
.plus2
= random2(THELM_DESC_MAX_SOFT
+ 1);
969 short get_gloves_desc(const item_def
&item
)
971 ASSERT(item
.base_type
== OBJ_ARMOUR
&& item
.sub_type
== ARM_GLOVES
);
976 void set_gloves_random_desc(item_def
&item
)
978 ASSERT(item
.base_type
== OBJ_ARMOUR
&& item
.sub_type
== ARM_GLOVES
);
980 item
.plus2
= coinflip() ? TGLOV_DESC_GLOVES
: TGLOV_DESC_GAUNTLETS
;
981 if (get_armour_ego_type(item
) == SPARM_ARCHERY
)
982 item
.plus2
= TGLOV_DESC_BRACERS
;
986 // Ego item functions:
988 bool set_item_ego_type(item_def
&item
, int item_type
, int ego_type
)
990 if (item
.base_type
== item_type
&& !is_artefact(item
))
992 item
.special
= ego_type
;
999 int get_weapon_brand(const item_def
&item
)
1001 // Weapon ego types are "brands", so we do the randart lookup here.
1003 // Staves "brands" handled specially
1004 if (item
.base_type
!= OBJ_WEAPONS
)
1005 return (SPWPN_NORMAL
);
1007 if (is_artefact(item
))
1008 return (artefact_wpn_property(item
, ARTP_BRAND
));
1010 return (item
.special
);
1013 bool missile_brand_obvious(special_missile_type brand
)
1015 // Missiles that are poisoned or made of obvious materials (steel,
1016 // silver) are always identified.
1017 // Same for needle brands.
1018 return (brand
== SPMSL_POISONED
1019 || brand
== SPMSL_CURARE
1020 || (brand
>= SPMSL_PARALYSIS
&& brand
<= SPMSL_RAGE
)
1021 || brand
== SPMSL_STEEL
1022 || brand
== SPMSL_SILVER
);
1025 special_missile_type
get_ammo_brand(const item_def
&item
)
1027 // No artefact arrows yet. -- bwr
1028 if (item
.base_type
!= OBJ_MISSILES
|| is_artefact(item
))
1029 return (SPMSL_NORMAL
);
1031 return (static_cast<special_missile_type
>(item
.special
));
1034 special_armour_type
get_armour_ego_type(const item_def
&item
)
1036 // Armour ego types are "brands", so we do the randart lookup here.
1037 if (item
.base_type
!= OBJ_ARMOUR
)
1038 return (SPARM_NORMAL
);
1040 if (is_artefact(item
))
1042 return (static_cast<special_armour_type
>(
1043 artefact_wpn_property(item
, ARTP_BRAND
)));
1046 return (static_cast<special_armour_type
>(item
.special
));
1049 // Armour information and checking functions.
1050 bool hide2armour(item_def
&item
)
1052 if (item
.base_type
!= OBJ_ARMOUR
)
1055 switch (item
.sub_type
)
1060 case ARM_DRAGON_HIDE
:
1061 item
.sub_type
= ARM_DRAGON_ARMOUR
;
1064 case ARM_TROLL_HIDE
:
1065 item
.sub_type
= ARM_TROLL_LEATHER_ARMOUR
;
1068 case ARM_ICE_DRAGON_HIDE
:
1069 item
.sub_type
= ARM_ICE_DRAGON_ARMOUR
;
1072 case ARM_MOTTLED_DRAGON_HIDE
:
1073 item
.sub_type
= ARM_MOTTLED_DRAGON_ARMOUR
;
1076 case ARM_STORM_DRAGON_HIDE
:
1077 item
.sub_type
= ARM_STORM_DRAGON_ARMOUR
;
1080 case ARM_GOLD_DRAGON_HIDE
:
1081 item
.sub_type
= ARM_GOLD_DRAGON_ARMOUR
;
1084 case ARM_SWAMP_DRAGON_HIDE
:
1085 item
.sub_type
= ARM_SWAMP_DRAGON_ARMOUR
;
1088 case ARM_STEAM_DRAGON_HIDE
:
1089 item
.sub_type
= ARM_STEAM_DRAGON_ARMOUR
;
1092 case ARM_PEARL_DRAGON_HIDE
:
1093 item
.sub_type
= ARM_PEARL_DRAGON_ARMOUR
;
1100 // Return the enchantment limit of a piece of armour.
1101 int armour_max_enchant(const item_def
&item
)
1103 ASSERT(item
.base_type
== OBJ_ARMOUR
);
1105 const int eq_slot
= get_armour_slot(item
);
1107 int max_plus
= MAX_SEC_ENCHANT
;
1108 if (eq_slot
== EQ_BODY_ARMOUR
)
1109 max_plus
= property(item
, PARM_AC
);
1110 else if (item
.sub_type
== ARM_CENTAUR_BARDING
1111 || item
.sub_type
== ARM_NAGA_BARDING
)
1113 max_plus
= MAX_ARM_ENCHANT
;
1115 else if (eq_slot
== EQ_SHIELD
)
1121 // Doesn't include animal skin (only skins we can make and enchant).
1122 bool armour_is_hide(const item_def
&item
, bool inc_made
)
1124 ASSERT(item
.base_type
== OBJ_ARMOUR
);
1126 switch (item
.sub_type
)
1128 case ARM_TROLL_LEATHER_ARMOUR
:
1129 case ARM_DRAGON_ARMOUR
:
1130 case ARM_ICE_DRAGON_ARMOUR
:
1131 case ARM_STEAM_DRAGON_ARMOUR
:
1132 case ARM_MOTTLED_DRAGON_ARMOUR
:
1133 case ARM_STORM_DRAGON_ARMOUR
:
1134 case ARM_GOLD_DRAGON_ARMOUR
:
1135 case ARM_SWAMP_DRAGON_ARMOUR
:
1136 case ARM_PEARL_DRAGON_ARMOUR
:
1139 case ARM_TROLL_HIDE
:
1140 case ARM_DRAGON_HIDE
:
1141 case ARM_ICE_DRAGON_HIDE
:
1142 case ARM_STEAM_DRAGON_HIDE
:
1143 case ARM_MOTTLED_DRAGON_HIDE
:
1144 case ARM_STORM_DRAGON_HIDE
:
1145 case ARM_GOLD_DRAGON_HIDE
:
1146 case ARM_SWAMP_DRAGON_HIDE
:
1147 case ARM_PEARL_DRAGON_HIDE
:
1157 equipment_type
get_armour_slot(const item_def
&item
)
1159 ASSERT(item
.base_type
== OBJ_ARMOUR
);
1161 return (Armour_prop
[ Armour_index
[item
.sub_type
] ].slot
);
1164 equipment_type
get_armour_slot(armour_type arm
)
1166 return (Armour_prop
[ Armour_index
[arm
] ].slot
);
1169 bool jewellery_is_amulet(const item_def
&item
)
1171 ASSERT(item
.base_type
== OBJ_JEWELLERY
);
1173 return (item
.sub_type
>= AMU_RAGE
);
1176 bool jewellery_is_amulet(int sub_type
)
1178 return (sub_type
>= AMU_RAGE
);
1181 // Returns the basic light status of an armour, ignoring things like the
1182 // elven bonus... you probably want is_light_armour() most times.
1183 bool base_armour_is_light(const item_def
&item
)
1185 ASSERT(item
.base_type
== OBJ_ARMOUR
);
1187 return (Armour_prop
[ Armour_index
[item
.sub_type
] ].light
);
1190 // Returns number of sizes off (0 if fitting).
1191 int fit_armour_size(const item_def
&item
, size_type size
)
1193 ASSERT(item
.base_type
== OBJ_ARMOUR
);
1195 const size_type min
= Armour_prop
[ Armour_index
[item
.sub_type
] ].fit_min
;
1196 const size_type max
= Armour_prop
[ Armour_index
[item
.sub_type
] ].fit_max
;
1199 return (min
- size
); // -'ve means levels too small
1200 else if (size
> max
)
1201 return (max
- size
); // +'ve means levels too large
1206 // Returns true if armour fits size (shape needs additional verification).
1207 bool check_armour_size(const item_def
&item
, size_type size
)
1209 ASSERT(item
.base_type
== OBJ_ARMOUR
);
1211 return (fit_armour_size(item
, size
) == 0);
1214 // Returns whether a wand or rod can be charged.
1215 // If hide_charged is true, wands known to be full will return false.
1216 // (This distinction is necessary because even full wands/rods give a message.)
1217 bool item_is_rechargeable(const item_def
&it
, bool hide_charged
, bool weapons
)
1219 // These are obvious...
1220 if (it
.base_type
== OBJ_WANDS
)
1225 // Don't offer wands already maximally charged.
1226 if (it
.plus2
== ZAPCOUNT_MAX_CHARGED
1227 || item_ident(it
, ISFLAG_KNOW_PLUSES
)
1228 && it
.plus
>= wand_max_charges(it
.sub_type
))
1234 else if (item_is_rod(it
))
1239 if (item_ident(it
, ISFLAG_KNOW_PLUSES
))
1241 return (it
.plus2
< MAX_ROD_CHARGE
* ROD_CHARGE_MULT
1242 || it
.plus
< it
.plus2
1243 || !it
.props
.exists("rod_enchantment")
1244 || short(it
.props
["rod_enchantment"]) < MAX_WPN_ENCHANT
);
1252 int wand_charge_value(int type
)
1256 case WAND_INVISIBILITY
:
1258 case WAND_TELEPORTATION
:
1263 case WAND_LIGHTNING
:
1276 int wand_max_charges(int type
)
1278 return wand_charge_value(type
) * 3;
1281 bool is_enchantable_weapon(const item_def
&wpn
, bool uncurse
, bool first
)
1283 if (wpn
.base_type
!= OBJ_WEAPONS
1284 && wpn
.base_type
!= OBJ_STAVES
1285 && wpn
.base_type
!= OBJ_MISSILES
)
1290 if (uncurse
&& wpn
.cursed() && you
.religion
!= GOD_ASHENZARI
)
1293 // Blowguns don't have any to-dam.
1294 // but they can be uncursed. -doy
1295 if (!first
&& wpn
.base_type
== OBJ_WEAPONS
&& wpn
.sub_type
== WPN_BLOWGUN
)
1298 // Artefacts or highly enchanted weapons cannot be enchanted,
1300 if (wpn
.base_type
== OBJ_WEAPONS
)
1302 if (is_artefact(wpn
)
1303 || first
&& wpn
.plus
>= MAX_WPN_ENCHANT
1304 || !first
&& wpn
.plus2
>= MAX_WPN_ENCHANT
)
1309 // Highly enchanted missiles, which have only one stat, cannot be
1310 // enchanted or uncursed, since missiles cannot be artefacts or
1312 else if (wpn
.plus
>= MAX_WPN_ENCHANT
)
1318 // Returns whether a piece of armour can be enchanted further.
1319 // If unknown is true, unidentified armour will return true.
1320 bool is_enchantable_armour(const item_def
&arm
, bool uncurse
, bool unknown
)
1322 if (arm
.base_type
!= OBJ_ARMOUR
)
1325 // Melded armour cannot be enchanted.
1326 if (item_is_melded(arm
))
1329 // If we don't know the plusses, assume enchanting is possible.
1330 if (unknown
&& !is_known_artefact(arm
)
1331 && !item_ident(arm
, ISFLAG_KNOW_PLUSES
))
1336 // Artefacts or highly enchanted armour cannot be enchanted, only
1338 if (is_artefact(arm
) || arm
.plus
>= armour_max_enchant(arm
))
1339 return (uncurse
&& arm
.cursed() && you
.religion
!= GOD_ASHENZARI
);
1345 // Weapon information and checking functions:
1348 // Checks how rare a weapon is. Many of these have special routines for
1349 // placement, especially those with a rarity of zero. Chance is out of 10.
1350 int weapon_rarity(int w_type
)
1360 case WPN_QUARTERSTAFF
:
1367 case WPN_SHORT_SWORD
:
1373 case WPN_LONG_SWORD
:
1374 case WPN_MORNINGSTAR
:
1380 case WPN_GREAT_SWORD
:
1391 case WPN_SPIKED_FLAIL
:
1395 case WPN_GREAT_MACE
:
1399 case WPN_DIRE_FLAIL
:
1405 case WPN_GIANT_CLUB
:
1406 case WPN_GIANT_SPIKED_CLUB
:
1410 case WPN_DOUBLE_SWORD
:
1411 case WPN_EVENINGSTAR
:
1412 case WPN_EXECUTIONERS_AXE
:
1415 case WPN_QUICK_BLADE
:
1416 case WPN_TRIPLE_SWORD
:
1417 case WPN_DEMON_WHIP
:
1418 case WPN_DEMON_BLADE
:
1419 case WPN_DEMON_TRIDENT
:
1420 case WPN_BLESSED_FALCHION
:
1421 case WPN_BLESSED_LONG_SWORD
:
1422 case WPN_BLESSED_SCIMITAR
:
1423 case WPN_BLESSED_KATANA
:
1424 case WPN_EUDEMON_BLADE
:
1425 case WPN_BLESSED_DOUBLE_SWORD
:
1426 case WPN_BLESSED_GREAT_SWORD
:
1427 case WPN_BLESSED_TRIPLE_SWORD
:
1428 case WPN_SACRED_SCOURGE
:
1430 // Zero value weapons must be placed specially -- see make_item() {dlb}
1440 int get_vorpal_type(const item_def
&item
)
1442 int ret
= DVORP_NONE
;
1444 if (item
.base_type
== OBJ_WEAPONS
)
1445 ret
= (Weapon_prop
[Weapon_index
[item
.sub_type
]].dam_type
& DAMV_MASK
);
1450 int get_damage_type(const item_def
&item
)
1454 if (item_is_rod(item
))
1456 if (item
.base_type
== OBJ_WEAPONS
)
1457 ret
= (Weapon_prop
[Weapon_index
[item
.sub_type
]].dam_type
& DAM_MASK
);
1462 bool does_damage_type(const item_def
&item
, int dam_type
)
1464 return (get_damage_type(item
) & dam_type
);
1467 int single_damage_type(const item_def
&item
)
1469 int ret
= get_damage_type(item
);
1475 for (int i
= 1; i
<= DAM_MAX_TYPE
; i
<<= 1)
1477 if (!does_damage_type(item
, i
))
1480 if (one_chance_in(++count
))
1488 hands_reqd_type
hands_reqd(object_class_type base_type
, int sub_type
,
1492 item
.base_type
= base_type
;
1493 item
.sub_type
= sub_type
;
1494 return hands_reqd(item
, size
);
1497 // Give hands required to wield weapon for a torso of "size".
1498 hands_reqd_type
hands_reqd(const item_def
&item
, size_type size
)
1500 int ret
= HANDS_ONE
;
1504 switch (item
.base_type
)
1508 // Merging staff with magical staves for consistency... doing
1509 // as a special case because we want to be very flexible with
1510 // these useful objects (we want spriggans and ogres to be
1511 // able to use them).
1512 if (item
.base_type
== OBJ_STAVES
|| weapon_skill(item
) == SK_STAVES
)
1514 if (size
< SIZE_SMALL
)
1516 else if (size
> SIZE_LARGE
)
1523 ret
= Weapon_prop
[ Weapon_index
[item
.sub_type
] ].hands
;
1525 // Size is the level where we can use one hand for one end.
1526 if (ret
== HANDS_DOUBLE
)
1529 ret
= HANDS_TWO
; // HANDS_HALF once double-ended is implemented.
1532 // Adjust handedness for size only for non-whip melee weapons.
1533 if (!is_range_weapon(item
)
1534 && item
.sub_type
!= WPN_WHIP
1535 && item
.sub_type
!= WPN_DEMON_WHIP
1536 && item
.sub_type
!= WPN_SACRED_SCOURGE
)
1538 fit
= cmp_weapon_size(item
, size
);
1540 // Adjust handedness for non-medium races:
1541 // (XX values don't matter, see fit_weapon_wieldable_size)
1543 // Spriggan Kobold Human Ogre Big Giant
1544 // Little 0 0 0 XX XX XX
1545 // Small +1 0 0 -2 XX XX
1546 // Medium XX +1 0 -1 -2 XX
1547 // Large XX XX 0 0 -1 -2
1548 // Big XX XX XX 0 0 -1
1549 // Giant XX XX XX XX 0 0
1551 // Note the stretching of double weapons for larger characters
1552 // by one level since they tend to be larger weapons.
1553 if (size
< SIZE_MEDIUM
&& fit
> 0)
1555 else if (size
> SIZE_MEDIUM
&& fit
< 0)
1556 ret
+= (fit
+ doub
);
1560 case OBJ_CORPSES
: // unwieldy
1564 case OBJ_ARMOUR
: // Bardings and body armours are unwieldy.
1565 if (item
.sub_type
== ARM_NAGA_BARDING
1566 || item
.sub_type
== ARM_CENTAUR_BARDING
1567 || get_armour_slot(item
) == EQ_BODY_ARMOUR
)
1577 if (ret
> HANDS_TWO
)
1579 else if (ret
< HANDS_ONE
)
1582 return (static_cast< hands_reqd_type
>(ret
));
1585 bool is_demonic(const item_def
&item
)
1587 if (item
.base_type
== OBJ_WEAPONS
)
1589 switch (item
.sub_type
)
1591 case WPN_DEMON_BLADE
:
1592 case WPN_DEMON_WHIP
:
1593 case WPN_DEMON_TRIDENT
:
1604 bool is_blessed(const item_def
&item
)
1606 if (item
.base_type
== OBJ_WEAPONS
)
1608 switch (item
.sub_type
)
1610 case WPN_BLESSED_FALCHION
:
1611 case WPN_BLESSED_LONG_SWORD
:
1612 case WPN_BLESSED_SCIMITAR
:
1613 case WPN_BLESSED_KATANA
:
1614 case WPN_EUDEMON_BLADE
:
1615 case WPN_BLESSED_DOUBLE_SWORD
:
1616 case WPN_BLESSED_GREAT_SWORD
:
1617 case WPN_BLESSED_TRIPLE_SWORD
:
1618 case WPN_SACRED_SCOURGE
:
1630 bool is_blessed_convertible(const item_def
&item
)
1632 return (!is_artefact(item
)
1633 && (item
.base_type
== OBJ_WEAPONS
1634 && (is_demonic(item
)
1635 || item
.sub_type
== WPN_SACRED_SCOURGE
1636 || item
.sub_type
== WPN_TRISHULA
1637 || weapon_skill(item
) == SK_LONG_BLADES
)));
1640 bool convert2good(item_def
&item
, bool allow_blessed
)
1642 if (item
.base_type
!= OBJ_WEAPONS
)
1645 switch (item
.sub_type
)
1653 item
.sub_type
= WPN_BLESSED_FALCHION
;
1656 case WPN_LONG_SWORD
:
1659 item
.sub_type
= WPN_BLESSED_LONG_SWORD
;
1665 item
.sub_type
= WPN_BLESSED_SCIMITAR
;
1668 case WPN_DEMON_BLADE
:
1670 item
.sub_type
= WPN_SCIMITAR
;
1672 item
.sub_type
= WPN_EUDEMON_BLADE
;
1678 item
.sub_type
= WPN_BLESSED_KATANA
;
1681 case WPN_DOUBLE_SWORD
:
1684 item
.sub_type
= WPN_BLESSED_DOUBLE_SWORD
;
1687 case WPN_GREAT_SWORD
:
1690 item
.sub_type
= WPN_BLESSED_GREAT_SWORD
;
1693 case WPN_TRIPLE_SWORD
:
1696 item
.sub_type
= WPN_BLESSED_TRIPLE_SWORD
;
1699 case WPN_DEMON_WHIP
:
1701 item
.sub_type
= WPN_WHIP
;
1703 item
.sub_type
= WPN_SACRED_SCOURGE
;
1706 case WPN_DEMON_TRIDENT
:
1708 item
.sub_type
= WPN_TRIDENT
;
1710 item
.sub_type
= WPN_TRISHULA
;
1714 if (is_blessed(item
))
1715 item
.flags
&= ~ISFLAG_RACIAL_MASK
;
1720 bool convert2bad(item_def
&item
)
1722 if (item
.base_type
!= OBJ_WEAPONS
)
1725 switch (item
.sub_type
)
1730 case WPN_BLESSED_FALCHION
:
1731 item
.sub_type
= WPN_FALCHION
;
1734 case WPN_BLESSED_LONG_SWORD
:
1735 item
.sub_type
= WPN_LONG_SWORD
;
1738 case WPN_BLESSED_SCIMITAR
:
1739 item
.sub_type
= WPN_SCIMITAR
;
1742 case WPN_EUDEMON_BLADE
:
1743 item
.sub_type
= WPN_DEMON_BLADE
;
1746 case WPN_BLESSED_KATANA
:
1747 item
.sub_type
= WPN_KATANA
;
1750 case WPN_BLESSED_DOUBLE_SWORD
:
1751 item
.sub_type
= WPN_DOUBLE_SWORD
;
1754 case WPN_BLESSED_GREAT_SWORD
:
1755 item
.sub_type
= WPN_GREAT_SWORD
;
1758 case WPN_BLESSED_TRIPLE_SWORD
:
1759 item
.sub_type
= WPN_TRIPLE_SWORD
;
1762 case WPN_SACRED_SCOURGE
:
1763 item
.sub_type
= WPN_DEMON_WHIP
;
1767 item
.sub_type
= WPN_DEMON_TRIDENT
;
1774 int weapon_str_weight(const item_def
&wpn
)
1776 ASSERT (wpn
.base_type
== OBJ_WEAPONS
|| wpn
.base_type
== OBJ_STAVES
);
1778 if (wpn
.base_type
== OBJ_STAVES
)
1779 return (Weapon_prop
[ Weapon_index
[WPN_QUARTERSTAFF
] ].str_weight
);
1781 return (Weapon_prop
[ Weapon_index
[wpn
.sub_type
] ].str_weight
);
1784 int weapon_dex_weight(const item_def
&wpn
)
1786 return (10 - weapon_str_weight(wpn
));
1789 // Returns melee skill of item.
1790 skill_type
weapon_skill(const item_def
&item
)
1792 if (item
.base_type
== OBJ_WEAPONS
&& !is_range_weapon(item
))
1793 return (Weapon_prop
[ Weapon_index
[item
.sub_type
] ].skill
);
1794 else if (item_is_rod(item
))
1795 return (SK_MACES_FLAILS
); // Rods are short and stubby
1796 else if (item
.base_type
== OBJ_STAVES
)
1799 // This is used to mark that only fighting applies.
1800 return (SK_FIGHTING
);
1803 // Front function for the above when we don't have a physical item to check.
1804 skill_type
weapon_skill(object_class_type wclass
, int wtype
)
1808 wpn
.base_type
= wclass
;
1809 wpn
.sub_type
= wtype
;
1811 return (weapon_skill(wpn
));
1814 // Returns range skill of the item.
1815 skill_type
range_skill(const item_def
&item
)
1817 if (item
.base_type
== OBJ_WEAPONS
&& is_range_weapon(item
))
1818 return (Weapon_prop
[ Weapon_index
[item
.sub_type
] ].skill
);
1819 else if (item
.base_type
== OBJ_MISSILES
)
1821 switch (item
.sub_type
)
1823 case MI_DART
: return (SK_THROWING
);
1824 case MI_JAVELIN
: return (SK_POLEARMS
);
1829 return (SK_THROWING
);
1832 // Front function for the above when we don't have a physical item to check.
1833 skill_type
range_skill(object_class_type wclass
, int wtype
)
1837 wpn
.base_type
= wclass
;
1838 wpn
.sub_type
= wtype
;
1840 return (range_skill(wpn
));
1844 // Calculate the bonus to melee EV for using "wpn", with "skill" and "dex"
1845 // to protect a body of size "body".
1846 int weapon_ev_bonus(const item_def
&wpn
, int skill
, size_type body
, int dex
,
1849 ASSERT(wpn
.base_type
== OBJ_WEAPONS
|| wpn
.base_type
== OBJ_STAVES
);
1853 // Note: ret currently measured in halves (see skill factor).
1854 if (wpn
.sub_type
== WPN_WHIP
|| wpn
.sub_type
== WPN_DEMON_WHIP
)
1855 ret
= 3 + (dex
/ 5);
1856 else if (weapon_skill(wpn
) == SK_POLEARMS
)
1857 ret
= 2 + (dex
/ 5);
1859 // Weapons of reaching are naturally a bit longer/flexier.
1860 if (!hide_hidden
|| item_type_known(wpn
))
1862 if (get_weapon_brand(wpn
) == SPWPN_REACHING
)
1866 // Only consider additional modifications if we have a positive base:
1870 // - large characters can't cover their flanks as well
1871 // - note that not all weapons are available to small characters
1872 if (body
> SIZE_LARGE
)
1873 ret
-= (4 * (body
- SIZE_LARGE
) - 2);
1874 else if (body
< SIZE_MEDIUM
)
1877 // apply skill (and dividing by 2)
1878 ret
= (ret
* (skill
+ 10)) / 20;
1880 // Make sure things can't get too insane.
1882 ret
= 8 + (ret
- 8) / 2;
1885 // Note: this is always a bonus.
1886 return ((ret
> 0) ? ret
: 0);
1889 static size_type
weapon_size(const item_def
&item
)
1891 ASSERT (item
.base_type
== OBJ_WEAPONS
|| item
.base_type
== OBJ_STAVES
);
1893 if (item
.base_type
== OBJ_STAVES
)
1894 return (Weapon_prop
[ Weapon_index
[WPN_QUARTERSTAFF
] ].fit_size
);
1896 return (Weapon_prop
[ Weapon_index
[item
.sub_type
] ].fit_size
);
1899 // Returns number of sizes off.
1900 int cmp_weapon_size(const item_def
&item
, size_type size
)
1902 ASSERT(item
.base_type
== OBJ_WEAPONS
|| item
.base_type
== OBJ_STAVES
);
1904 return (weapon_size(item
) - size
);
1907 // Returns number of sizes away from being a usable weapon.
1908 int fit_weapon_wieldable_size(const item_def
&item
, size_type size
)
1910 ASSERT(item
.base_type
== OBJ_WEAPONS
|| item
.base_type
== OBJ_STAVES
);
1912 const int fit
= cmp_weapon_size(item
, size
);
1914 return ((fit
< -2) ? fit
+ 2 :
1915 (fit
> 1) ? fit
- 1 : 0);
1918 // Returns number of sizes away from being throwable... the window
1919 // is currently [size - 5, size - 1].
1920 int fit_item_throwable_size(const item_def
&item
, size_type size
)
1922 int ret
= item_size(item
) - size
;
1924 return ((ret
>= 0) ? ret
+ 1 :
1929 // Returns true if weapon is usable as a weapon.
1930 bool check_weapon_wieldable_size(const item_def
&item
, size_type size
)
1932 ASSERT(item
.base_type
== OBJ_WEAPONS
|| item
.base_type
== OBJ_STAVES
);
1934 // Staves are currently wieldable for everyone just to be nice.
1935 if (item
.base_type
== OBJ_STAVES
|| weapon_skill(item
) == SK_STAVES
)
1938 int fit
= fit_weapon_wieldable_size(item
, size
);
1940 // Adjust fit for size.
1941 if (size
< SIZE_SMALL
&& fit
> 0)
1943 else if (size
> SIZE_LARGE
&& fit
< 0)
1950 // Launcher and ammo functions:
1952 missile_type
fires_ammo_type(const item_def
&item
)
1954 if (item
.base_type
!= OBJ_WEAPONS
)
1957 return (Weapon_prop
[Weapon_index
[item
.sub_type
]].ammo
);
1960 missile_type
fires_ammo_type(weapon_type wtype
)
1963 wpn
.base_type
= OBJ_WEAPONS
;
1964 wpn
.sub_type
= wtype
;
1966 return (fires_ammo_type(wpn
));
1969 bool is_range_weapon(const item_def
&item
)
1971 return (fires_ammo_type(item
) != MI_NONE
);
1974 bool is_range_weapon_type(weapon_type wtype
)
1977 wpn
.base_type
= OBJ_WEAPONS
;
1978 wpn
.sub_type
= wtype
;
1980 return (is_range_weapon(wpn
));
1983 const char *ammo_name(missile_type ammo
)
1985 return (ammo
< 0 || ammo
>= NUM_MISSILES
? "eggplant"
1986 : Missile_prop
[ Missile_index
[ammo
] ].name
);
1989 const char *ammo_name(const item_def
&bow
)
1991 ASSERT(is_range_weapon(bow
));
1992 return ammo_name(fires_ammo_type(bow
));
1995 // Returns true if item has an associated launcher.
1996 bool has_launcher(const item_def
&ammo
)
1998 ASSERT(ammo
.base_type
== OBJ_MISSILES
);
1999 return (ammo
.sub_type
!= MI_DART
2000 && ammo
.sub_type
!= MI_LARGE_ROCK
2001 && ammo
.sub_type
!= MI_JAVELIN
2002 && ammo
.sub_type
!= MI_THROWING_NET
);
2005 // Returns true if item can be reasonably thrown without a launcher.
2006 bool is_throwable(const actor
*actor
, const item_def
&wpn
, bool force
)
2008 size_type bodysize
= actor
->body_size();
2010 if (wpn
.base_type
== OBJ_WEAPONS
)
2011 return (Weapon_prop
[Weapon_index
[wpn
.sub_type
]].throwable
);
2012 else if (wpn
.base_type
== OBJ_MISSILES
)
2016 if ((bodysize
< SIZE_LARGE
2017 || !actor
->can_throw_large_rocks())
2018 && wpn
.sub_type
== MI_LARGE_ROCK
)
2023 if (bodysize
< SIZE_MEDIUM
2024 && (wpn
.sub_type
== MI_JAVELIN
2025 || wpn
.sub_type
== MI_THROWING_NET
))
2031 return (Missile_prop
[Missile_index
[wpn
.sub_type
]].throwable
);
2037 // Decide if something is launched or thrown.
2038 launch_retval
is_launched(const actor
*actor
, const item_def
*launcher
,
2039 const item_def
&missile
)
2041 if (missile
.base_type
== OBJ_MISSILES
2043 && missile
.launched_by(*launcher
))
2045 return (LRET_LAUNCHED
);
2048 return (is_throwable(actor
, missile
) ? LRET_THROWN
: LRET_FUMBLED
);
2052 // Staff/rod functions:
2054 bool item_is_rod(const item_def
&item
)
2056 return (item
.base_type
== OBJ_STAVES
&& item
.sub_type
>= STAFF_FIRST_ROD
);
2059 bool item_is_staff(const item_def
&item
)
2061 return (item
.base_type
== OBJ_STAVES
&& !item_is_rod(item
));
2067 bool item_is_rune(const item_def
&item
, rune_type which_rune
)
2069 return (item
.base_type
== OBJ_MISCELLANY
2070 && item
.sub_type
== MISC_RUNE_OF_ZOT
2071 && (which_rune
== NUM_RUNE_TYPES
|| item
.plus
== which_rune
));
2074 bool item_is_unique_rune(const item_def
&item
)
2076 return (item
.base_type
== OBJ_MISCELLANY
2077 && item
.sub_type
== MISC_RUNE_OF_ZOT
2078 && item
.plus
!= RUNE_DEMONIC
2079 && item
.plus
!= RUNE_ABYSSAL
);
2082 bool item_is_orb(const item_def
&item
)
2084 return (item
.base_type
== OBJ_ORBS
&& item
.sub_type
== ORB_ZOT
);
2087 bool item_is_corpse(const item_def
&item
)
2089 return (item
.base_type
== OBJ_CORPSES
&& item
.sub_type
== CORPSE_BODY
);
2092 bool item_is_spellbook(const item_def
&item
)
2094 return (item
.base_type
== OBJ_BOOKS
&& item
.sub_type
!= BOOK_MANUAL
2095 && item
.sub_type
!= BOOK_DESTRUCTION
);
2101 // Returns number of pluses on jewellery (always none for amulets yet).
2102 int ring_has_pluses(const item_def
&item
)
2104 ASSERT (item
.base_type
== OBJ_JEWELLERY
);
2106 // not known -> no pluses
2107 if (!item_type_known(item
))
2110 switch (item
.sub_type
)
2115 case RING_PROTECTION
:
2118 case RING_INTELLIGENCE
:
2119 case RING_DEXTERITY
:
2129 // Returns true if having two rings of the same type on at the same
2130 // has more effect than just having one on.
2131 bool ring_has_stackable_effect(const item_def
&item
)
2133 ASSERT (item
.base_type
== OBJ_JEWELLERY
);
2134 ASSERT (!jewellery_is_amulet(item
));
2136 if (!item_type_known(item
))
2139 if (ring_has_pluses(item
))
2142 switch (item
.sub_type
)
2144 case RING_PROTECTION_FROM_FIRE
:
2145 case RING_PROTECTION_FROM_COLD
:
2146 case RING_LIFE_PROTECTION
:
2147 case RING_SUSTENANCE
:
2163 bool food_is_meat(const item_def
&item
)
2165 ASSERT(item
.defined() && item
.base_type
== OBJ_FOOD
);
2166 return (Food_prop
[Food_index
[item
.sub_type
]].carn_mod
> 0);
2169 bool food_is_veg(const item_def
&item
)
2171 ASSERT(item
.defined() && item
.base_type
== OBJ_FOOD
);
2172 return (Food_prop
[Food_index
[item
.sub_type
]].herb_mod
> 0);
2175 bool is_blood_potion(const item_def
&item
)
2177 if (item
.base_type
!= OBJ_POTIONS
)
2180 return (item
.sub_type
== POT_BLOOD
2181 || item
.sub_type
== POT_BLOOD_COAGULATED
);
2184 bool is_fizzing_potion (const item_def
&item
)
2186 if (item
.base_type
!= OBJ_POTIONS
)
2189 return (item
.sub_type
== POT_FIZZING
);
2192 // Returns food value for one turn of eating.
2193 int food_value(const item_def
&item
)
2195 ASSERT(item
.defined() && item
.base_type
== OBJ_FOOD
);
2197 const int herb
= player_mutation_level(MUT_HERBIVOROUS
);
2199 // XXX: This needs to be better merged with the mutation system.
2200 const int carn
= player_mutation_level(MUT_CARNIVOROUS
);
2202 const food_def
&food
= Food_prop
[Food_index
[item
.sub_type
]];
2204 int ret
= food
.value
;
2206 ret
+= (carn
* food
.carn_mod
);
2207 ret
+= (herb
* food
.herb_mod
);
2209 return ((ret
> 0) ? div_rand_round(ret
, food
.turns
) : 0);
2212 int food_turns(const item_def
&item
)
2214 ASSERT(item
.defined() && item
.base_type
== OBJ_FOOD
);
2215 return (Food_prop
[Food_index
[item
.sub_type
]].turns
);
2218 bool can_cut_meat(const item_def
&item
)
2220 return (does_damage_type(item
, DAM_SLICE
));
2223 bool is_fruit(const item_def
& item
)
2225 if (item
.base_type
!= OBJ_FOOD
)
2228 return (Food_prop
[Food_index
[item
.sub_type
]].flags
& FFL_FRUIT
);
2231 uint32_t item_fruit_mask(const item_def
&item
)
2233 return (is_fruit(item
)? (1 << Food_index
[item
.sub_type
]) : 0);
2236 bool food_is_rotten(const item_def
&item
)
2238 return (item
.special
<= ROTTING_CORPSE
)
2239 && (item
.base_type
== OBJ_CORPSES
2240 && item
.sub_type
== CORPSE_BODY
2241 || item
.base_type
== OBJ_FOOD
2242 && item
.sub_type
== FOOD_CHUNK
);
2245 int corpse_freshness(const item_def
&item
)
2247 ASSERT(item
.base_type
== OBJ_CORPSES
);
2248 ASSERT(item
.special
<= FRESHEST_CORPSE
);
2249 return (item
.special
);
2253 // Generic item functions:
2255 int get_armour_res_fire(const item_def
&arm
, bool check_artp
)
2257 ASSERT(arm
.base_type
== OBJ_ARMOUR
);
2261 // intrinsic armour abilities
2262 switch (arm
.sub_type
)
2264 case ARM_DRAGON_ARMOUR
:
2265 case ARM_DRAGON_HIDE
:
2268 case ARM_GOLD_DRAGON_ARMOUR
:
2269 case ARM_GOLD_DRAGON_HIDE
:
2272 case ARM_ICE_DRAGON_ARMOUR
:
2273 case ARM_ICE_DRAGON_HIDE
:
2280 // check ego resistance
2281 const int ego
= get_armour_ego_type(arm
);
2282 if (ego
== SPARM_FIRE_RESISTANCE
|| ego
== SPARM_RESISTANCE
)
2285 if (check_artp
&& is_artefact(arm
))
2286 res
+= artefact_wpn_property(arm
, ARTP_FIRE
);
2291 int get_armour_res_cold(const item_def
&arm
, bool check_artp
)
2293 ASSERT(arm
.base_type
== OBJ_ARMOUR
);
2297 // intrinsic armour abilities
2298 switch (arm
.sub_type
)
2300 case ARM_ICE_DRAGON_ARMOUR
:
2301 case ARM_ICE_DRAGON_HIDE
:
2304 case ARM_GOLD_DRAGON_ARMOUR
:
2305 case ARM_GOLD_DRAGON_HIDE
:
2308 case ARM_DRAGON_ARMOUR
:
2309 case ARM_DRAGON_HIDE
:
2316 // check ego resistance
2317 const int ego
= get_armour_ego_type(arm
);
2318 if (ego
== SPARM_COLD_RESISTANCE
|| ego
== SPARM_RESISTANCE
)
2321 if (check_artp
&& is_artefact(arm
))
2322 res
+= artefact_wpn_property(arm
, ARTP_COLD
);
2327 int get_armour_res_poison(const item_def
&arm
, bool check_artp
)
2329 ASSERT(arm
.base_type
== OBJ_ARMOUR
);
2333 // intrinsic armour abilities
2334 switch (arm
.sub_type
)
2336 case ARM_SWAMP_DRAGON_ARMOUR
:
2337 case ARM_SWAMP_DRAGON_HIDE
:
2340 case ARM_GOLD_DRAGON_ARMOUR
:
2341 case ARM_GOLD_DRAGON_HIDE
:
2348 // check ego resistance
2349 if (get_armour_ego_type(arm
) == SPARM_POISON_RESISTANCE
)
2352 if (check_artp
&& is_artefact(arm
))
2353 res
+= artefact_wpn_property(arm
, ARTP_POISON
);
2358 int get_armour_res_elec(const item_def
&arm
, bool check_artp
)
2360 ASSERT(arm
.base_type
== OBJ_ARMOUR
);
2364 // intrinsic armour abilities
2365 switch (arm
.sub_type
)
2367 case ARM_STORM_DRAGON_ARMOUR
:
2368 case ARM_STORM_DRAGON_HIDE
:
2375 if (check_artp
&& is_artefact(arm
))
2376 res
+= artefact_wpn_property(arm
, ARTP_ELECTRICITY
);
2381 int get_armour_life_protection(const item_def
&arm
, bool check_artp
)
2383 ASSERT(arm
.base_type
== OBJ_ARMOUR
);
2387 // Pearl dragon armour grants rN+.
2388 if (arm
.sub_type
== ARM_PEARL_DRAGON_ARMOUR
)
2391 // check for ego resistance
2392 if (get_armour_ego_type(arm
) == SPARM_POSITIVE_ENERGY
)
2395 if (check_artp
&& is_artefact(arm
))
2396 res
+= artefact_wpn_property(arm
, ARTP_NEGATIVE_ENERGY
);
2401 int get_armour_res_magic(const item_def
&arm
, bool check_artp
)
2403 ASSERT(arm
.base_type
== OBJ_ARMOUR
);
2407 // check for ego resistance
2408 if (get_armour_ego_type(arm
) == SPARM_MAGIC_RESISTANCE
)
2411 if (check_artp
&& is_artefact(arm
))
2412 res
+= artefact_wpn_property(arm
, ARTP_MAGIC
);
2417 bool get_armour_see_invisible(const item_def
&arm
, bool check_artp
)
2419 ASSERT(arm
.base_type
== OBJ_ARMOUR
);
2421 // check for ego resistance
2422 if (get_armour_ego_type(arm
) == SPARM_POSITIVE_ENERGY
)
2425 if (check_artp
&& is_artefact(arm
))
2426 return artefact_wpn_property(arm
, ARTP_EYESIGHT
);
2431 int get_armour_res_sticky_flame(const item_def
&arm
)
2433 ASSERT(arm
.base_type
== OBJ_ARMOUR
);
2435 // intrinsic armour abilities
2436 switch (arm
.sub_type
)
2438 case ARM_MOTTLED_DRAGON_ARMOUR
:
2439 case ARM_MOTTLED_DRAGON_HIDE
:
2446 int property(const item_def
&item
, int prop_type
)
2448 weapon_type weapon_sub
;
2450 switch (item
.base_type
)
2453 if (prop_type
== PARM_AC
)
2454 return (Armour_prop
[ Armour_index
[item
.sub_type
] ].ac
);
2455 else if (prop_type
== PARM_EVASION
)
2456 return (Armour_prop
[ Armour_index
[item
.sub_type
] ].ev
);
2460 if (prop_type
== PWPN_DAMAGE
)
2461 return (Weapon_prop
[ Weapon_index
[item
.sub_type
] ].dam
);
2462 else if (prop_type
== PWPN_HIT
)
2463 return (Weapon_prop
[ Weapon_index
[item
.sub_type
] ].hit
);
2464 else if (prop_type
== PWPN_SPEED
)
2465 return (Weapon_prop
[ Weapon_index
[item
.sub_type
] ].speed
);
2466 else if (prop_type
== PWPN_ACQ_WEIGHT
)
2467 return (Weapon_prop
[ Weapon_index
[item
.sub_type
] ].acquire_weight
);
2471 if (prop_type
== PWPN_DAMAGE
)
2472 return (Missile_prop
[ Missile_index
[item
.sub_type
] ].dam
);
2476 weapon_sub
= item_is_rod(item
) ? WPN_CLUB
: WPN_QUARTERSTAFF
;
2478 if (prop_type
== PWPN_DAMAGE
)
2479 return (Weapon_prop
[ Weapon_index
[weapon_sub
] ].dam
);
2480 else if (prop_type
== PWPN_HIT
)
2481 return (Weapon_prop
[ Weapon_index
[weapon_sub
] ].hit
);
2482 else if (prop_type
== PWPN_SPEED
)
2483 return (Weapon_prop
[ Weapon_index
[weapon_sub
] ].speed
);
2493 // Returns true if item is evokable.
2494 bool gives_ability(const item_def
&item
)
2496 if (!item_type_known(item
))
2499 switch (item
.base_type
)
2504 if (!jewellery_is_amulet(item
))
2506 if (item
.sub_type
== RING_TELEPORTATION
2507 || item
.sub_type
== RING_LEVITATION
2508 || item
.sub_type
== RING_INVISIBILITY
)
2515 if (item
.sub_type
== AMU_RAGE
)
2521 const equipment_type eq
= get_armour_slot(item
);
2524 const special_armour_type ego
= get_armour_ego_type(item
);
2526 if (ego
== SPARM_DARKNESS
|| ego
== SPARM_LEVITATION
)
2534 if (!is_artefact(item
))
2537 // Check for evokable randart properties.
2538 for (int rap
= ARTP_INVISIBLE
; rap
<= ARTP_BERSERK
; rap
++)
2539 if (artefact_wpn_property(item
, static_cast<artefact_prop_type
>(rap
)))
2545 // Returns true if the item confers an intrinsic that is shown on the % screen.
2546 bool gives_resistance(const item_def
&item
)
2548 if (!item_type_known(item
))
2551 switch (item
.base_type
)
2556 if (!jewellery_is_amulet(item
))
2558 if (item
.sub_type
>= RING_PROTECTION_FROM_FIRE
2559 && item
.sub_type
<= RING_PROTECTION_FROM_COLD
2560 || item
.sub_type
== RING_SEE_INVISIBLE
2561 || item
.sub_type
>= RING_LIFE_PROTECTION
2562 && item
.sub_type
<= RING_TELEPORT_CONTROL
2563 || item
.sub_type
== RING_SUSTAIN_ABILITIES
)
2570 if (item
.sub_type
!= AMU_RAGE
&& item
.sub_type
!= AMU_INACCURACY
)
2576 const equipment_type eq
= get_armour_slot(item
);
2580 const int ego
= get_armour_ego_type(item
);
2581 if (ego
>= SPARM_FIRE_RESISTANCE
&& ego
<= SPARM_SEE_INVISIBLE
2582 || ego
== SPARM_RESISTANCE
|| ego
== SPARM_POSITIVE_ENERGY
)
2589 if (item
.sub_type
>= STAFF_FIRE
&& item
.sub_type
<= STAFF_POISON
2590 || item
.sub_type
== STAFF_AIR
)
2599 if (!is_artefact(item
))
2602 // Check for randart resistances.
2603 for (int rap
= ARTP_FIRE
; rap
<= ARTP_BERSERK
; rap
++)
2605 if (rap
== ARTP_MAGIC
|| rap
>= ARTP_INVISIBLE
)
2608 if (artefact_wpn_property(item
, static_cast<artefact_prop_type
>(rap
)))
2615 int item_mass(const item_def
&item
)
2619 switch (item
.base_type
)
2622 unit_mass
= Weapon_prop
[ Weapon_index
[item
.sub_type
] ].mass
;
2626 unit_mass
= Armour_prop
[ Armour_index
[item
.sub_type
] ].mass
;
2628 if (get_equip_race(item
) == ISFLAG_ELVEN
)
2630 const int reduc
= (unit_mass
>= 25) ? unit_mass
/ 5 : 5;
2632 // Truncate to the nearest 5 and reduce the item mass:
2633 unit_mass
-= ((reduc
/ 5) * 5);
2634 unit_mass
= std::max(unit_mass
, 5);
2640 unit_mass
= Missile_prop
[ Missile_index
[item
.sub_type
] ].mass
;
2641 int brand
= get_ammo_brand(item
);
2643 if (brand
== SPMSL_SILVER
)
2645 else if (brand
== SPMSL_STEEL
)
2651 unit_mass
= Food_prop
[ Food_index
[item
.sub_type
] ].mass
;
2682 case OBJ_MISCELLANY
:
2688 switch (item
.sub_type
)
2690 case MISC_BOTTLED_EFREET
:
2691 case MISC_CRYSTAL_BALL_OF_SEEING
:
2692 case MISC_CRYSTAL_BALL_OF_ENERGY
:
2693 case MISC_CRYSTAL_BALL_OF_FIXATION
:
2704 unit_mass
= mons_weight(item
.plus
);
2706 if (item
.sub_type
== CORPSE_SKELETON
)
2716 return ((unit_mass
> 0) ? unit_mass
: 0);
2719 // Note that this function, and item sizes in general aren't quite on the
2720 // same scale as PCs and monsters.
2721 size_type
item_size(const item_def
&item
)
2723 int size
= SIZE_TINY
;
2725 switch (item
.base_type
)
2729 size
= Weapon_prop
[ Weapon_index
[item
.sub_type
] ].fit_size
- 1;
2735 switch (item
.sub_type
)
2740 case ARM_WIZARD_HAT
:
2751 case ARM_LARGE_SHIELD
:
2755 default: // Body armours and bardings.
2762 if (item
.sub_type
== MI_LARGE_ROCK
)
2766 case OBJ_MISCELLANY
:
2770 // FIXME: This should depend on the original monster's size!
2774 default: // sundry tiny items
2778 if (size
< SIZE_TINY
)
2780 else if (size
> SIZE_HUGE
)
2783 return (static_cast<size_type
>(size
));
2786 equipment_type
get_item_slot(const item_def
& item
)
2788 return get_item_slot(item
.base_type
, item
.sub_type
);
2791 equipment_type
get_item_slot(object_class_type type
, int sub_type
)
2797 case OBJ_MISCELLANY
:
2801 return get_armour_slot(static_cast<armour_type
>(sub_type
));
2804 return (jewellery_is_amulet(sub_type
) ? EQ_AMULET
: EQ_RINGS
);
2813 bool is_shield(const item_def
&item
)
2815 return (item
.base_type
== OBJ_ARMOUR
2816 && get_armour_slot(item
) == EQ_SHIELD
);
2819 // Returns true if the given item cannot be wielded with the given shield.
2820 // The currently equipped shield is used if no shield is passed in.
2821 bool is_shield_incompatible(const item_def
&weapon
, const item_def
*shield
)
2823 // If there's no shield, there's no problem.
2824 if (!shield
&& !(shield
= you
.shield()))
2827 hands_reqd_type hand
= hands_reqd(weapon
, you
.body_size());
2828 return (hand
== HANDS_TWO
2829 && !item_is_rod(weapon
)
2830 && !is_range_weapon(weapon
));
2833 bool shield_reflects(const item_def
&shield
)
2835 ASSERT(is_shield(shield
));
2837 return (get_armour_ego_type(shield
) == SPARM_REFLECTION
);
2840 void ident_reflector(item_def
*item
)
2842 if (!is_artefact(*item
))
2843 set_ident_flags(*item
, ISFLAG_KNOW_TYPE
);
2846 std::string
item_base_name(const item_def
&item
)
2848 return item_base_name(item
.base_type
, item
.sub_type
);
2851 std::string
item_base_name (object_class_type type
, int sub_type
)
2856 return Weapon_prop
[Weapon_index
[sub_type
]].name
;
2858 return Missile_prop
[Missile_index
[sub_type
]].name
;
2860 return Armour_prop
[Armour_index
[sub_type
]].name
;
2862 return (jewellery_is_amulet(sub_type
) ? "amulet" : "ring");
2868 std::string
food_type_name (const item_def
&item
)
2870 ASSERT(item
.base_type
== OBJ_FOOD
);
2872 return food_type_name(item
.sub_type
);
2875 std::string
food_type_name (int sub_type
)
2877 return (Food_prop
[Food_index
[sub_type
]].name
);
2880 const char* weapon_base_name(uint8_t subtype
)
2882 return Weapon_prop
[Weapon_index
[subtype
]].name
;
2885 bool in_shop(const item_def
&item
)
2887 // yay the shop hack...
2888 return (item
.pos
.x
== 0 && item
.pos
.y
>= 5);
2891 void seen_item(const item_def
&item
)
2893 if (!is_artefact(item
) && _is_affordable(item
))
2895 // Known brands will be set in set_item_flags().
2896 if (item
.base_type
== OBJ_WEAPONS
)
2897 you
.seen_weapon
[item
.sub_type
] |= 1 << SP_UNKNOWN_BRAND
;
2898 if (item
.base_type
== OBJ_ARMOUR
)
2899 you
.seen_armour
[item
.sub_type
] |= 1 << SP_UNKNOWN_BRAND
;
2902 // major hack. Deconstify should be safe here, but it's still repulsive.
2903 if (you
.religion
== GOD_ASHENZARI
)
2904 ((item_def
*)&item
)->flags
|= ISFLAG_KNOW_CURSE
;