Code cleanup
[crawl.git] / crawl-ref / source / itemprop.cc
blobc852a0d052ebf6048a635614145d7653d52332fd
1 /*
2 * File: itemprop.h
3 * Summary: Misc functions.
4 * Written by: Brent Ross
5 */
7 #include "AppHdr.h"
9 #include "itemname.h"
11 #include <ctype.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <stdio.h>
16 #include "externs.h"
18 #include "artefact.h"
19 #include "coord.h"
20 #include "coordit.h"
21 #include "decks.h"
22 #include "describe.h"
23 #include "food.h"
24 #include "godpassive.h"
25 #include "invent.h"
26 #include "items.h"
27 #include "itemprop.h"
28 #include "mon-util.h"
29 #include "mon-stuff.h"
30 #include "notes.h"
31 #include "options.h"
32 #include "player.h"
33 #include "religion.h"
34 #include "quiver.h"
35 #include "random.h"
36 #include "shopping.h"
37 #include "stuff.h"
38 #include "xom.h"
41 // XXX: Name strings in most of the following are currently unused!
42 struct armour_def
44 armour_type id;
45 const char *name;
46 int ac;
47 int ev;
48 int mass;
50 bool light;
51 equipment_type slot;
52 size_type fit_min;
53 size_type fit_max;
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 },
158 struct weapon_def
160 int id;
161 const char *name;
162 int dam;
163 int hit;
164 int speed;
165 int mass;
166 int str_weight;
168 skill_type skill;
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
172 bool throwable;
174 int dam_type;
175 int acquire_weight;
178 static int Weapon_index[NUM_WEAPONS];
179 static weapon_def Weapon_prop[NUM_WEAPONS] =
181 // Maces & Flails
182 { WPN_CLUB, "club", 5, 3, 13, 50, 7,
183 SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, true,
184 DAMV_CRUSHING, 0 },
185 { WPN_WHIP, "whip", 6, 2, 11, 30, 2,
186 SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
187 DAMV_SLASHING, 0 },
188 { WPN_HAMMER, "hammer", 7, 3, 13, 90, 7,
189 SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false,
190 DAMV_CRUSHING, 0 },
191 { WPN_MACE, "mace", 8, 3, 14, 120, 8,
192 SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false,
193 DAMV_CRUSHING, 10 },
194 { WPN_FLAIL, "flail", 9, 2, 15, 130, 8,
195 SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false,
196 DAMV_CRUSHING, 10 },
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,
205 DAMV_SLASHING, 2 },
206 { WPN_SACRED_SCOURGE, "sacred scourge", 13, 0, 11, 30, 2,
207 SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
208 DAMV_SLASHING, 0 },
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,
220 DAMV_CRUSHING, 10 },
221 { WPN_GIANT_CLUB, "giant club", 20, -6, 17, 330, 10,
222 SK_MACES_FLAILS, HANDS_TWO, SIZE_BIG, MI_NONE, false,
223 DAMV_CRUSHING, 10 },
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 },
228 // Short Blades
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 },
245 // Long Blades
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,
254 DAMV_SLICING, 10 },
255 { WPN_BLESSED_LONG_SWORD, "blessed long sword", 12, 0, 12, 160, 3,
256 SK_LONG_BLADES, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
257 DAMV_SLICING, 10 },
258 { WPN_SCIMITAR, "scimitar", 11, -1, 14, 170, 3,
259 SK_LONG_BLADES, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
260 DAMV_SLICING, 10 },
261 { WPN_BLESSED_SCIMITAR, "blessed scimitar", 13, -1, 13, 170, 3,
262 SK_LONG_BLADES, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
263 DAMV_SLICING, 10 },
264 { WPN_KATANA, "katana", 14, 3, 12, 160, 3,
265 SK_LONG_BLADES, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
266 DAMV_SLICING, 2 },
267 { WPN_BLESSED_KATANA, "blessed katana", 15, 2, 12, 160, 3,
268 SK_LONG_BLADES, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
269 DAMV_SLICING, 2 },
270 { WPN_DEMON_BLADE, "demon blade", 13, -1, 15, 200, 4,
271 SK_LONG_BLADES, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
272 DAMV_SLICING, 2 },
273 { WPN_EUDEMON_BLADE, "eudemon blade", 14, -2, 14, 200, 4,
274 SK_LONG_BLADES, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
275 DAMV_SLICING, 0 },
276 { WPN_DOUBLE_SWORD, "double sword", 16, -1, 15, 220, 5,
277 SK_LONG_BLADES, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
278 DAMV_SLICING, 2 },
279 { WPN_BLESSED_DOUBLE_SWORD, "blessed double sword", 16, -1, 14, 220, 5,
280 SK_LONG_BLADES, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
281 DAMV_SLICING, 2 },
282 { WPN_GREAT_SWORD, "great sword", 16, -3, 17, 250, 6,
283 SK_LONG_BLADES, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
284 DAMV_SLICING, 10 },
285 { WPN_BLESSED_GREAT_SWORD, "blessed great sword", 17, -3, 17, 250, 6,
286 SK_LONG_BLADES, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
287 DAMV_SLICING, 10 },
288 { WPN_TRIPLE_SWORD, "triple sword", 19, -4, 19, 260, 6,
289 SK_LONG_BLADES, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
290 DAMV_SLICING, 2 },
291 { WPN_BLESSED_TRIPLE_SWORD, "blessed triple sword", 19, -4, 18, 260, 6,
292 SK_LONG_BLADES, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
293 DAMV_SLICING, 2 },
295 // Axes
296 { WPN_HAND_AXE, "hand axe", 7, 3, 13, 80, 6,
297 SK_AXES, HANDS_ONE, SIZE_SMALL, MI_NONE, true,
298 DAMV_CHOPPING, 10 },
299 { WPN_WAR_AXE, "war axe", 11, 0, 16, 180, 7,
300 SK_AXES, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
301 DAMV_CHOPPING, 10 },
302 { WPN_BROAD_AXE, "broad axe", 14, -2, 16, 230, 8,
303 SK_AXES, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
304 DAMV_CHOPPING, 10 },
305 { WPN_BATTLEAXE, "battleaxe", 17, -4, 18, 250, 8,
306 SK_AXES, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
307 DAMV_CHOPPING, 10 },
308 { WPN_EXECUTIONERS_AXE, "executioner\'s axe", 20, -6, 20, 280, 9,
309 SK_AXES, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
310 DAMV_CHOPPING, 2 },
312 // Polearms
313 { WPN_SPEAR, "spear", 7, 4, 11, 50, 3,
314 SK_POLEARMS, HANDS_HALF, SIZE_SMALL, MI_NONE, true,
315 DAMV_PIERCING, 10 },
316 { WPN_TRIDENT, "trident", 10, 3, 13, 160, 4,
317 SK_POLEARMS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
318 DAMV_PIERCING, 10 },
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,
324 DAMV_SLICING, 10 },
325 { WPN_DEMON_TRIDENT, "demon trident", 14, 1, 13, 160, 4,
326 SK_POLEARMS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
327 DAMV_PIERCING, 2 },
328 { WPN_TRISHULA, "trishula", 15, 0, 13, 160, 4,
329 SK_POLEARMS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
330 DAMV_PIERCING, 0 },
331 { WPN_GLAIVE, "glaive", 15, -3, 18, 200, 6,
332 SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
333 DAMV_CHOPPING, 10 },
334 { WPN_BARDICHE, "bardiche", 18, -6, 20, 200, 8,
335 SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
336 DAMV_CHOPPING, 2 },
338 // Staves
339 { WPN_QUARTERSTAFF, "quarterstaff", 7, 6, 12, 180, 7,
340 SK_STAVES, HANDS_DOUBLE, SIZE_LARGE, MI_NONE, false,
341 DAMV_CRUSHING, 10 },
342 { WPN_LAJATANG, "lajatang", 14, -3, 14, 200, 3,
343 SK_STAVES, HANDS_DOUBLE, SIZE_LARGE, MI_NONE, false,
344 DAMV_SLICING, 2 },
346 // Range weapons
347 // Notes:
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,
354 DAMV_NON_MELEE, 0 },
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 },
369 struct missile_def
371 int id;
372 const char *name;
373 int dam;
374 int mass;
375 bool throwable;
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 },
392 enum food_flag_type
394 FFL_NONE = 0x00,
395 FFL_FRUIT = 0x01,
398 struct food_def
400 int id;
401 const char *name;
402 int value;
403 int carn_mod;
404 int herb_mod;
405 int mass;
406 int turns;
407 uint32_t flags;
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);
456 int i;
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)
491 // Already cursed?
492 if (item.flags & ISFLAG_CURSED)
493 return;
495 // Holy wrath weapons cannot be cursed.
496 if (item.base_type == OBJ_WEAPONS
497 && get_weapon_brand(item) == SPWPN_HOLY_WRATH)
499 if (!quiet)
501 mprf("Your %s glows black briefly, but repels the curse.",
502 item.name(DESC_PLAIN).c_str());
504 return;
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))
511 if (!quiet)
513 mprf("Your %s glows black briefly, but repels the curse.",
514 item.name(DESC_PLAIN).c_str());
516 return;
519 if (!quiet)
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))
535 int amusement = 64;
537 if (item_is_equipped(item))
539 amusement *= 2;
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))
547 amusement *= 2;
549 else if (you.equip[EQ_WEAPON] == item.link)
551 // Redraw the weapon.
552 you.wield_change = true;
554 ash_check_bondage();
555 ash_id_inventory();
557 xom_is_stimulated(amusement);
561 void do_uncurse_item(item_def &item, bool inscribe, bool no_ash)
563 if (!item.cursed())
565 item.flags &= ~ISFLAG_SEEN_CURSED;
566 if (in_inventory(item))
567 item.flags |= ISFLAG_KNOW_CURSE;
568 return;
571 if (no_ash && you.religion == GOD_ASHENZARI)
573 simple_god_message(" preserves the curse.");
574 return;
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);
597 ash_check_bondage();
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)
604 item.plus2 = 1;
607 void remove_item_stationary(item_def &item)
609 if (item.base_type == OBJ_MISSILES && item.sub_type == MI_THROWING_NET)
610 item.plus2 = 0;
613 bool item_is_stationary(const item_def &item)
615 return (item.base_type == OBJ_MISSILES
616 && item.sub_type == MI_THROWING_NET
617 && item.plus2);
620 bool _is_affordable(const item_def &item)
622 // Temp items never count.
623 if (item.flags & ISFLAG_SUMMONED)
624 return false;
626 // Already in our grubby mitts.
627 if (in_inventory(item))
628 return true;
630 // Disregard shop stuff above your reach.
631 if (in_shop(item))
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))
639 return true;
640 dprf("Seen item %s seems to be un(easily)obtainable.",
641 item.name(DESC_PLAIN).c_str());
642 return false;
645 // A monster has it. Violence is the answer.
646 return true;
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)
662 item.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)
718 case OBJ_FOOD:
719 case OBJ_CORPSES:
720 flagset = 0;
721 break;
722 case OBJ_MISCELLANY:
723 if (item.sub_type == MISC_RUNE_OF_ZOT)
724 flagset = 0;
725 else
726 flagset = ISFLAG_KNOW_TYPE;
727 break;
728 case OBJ_BOOKS:
729 case OBJ_ORBS:
730 case OBJ_SCROLLS:
731 case OBJ_POTIONS:
732 flagset = ISFLAG_KNOW_TYPE;
733 break;
734 case OBJ_STAVES:
735 if (item_is_rod(item))
736 flagset = ISFLAG_KNOW_TYPE | ISFLAG_KNOW_PLUSES;
737 else
738 flagset = ISFLAG_KNOW_TYPE;
739 break;
740 case OBJ_WANDS:
741 flagset = (ISFLAG_KNOW_TYPE | ISFLAG_KNOW_PLUSES);
742 break;
743 case OBJ_JEWELLERY:
744 flagset = (ISFLAG_KNOW_CURSE | ISFLAG_KNOW_TYPE);
745 if (ring_has_pluses(item))
746 flagset |= ISFLAG_KNOW_PLUSES;
747 break;
748 case OBJ_MISSILES:
749 flagset = ISFLAG_KNOW_PLUSES | ISFLAG_KNOW_TYPE;
750 if (get_ammo_brand(item) == SPMSL_NORMAL)
751 flagset &= ~ISFLAG_KNOW_TYPE;
752 break;
753 case OBJ_WEAPONS:
754 case OBJ_ARMOUR:
755 // All flags necessary for full identification.
756 default:
757 break;
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;
766 return flagset;
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)
794 case OBJ_WEAPONS:
795 if (item.sub_type > WPN_MAX_RACIAL)
796 return;
797 break;
799 case OBJ_ARMOUR:
800 if (item.sub_type > ARM_MAX_RACIAL)
801 return;
802 break;
804 case OBJ_MISSILES:
805 if (item.sub_type > MI_MAX_RACIAL)
806 return;
807 break;
809 default:
810 return;
813 // check that item is appropriate for racial type
814 switch (flags)
816 case ISFLAG_ELVEN:
817 switch (item.base_type)
819 case OBJ_WEAPONS:
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)
832 return;
834 break;
835 case OBJ_ARMOUR:
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))
841 return;
843 break;
844 case OBJ_MISSILES:
845 if (item.sub_type == MI_BOLT)
846 return;
847 break;
848 default:
849 break;
851 break;
853 case ISFLAG_DWARVEN:
854 switch (item.base_type)
856 case OBJ_WEAPONS:
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)
868 return;
870 break;
871 case OBJ_ARMOUR:
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))
876 return;
878 break;
879 case OBJ_MISSILES:
880 if (item.sub_type == MI_NEEDLE
881 || item.sub_type == MI_ARROW
882 || item.sub_type == MI_JAVELIN)
884 return;
886 break;
887 default:
888 break;
890 break;
892 case ISFLAG_ORCISH:
893 switch (item.base_type)
895 case OBJ_WEAPONS:
896 if (item.sub_type == WPN_QUICK_BLADE
897 || item.sub_type == WPN_LONGBOW)
899 return;
901 break;
902 case OBJ_ARMOUR:
903 if (get_armour_slot(item) == EQ_HELMET && !is_hard_helmet(item)
904 && item.sub_type != ARM_WIZARD_HAT)
906 return;
908 break;
909 default:
910 break;
913 default:
914 break;
917 item.flags &= ~ISFLAG_RACIAL_MASK; // delete previous
918 item.flags |= flags;
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
926 item.flags |= flags;
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));
936 return item.plus2;
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;
946 item.plus2 = type;
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);
965 else
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);
973 return item.plus2;
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;
993 return (true);
996 return (false);
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)
1053 return (false);
1055 switch (item.sub_type)
1057 default:
1058 return (false);
1060 case ARM_DRAGON_HIDE:
1061 item.sub_type = ARM_DRAGON_ARMOUR;
1062 break;
1064 case ARM_TROLL_HIDE:
1065 item.sub_type = ARM_TROLL_LEATHER_ARMOUR;
1066 break;
1068 case ARM_ICE_DRAGON_HIDE:
1069 item.sub_type = ARM_ICE_DRAGON_ARMOUR;
1070 break;
1072 case ARM_MOTTLED_DRAGON_HIDE:
1073 item.sub_type = ARM_MOTTLED_DRAGON_ARMOUR;
1074 break;
1076 case ARM_STORM_DRAGON_HIDE:
1077 item.sub_type = ARM_STORM_DRAGON_ARMOUR;
1078 break;
1080 case ARM_GOLD_DRAGON_HIDE:
1081 item.sub_type = ARM_GOLD_DRAGON_ARMOUR;
1082 break;
1084 case ARM_SWAMP_DRAGON_HIDE:
1085 item.sub_type = ARM_SWAMP_DRAGON_ARMOUR;
1086 break;
1088 case ARM_STEAM_DRAGON_HIDE:
1089 item.sub_type = ARM_STEAM_DRAGON_ARMOUR;
1090 break;
1092 case ARM_PEARL_DRAGON_HIDE:
1093 item.sub_type = ARM_PEARL_DRAGON_ARMOUR;
1094 break;
1097 return (true);
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)
1116 max_plus = 3;
1118 return (max_plus);
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:
1137 return (inc_made);
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:
1148 return (true);
1150 default:
1151 break;
1154 return (false);
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;
1198 if (size < min)
1199 return (min - size); // -'ve means levels too small
1200 else if (size > max)
1201 return (max - size); // +'ve means levels too large
1203 return (0);
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)
1222 if (!hide_charged)
1223 return (true);
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))
1230 return (false);
1232 return (true);
1234 else if (item_is_rod(it))
1236 if (!hide_charged)
1237 return (true);
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);
1246 return (true);
1249 return (false);
1252 int wand_charge_value(int type)
1254 switch (type)
1256 case WAND_INVISIBILITY:
1257 case WAND_FIREBALL:
1258 case WAND_TELEPORTATION:
1259 case WAND_HEALING:
1260 case WAND_HASTING:
1261 return 3;
1263 case WAND_LIGHTNING:
1264 case WAND_DRAINING:
1265 return 4;
1267 case WAND_FIRE:
1268 case WAND_COLD:
1269 return 5;
1271 default:
1272 return 8;
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)
1287 return (false);
1290 if (uncurse && wpn.cursed() && you.religion != GOD_ASHENZARI)
1291 return true;
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)
1296 return false;
1298 // Artefacts or highly enchanted weapons cannot be enchanted,
1299 // only uncursed.
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)
1306 return (false);
1309 // Highly enchanted missiles, which have only one stat, cannot be
1310 // enchanted or uncursed, since missiles cannot be artefacts or
1311 // cursed.
1312 else if (wpn.plus >= MAX_WPN_ENCHANT)
1313 return (false);
1315 return (true);
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)
1323 return (false);
1325 // Melded armour cannot be enchanted.
1326 if (item_is_melded(arm))
1327 return (false);
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))
1333 return (true);
1336 // Artefacts or highly enchanted armour cannot be enchanted, only
1337 // uncursed.
1338 if (is_artefact(arm) || arm.plus >= armour_max_enchant(arm))
1339 return (uncurse && arm.cursed() && you.religion != GOD_ASHENZARI);
1341 return (true);
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)
1352 switch (w_type)
1354 case WPN_CLUB:
1355 case WPN_DAGGER:
1356 return (10);
1358 case WPN_HAND_AXE:
1359 case WPN_MACE:
1360 case WPN_QUARTERSTAFF:
1361 return (9);
1363 case WPN_BOW:
1364 case WPN_FLAIL:
1365 case WPN_HAMMER:
1366 case WPN_SABRE:
1367 case WPN_SHORT_SWORD:
1368 case WPN_SLING:
1369 case WPN_SPEAR:
1370 return (8);
1372 case WPN_FALCHION:
1373 case WPN_LONG_SWORD:
1374 case WPN_MORNINGSTAR:
1375 case WPN_WAR_AXE:
1376 return (7);
1378 case WPN_BATTLEAXE:
1379 case WPN_CROSSBOW:
1380 case WPN_GREAT_SWORD:
1381 case WPN_SCIMITAR:
1382 case WPN_TRIDENT:
1383 return (6);
1385 case WPN_GLAIVE:
1386 case WPN_HALBERD:
1387 case WPN_BLOWGUN:
1388 return (5);
1390 case WPN_BROAD_AXE:
1391 case WPN_SPIKED_FLAIL:
1392 case WPN_WHIP:
1393 return (4);
1395 case WPN_GREAT_MACE:
1396 return (3);
1398 case WPN_ANKUS:
1399 case WPN_DIRE_FLAIL:
1400 case WPN_SCYTHE:
1401 case WPN_LONGBOW:
1402 case WPN_LAJATANG:
1403 return (2);
1405 case WPN_GIANT_CLUB:
1406 case WPN_GIANT_SPIKED_CLUB:
1407 case WPN_BARDICHE:
1408 return (1);
1410 case WPN_DOUBLE_SWORD:
1411 case WPN_EVENINGSTAR:
1412 case WPN_EXECUTIONERS_AXE:
1413 case WPN_KATANA:
1414 case WPN_KNIFE:
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:
1429 case WPN_TRISHULA:
1430 // Zero value weapons must be placed specially -- see make_item() {dlb}
1431 return (0);
1433 default:
1434 break;
1437 return (0);
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);
1447 return (ret);
1450 int get_damage_type(const item_def &item)
1452 int ret = DAM_BASH;
1454 if (item_is_rod(item))
1455 ret = DAM_BLUDGEON;
1456 if (item.base_type == OBJ_WEAPONS)
1457 ret = (Weapon_prop[Weapon_index[item.sub_type]].dam_type & DAM_MASK);
1459 return (ret);
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);
1471 if (ret > 0)
1473 int count = 0;
1475 for (int i = 1; i <= DAM_MAX_TYPE; i <<= 1)
1477 if (!does_damage_type(item, i))
1478 continue;
1480 if (one_chance_in(++count))
1481 ret = i;
1485 return (ret);
1488 hands_reqd_type hands_reqd(object_class_type base_type, int sub_type,
1489 size_type size)
1491 item_def item;
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;
1501 int fit;
1502 bool doub = false;
1504 switch (item.base_type)
1506 case OBJ_STAVES:
1507 case OBJ_WEAPONS:
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)
1515 ret = HANDS_TWO;
1516 else if (size > SIZE_LARGE)
1517 ret = HANDS_ONE;
1518 else
1519 ret = HANDS_HALF;
1520 break;
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)
1528 doub = true;
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)
1554 ret += fit;
1555 else if (size > SIZE_MEDIUM && fit < 0)
1556 ret += (fit + doub);
1558 break;
1560 case OBJ_CORPSES: // unwieldy
1561 ret = HANDS_TWO;
1562 break;
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)
1569 ret = HANDS_TWO;
1571 break;
1573 default:
1574 break;
1577 if (ret > HANDS_TWO)
1578 ret = HANDS_TWO;
1579 else if (ret < HANDS_ONE)
1580 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:
1594 return (true);
1596 default:
1597 break;
1601 return (false);
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:
1619 case WPN_TRISHULA:
1620 return (true);
1622 default:
1623 break;
1627 return (false);
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)
1643 return (false);
1645 switch (item.sub_type)
1647 default:
1648 return (false);
1650 case WPN_FALCHION:
1651 if (!allow_blessed)
1652 return (false);
1653 item.sub_type = WPN_BLESSED_FALCHION;
1654 break;
1656 case WPN_LONG_SWORD:
1657 if (!allow_blessed)
1658 return (false);
1659 item.sub_type = WPN_BLESSED_LONG_SWORD;
1660 break;
1662 case WPN_SCIMITAR:
1663 if (!allow_blessed)
1664 return (false);
1665 item.sub_type = WPN_BLESSED_SCIMITAR;
1666 break;
1668 case WPN_DEMON_BLADE:
1669 if (!allow_blessed)
1670 item.sub_type = WPN_SCIMITAR;
1671 else
1672 item.sub_type = WPN_EUDEMON_BLADE;
1673 break;
1675 case WPN_KATANA:
1676 if (!allow_blessed)
1677 return (false);
1678 item.sub_type = WPN_BLESSED_KATANA;
1679 break;
1681 case WPN_DOUBLE_SWORD:
1682 if (!allow_blessed)
1683 return (false);
1684 item.sub_type = WPN_BLESSED_DOUBLE_SWORD;
1685 break;
1687 case WPN_GREAT_SWORD:
1688 if (!allow_blessed)
1689 return (false);
1690 item.sub_type = WPN_BLESSED_GREAT_SWORD;
1691 break;
1693 case WPN_TRIPLE_SWORD:
1694 if (!allow_blessed)
1695 return (false);
1696 item.sub_type = WPN_BLESSED_TRIPLE_SWORD;
1697 break;
1699 case WPN_DEMON_WHIP:
1700 if (!allow_blessed)
1701 item.sub_type = WPN_WHIP;
1702 else
1703 item.sub_type = WPN_SACRED_SCOURGE;
1704 break;
1706 case WPN_DEMON_TRIDENT:
1707 if (!allow_blessed)
1708 item.sub_type = WPN_TRIDENT;
1709 else
1710 item.sub_type = WPN_TRISHULA;
1711 break;
1714 if (is_blessed(item))
1715 item.flags &= ~ISFLAG_RACIAL_MASK;
1717 return (true);
1720 bool convert2bad(item_def &item)
1722 if (item.base_type != OBJ_WEAPONS)
1723 return (false);
1725 switch (item.sub_type)
1727 default:
1728 return (false);
1730 case WPN_BLESSED_FALCHION:
1731 item.sub_type = WPN_FALCHION;
1732 break;
1734 case WPN_BLESSED_LONG_SWORD:
1735 item.sub_type = WPN_LONG_SWORD;
1736 break;
1738 case WPN_BLESSED_SCIMITAR:
1739 item.sub_type = WPN_SCIMITAR;
1740 break;
1742 case WPN_EUDEMON_BLADE:
1743 item.sub_type = WPN_DEMON_BLADE;
1744 break;
1746 case WPN_BLESSED_KATANA:
1747 item.sub_type = WPN_KATANA;
1748 break;
1750 case WPN_BLESSED_DOUBLE_SWORD:
1751 item.sub_type = WPN_DOUBLE_SWORD;
1752 break;
1754 case WPN_BLESSED_GREAT_SWORD:
1755 item.sub_type = WPN_GREAT_SWORD;
1756 break;
1758 case WPN_BLESSED_TRIPLE_SWORD:
1759 item.sub_type = WPN_TRIPLE_SWORD;
1760 break;
1762 case WPN_SACRED_SCOURGE:
1763 item.sub_type = WPN_DEMON_WHIP;
1764 break;
1766 case WPN_TRISHULA:
1767 item.sub_type = WPN_DEMON_TRIDENT;
1768 break;
1771 return (true);
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)
1797 return (SK_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)
1806 item_def wpn;
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);
1825 default: break;
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)
1835 item_def wpn;
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,
1847 bool hide_hidden)
1849 ASSERT(wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES);
1851 int ret = 0;
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)
1863 ret += 1;
1866 // Only consider additional modifications if we have a positive base:
1867 if (ret > 0)
1869 // Size factors:
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)
1875 ret += 1;
1877 // apply skill (and dividing by 2)
1878 ret = (ret * (skill + 10)) / 20;
1880 // Make sure things can't get too insane.
1881 if (ret > 8)
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 :
1925 (ret > -6) ? 0
1926 : ret + 5);
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)
1936 return (true);
1938 int fit = fit_weapon_wieldable_size(item, size);
1940 // Adjust fit for size.
1941 if (size < SIZE_SMALL && fit > 0)
1942 fit--;
1943 else if (size > SIZE_LARGE && fit < 0)
1944 fit++;
1946 return (fit == 0);
1950 // Launcher and ammo functions:
1952 missile_type fires_ammo_type(const item_def &item)
1954 if (item.base_type != OBJ_WEAPONS)
1955 return (MI_NONE);
1957 return (Weapon_prop[Weapon_index[item.sub_type]].ammo);
1960 missile_type fires_ammo_type(weapon_type wtype)
1962 item_def wpn;
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)
1976 item_def wpn;
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)
2014 if (!force)
2016 if ((bodysize < SIZE_LARGE
2017 || !actor->can_throw_large_rocks())
2018 && wpn.sub_type == MI_LARGE_ROCK)
2020 return (false);
2023 if (bodysize < SIZE_MEDIUM
2024 && (wpn.sub_type == MI_JAVELIN
2025 || wpn.sub_type == MI_THROWING_NET))
2027 return (false);
2031 return (Missile_prop[Missile_index[wpn.sub_type]].throwable);
2034 return (false);
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
2042 && launcher
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));
2065 // Macguffins
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);
2099 // Ring functions:
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))
2108 return (0);
2110 switch (item.sub_type)
2112 case RING_SLAYING:
2113 return (2);
2115 case RING_PROTECTION:
2116 case RING_EVASION:
2117 case RING_STRENGTH:
2118 case RING_INTELLIGENCE:
2119 case RING_DEXTERITY:
2120 return (1);
2122 default:
2123 break;
2126 return (0);
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))
2137 return (false);
2139 if (ring_has_pluses(item))
2140 return (true);
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:
2148 case RING_WIZARDRY:
2149 case RING_FIRE:
2150 case RING_ICE:
2151 return (true);
2153 default:
2154 break;
2157 return (false);
2161 // Food functions:
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)
2178 return (false);
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)
2187 return (false);
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)
2226 return (false);
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);
2259 int res = 0;
2261 // intrinsic armour abilities
2262 switch (arm.sub_type)
2264 case ARM_DRAGON_ARMOUR:
2265 case ARM_DRAGON_HIDE:
2266 res += 2;
2267 break;
2268 case ARM_GOLD_DRAGON_ARMOUR:
2269 case ARM_GOLD_DRAGON_HIDE:
2270 res += 1;
2271 break;
2272 case ARM_ICE_DRAGON_ARMOUR:
2273 case ARM_ICE_DRAGON_HIDE:
2274 res -= 1;
2275 break;
2276 default:
2277 break;
2280 // check ego resistance
2281 const int ego = get_armour_ego_type(arm);
2282 if (ego == SPARM_FIRE_RESISTANCE || ego == SPARM_RESISTANCE)
2283 res += 1;
2285 if (check_artp && is_artefact(arm))
2286 res += artefact_wpn_property(arm, ARTP_FIRE);
2288 return (res);
2291 int get_armour_res_cold(const item_def &arm, bool check_artp)
2293 ASSERT(arm.base_type == OBJ_ARMOUR);
2295 int res = 0;
2297 // intrinsic armour abilities
2298 switch (arm.sub_type)
2300 case ARM_ICE_DRAGON_ARMOUR:
2301 case ARM_ICE_DRAGON_HIDE:
2302 res += 2;
2303 break;
2304 case ARM_GOLD_DRAGON_ARMOUR:
2305 case ARM_GOLD_DRAGON_HIDE:
2306 res += 1;
2307 break;
2308 case ARM_DRAGON_ARMOUR:
2309 case ARM_DRAGON_HIDE:
2310 res -= 1;
2311 break;
2312 default:
2313 break;
2316 // check ego resistance
2317 const int ego = get_armour_ego_type(arm);
2318 if (ego == SPARM_COLD_RESISTANCE || ego == SPARM_RESISTANCE)
2319 res += 1;
2321 if (check_artp && is_artefact(arm))
2322 res += artefact_wpn_property(arm, ARTP_COLD);
2324 return (res);
2327 int get_armour_res_poison(const item_def &arm, bool check_artp)
2329 ASSERT(arm.base_type == OBJ_ARMOUR);
2331 int res = 0;
2333 // intrinsic armour abilities
2334 switch (arm.sub_type)
2336 case ARM_SWAMP_DRAGON_ARMOUR:
2337 case ARM_SWAMP_DRAGON_HIDE:
2338 res += 1;
2339 break;
2340 case ARM_GOLD_DRAGON_ARMOUR:
2341 case ARM_GOLD_DRAGON_HIDE:
2342 res += 1;
2343 break;
2344 default:
2345 break;
2348 // check ego resistance
2349 if (get_armour_ego_type(arm) == SPARM_POISON_RESISTANCE)
2350 res += 1;
2352 if (check_artp && is_artefact(arm))
2353 res += artefact_wpn_property(arm, ARTP_POISON);
2355 return (res);
2358 int get_armour_res_elec(const item_def &arm, bool check_artp)
2360 ASSERT(arm.base_type == OBJ_ARMOUR);
2362 int res = 0;
2364 // intrinsic armour abilities
2365 switch (arm.sub_type)
2367 case ARM_STORM_DRAGON_ARMOUR:
2368 case ARM_STORM_DRAGON_HIDE:
2369 res += 1;
2370 break;
2371 default:
2372 break;
2375 if (check_artp && is_artefact(arm))
2376 res += artefact_wpn_property(arm, ARTP_ELECTRICITY);
2378 return (res);
2381 int get_armour_life_protection(const item_def &arm, bool check_artp)
2383 ASSERT(arm.base_type == OBJ_ARMOUR);
2385 int res = 0;
2387 // Pearl dragon armour grants rN+.
2388 if (arm.sub_type == ARM_PEARL_DRAGON_ARMOUR)
2389 res += 1;
2391 // check for ego resistance
2392 if (get_armour_ego_type(arm) == SPARM_POSITIVE_ENERGY)
2393 res += 1;
2395 if (check_artp && is_artefact(arm))
2396 res += artefact_wpn_property(arm, ARTP_NEGATIVE_ENERGY);
2398 return (res);
2401 int get_armour_res_magic(const item_def &arm, bool check_artp)
2403 ASSERT(arm.base_type == OBJ_ARMOUR);
2405 int res = 0;
2407 // check for ego resistance
2408 if (get_armour_ego_type(arm) == SPARM_MAGIC_RESISTANCE)
2409 res += 30;
2411 if (check_artp && is_artefact(arm))
2412 res += artefact_wpn_property(arm, ARTP_MAGIC);
2414 return (res);
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)
2423 return (true);
2425 if (check_artp && is_artefact(arm))
2426 return artefact_wpn_property(arm, ARTP_EYESIGHT);
2428 return (false);
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:
2440 return 1;
2441 default:
2442 return 0;
2446 int property(const item_def &item, int prop_type)
2448 weapon_type weapon_sub;
2450 switch (item.base_type)
2452 case OBJ_ARMOUR:
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);
2457 break;
2459 case OBJ_WEAPONS:
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);
2468 break;
2470 case OBJ_MISSILES:
2471 if (prop_type == PWPN_DAMAGE)
2472 return (Missile_prop[ Missile_index[item.sub_type] ].dam);
2473 break;
2475 case OBJ_STAVES:
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);
2484 break;
2486 default:
2487 break;
2490 return (0);
2493 // Returns true if item is evokable.
2494 bool gives_ability(const item_def &item)
2496 if (!item_type_known(item))
2497 return (false);
2499 switch (item.base_type)
2501 case OBJ_WEAPONS:
2502 break;
2503 case OBJ_JEWELLERY:
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)
2510 return (true);
2513 else
2515 if (item.sub_type == AMU_RAGE)
2516 return (true);
2518 break;
2519 case OBJ_ARMOUR:
2521 const equipment_type eq = get_armour_slot(item);
2522 if (eq == EQ_NONE)
2523 return (false);
2524 const special_armour_type ego = get_armour_ego_type(item);
2526 if (ego == SPARM_DARKNESS || ego == SPARM_LEVITATION)
2527 return (true);
2528 break;
2530 default:
2531 return (false);
2534 if (!is_artefact(item))
2535 return (false);
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)))
2540 return (true);
2542 return (false);
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))
2549 return (false);
2551 switch (item.base_type)
2553 case OBJ_WEAPONS:
2554 break;
2555 case OBJ_JEWELLERY:
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)
2565 return (true);
2568 else
2570 if (item.sub_type != AMU_RAGE && item.sub_type != AMU_INACCURACY)
2571 return (true);
2573 break;
2574 case OBJ_ARMOUR:
2576 const equipment_type eq = get_armour_slot(item);
2577 if (eq == EQ_NONE)
2578 return (false);
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)
2584 return (true);
2586 break;
2588 case OBJ_STAVES:
2589 if (item.sub_type >= STAFF_FIRE && item.sub_type <= STAFF_POISON
2590 || item.sub_type == STAFF_AIR)
2592 return (true);
2594 return (false);
2595 default:
2596 return (false);
2599 if (!is_artefact(item))
2600 return (false);
2602 // Check for randart resistances.
2603 for (int rap = ARTP_FIRE; rap <= ARTP_BERSERK; rap++)
2605 if (rap == ARTP_MAGIC || rap >= ARTP_INVISIBLE)
2606 continue;
2608 if (artefact_wpn_property(item, static_cast<artefact_prop_type>(rap)))
2609 return (true);
2612 return (false);
2615 int item_mass(const item_def &item)
2617 int unit_mass = 0;
2619 switch (item.base_type)
2621 case OBJ_WEAPONS:
2622 unit_mass = Weapon_prop[ Weapon_index[item.sub_type] ].mass;
2623 break;
2625 case OBJ_ARMOUR:
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);
2636 break;
2638 case OBJ_MISSILES:
2640 unit_mass = Missile_prop[ Missile_index[item.sub_type] ].mass;
2641 int brand = get_ammo_brand(item);
2643 if (brand == SPMSL_SILVER)
2644 unit_mass *= 2;
2645 else if (brand == SPMSL_STEEL)
2646 unit_mass *= 3;
2647 break;
2650 case OBJ_FOOD:
2651 unit_mass = Food_prop[ Food_index[item.sub_type] ].mass;
2652 break;
2654 case OBJ_WANDS:
2655 unit_mass = 100;
2656 break;
2658 case OBJ_SCROLLS:
2659 unit_mass = 20;
2660 break;
2662 case OBJ_JEWELLERY:
2663 unit_mass = 10;
2664 break;
2666 case OBJ_POTIONS:
2667 unit_mass = 40;
2668 break;
2670 case OBJ_BOOKS:
2671 unit_mass = 70;
2672 break;
2674 case OBJ_STAVES:
2675 unit_mass = 130;
2676 break;
2678 case OBJ_ORBS:
2679 unit_mass = 300;
2680 break;
2682 case OBJ_MISCELLANY:
2683 if (is_deck(item))
2685 unit_mass = 50;
2686 break;
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:
2694 unit_mass = 150;
2695 break;
2697 default:
2698 unit_mass = 100;
2699 break;
2701 break;
2703 case OBJ_CORPSES:
2704 unit_mass = mons_weight(item.plus);
2706 if (item.sub_type == CORPSE_SKELETON)
2707 unit_mass /= 10;
2708 break;
2710 default:
2711 case OBJ_GOLD:
2712 unit_mass = 0;
2713 break;
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)
2727 case OBJ_WEAPONS:
2728 case OBJ_STAVES:
2729 size = Weapon_prop[ Weapon_index[item.sub_type] ].fit_size - 1;
2730 break;
2732 case OBJ_ARMOUR:
2733 size = SIZE_MEDIUM;
2735 switch (item.sub_type)
2737 case ARM_GLOVES:
2738 case ARM_HELMET:
2739 case ARM_CAP:
2740 case ARM_WIZARD_HAT:
2741 case ARM_BOOTS:
2742 case ARM_BUCKLER:
2743 // tiny armour
2744 size = SIZE_TINY;
2745 break;
2747 case ARM_SHIELD:
2748 size = SIZE_LITTLE;
2749 break;
2751 case ARM_LARGE_SHIELD:
2752 size = SIZE_SMALL;
2753 break;
2755 default: // Body armours and bardings.
2756 size = SIZE_MEDIUM;
2757 break;
2759 break;
2761 case OBJ_MISSILES:
2762 if (item.sub_type == MI_LARGE_ROCK)
2763 size = SIZE_SMALL;
2764 break;
2766 case OBJ_MISCELLANY:
2767 break;
2769 case OBJ_CORPSES:
2770 // FIXME: This should depend on the original monster's size!
2771 size = SIZE_SMALL;
2772 break;
2774 default: // sundry tiny items
2775 break;
2778 if (size < SIZE_TINY)
2779 size = SIZE_TINY;
2780 else if (size > SIZE_HUGE)
2781 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)
2793 switch(type)
2795 case OBJ_WEAPONS:
2796 case OBJ_STAVES:
2797 case OBJ_MISCELLANY:
2798 return (EQ_WEAPON);
2800 case OBJ_ARMOUR:
2801 return get_armour_slot(static_cast<armour_type>(sub_type));
2803 case OBJ_JEWELLERY:
2804 return (jewellery_is_amulet(sub_type) ? EQ_AMULET : EQ_RINGS);
2806 default:
2807 break;
2810 return (EQ_NONE);
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()))
2825 return (false);
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)
2853 switch (type)
2855 case OBJ_WEAPONS:
2856 return Weapon_prop[Weapon_index[sub_type]].name;
2857 case OBJ_MISSILES:
2858 return Missile_prop[Missile_index[sub_type]].name;
2859 case OBJ_ARMOUR:
2860 return Armour_prop[Armour_index[sub_type]].name;
2861 case OBJ_JEWELLERY:
2862 return (jewellery_is_amulet(sub_type) ? "amulet" : "ring");
2863 default:
2864 return "";
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;