1 /* File: flavor.c */
2 
3 /* Purpose: Object flavor code */
4 
5 /*
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research, and
9  * not for profit purposes provided that this copyright and statement are
10  * included in all such copies.
11  */
12 
13 #include "angband.h"
14 
15 
16 /*
17  * Max sizes of the following arrays
18  */
19 #define MAX_ROCKS      68		/* Used with rings (min 55) */
20 #define MAX_AMULETS    30		/* Used with amulets (min 20) */
21 #define MAX_WOODS      40		/* Used with staffs (min 30) */
22 #define MAX_METALS     39		/* Used with wands/rods (min 30/29) */
23 #define MAX_COLORS     76		/* Used with potions (min 64) */
24 #define MAX_SHROOM     25		/* Used with mushrooms (min 20) */
25 #define MAX_TITLES     54		/* Used with scrolls (min 48) */
26 #define MAX_SYLLABLES 164		/* Used with scrolls (see below) */
27 
28 
29 /*
30  * Rings (adjectives and colors)
31  */
32 
33 static cptr ring_adj[MAX_ROCKS] =
34 {
35 	/* 0-9 */
36 	"Alexandrite", "Amethyst", "Aquamarine", "Azurite", "Beryl",
37 	"Bloodstone", "Calcite", "Carnelian", "Corundum", "Diamond",
38 	/* 10-19 */
39 	"Emerald", "Fluorite", "Garnet", "Granite", "Jade",
40 	"Jasper", "Lapis Lazuli", "Malachite", "Marble", "Moonstone",
41 	/* 20-29 */
42 	"Onyx", "Opal", "Pearl", "Quartz", "Quartzite",
43 	"Rhodonite", "Ruby", "Sapphire", "Tiger Eye", "Topaz",
44 	/* 30-39 */
45 	"Turquoise", "Zircon", "Platinum", "Bronze", "Gold",
46 	"Obsidian", "Silver", "Tortoise Shell", "Mithril", "Jet",
47 	/* 40-49 */
48 	"Engagement", "Adamantite", "Wire", "Dilithium", "Bone",
49 	"Wooden", "Iron", "Serpent", "Wedding", "Double",
50 	/* 50-59 */
51 	"Plain", "Brass", "Scarab", "Shining", "Rusty",
52 	"Transparent", "Cat's-Eye", "Chrysoberyl", "Serpentine", "Spinel",
53 	/* 60-67 */
54 	"Topaz", "Morganite", "Heliodor", "Tourmaline", "Chalcedony",
55 	"Peridot", "Hematite", "Coral"
56 };
57 
58 static byte ring_col[MAX_ROCKS] =
59 {
60 	/* 0-9 */
61 	TERM_GREEN, TERM_VIOLET, TERM_L_BLUE, TERM_L_BLUE, TERM_L_GREEN,
62 	TERM_RED, TERM_WHITE, TERM_RED, TERM_SLATE, TERM_WHITE,
63 	/* 10-19 */
64 	TERM_GREEN, TERM_L_GREEN, TERM_RED, TERM_L_DARK, TERM_L_GREEN,
65 	TERM_UMBER, TERM_BLUE, TERM_GREEN, TERM_WHITE, TERM_L_WHITE,
66 	/* 20-29 */
67 	TERM_L_RED, TERM_L_WHITE, TERM_WHITE, TERM_L_WHITE, TERM_L_WHITE,
68 	TERM_L_RED, TERM_RED, TERM_BLUE, TERM_YELLOW, TERM_YELLOW,
69 	/* 30-39 */
70 	TERM_L_BLUE, TERM_L_UMBER, TERM_WHITE, TERM_L_UMBER, TERM_YELLOW,
71 	TERM_L_DARK, TERM_L_WHITE, TERM_GREEN, TERM_L_BLUE, TERM_L_DARK,
72 	/* 40-49 */
73 	TERM_YELLOW, TERM_VIOLET, TERM_UMBER, TERM_L_WHITE, TERM_WHITE,
74 	TERM_UMBER, TERM_BLUE, TERM_GREEN, TERM_YELLOW, TERM_ORANGE,
75 	/* 50-59 */
76 	TERM_YELLOW, TERM_ORANGE, TERM_L_GREEN, TERM_YELLOW, TERM_RED,
77 	TERM_WHITE, TERM_YELLOW, TERM_YELLOW, TERM_L_GREEN, TERM_RED,
78 	/* 60-67 */
79 	TERM_YELLOW, TERM_L_RED, TERM_YELLOW, TERM_GREEN, TERM_L_DARK,
80 	TERM_L_GREEN, TERM_L_DARK, TERM_L_RED
81 };
82 
83 
84 /*
85  * Amulets (adjectives and colors)
86  */
87 static cptr amulet_adj[MAX_AMULETS] =
88 {
89 	/* 0-9 */
90 	"Amber", "Driftwood", "Coral", "Agate", "Ivory",
91 	"Obsidian", "Bone", "Brass", "Bronze", "Pewter",
92 	/* 10-19 */
93 	"Tortoise Shell", "Golden", "Azure", "Crystal", "Silver",
94 	"Copper", "Rosetted", "Spiral", "Star", "Square",
95 	/* 20-29 */
96 	"Hexagonal", "Steel", "Skull", "Platinum", "Electrum",
97 	"Glass", "Cracked", "Heartwood", "Bark", "Mirrored"
98 };
99 
100 static byte amulet_col[MAX_AMULETS] =
101 {
102 	/* 0-9 */
103 	TERM_YELLOW, TERM_L_UMBER, TERM_WHITE, TERM_L_WHITE, TERM_WHITE,
104 	TERM_L_DARK, TERM_WHITE, TERM_L_UMBER, TERM_L_UMBER, TERM_SLATE,
105 	/* 10-19 */
106 	TERM_GREEN, TERM_YELLOW, TERM_L_BLUE, TERM_L_BLUE, TERM_L_WHITE,
107 	TERM_L_UMBER, TERM_VIOLET, TERM_VIOLET, TERM_YELLOW, TERM_L_UMBER,
108 	/* 20-29 */
109 	TERM_L_DARK, TERM_WHITE, TERM_L_DARK, TERM_L_WHITE, TERM_WHITE,
110 	TERM_L_RED, TERM_RED, TERM_UMBER, TERM_UMBER, TERM_WHITE
111 };
112 
113 
114 /*
115  * Staffs (adjectives and colors)
116  */
117 static cptr staff_adj[MAX_WOODS] =
118 {
119 	/* 0-9 */
120 	"Aspen", "Balsa", "Banyan", "Birch", "Cedar",
121 	"Cottonwood", "Cypress", "Dogwood", "Elm", "Willow",
122 	/* 10-19 */
123 	"Hemlock", "Hickory", "Ironwood", "Locust", "Mahogany",
124 	"Maple", "Mulberry", "Oak", "Pine", "Redwood",
125 	/* 20-29 */
126 	"Rosewood", "Spruce", "Sycamore", "Teak", "Walnut",
127 	"Mistletoe", "Hawthorn", "Bamboo", "Silver", "Runed",
128 	/* 30-39 */
129 	"Golden", "Ashen", "Gnarled", "Ivory", "Sandalwood",
130 	"Yew", "Thorned", "Charred", "Darkwood", "Flowering"
131 };
132 
133 static byte staff_col[MAX_WOODS] =
134 {
135 	/* 0-9 */
136 	TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER,
137 	TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER,
138 	/* 10-19 */
139 	TERM_L_UMBER, TERM_L_UMBER, TERM_UMBER, TERM_L_UMBER, TERM_UMBER,
140 	TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_RED,
141 	/* 20-29 */
142 	TERM_RED, TERM_L_UMBER, TERM_L_UMBER, TERM_L_UMBER, TERM_UMBER,
143 	TERM_GREEN, TERM_L_UMBER, TERM_L_UMBER, TERM_L_WHITE, TERM_UMBER,
144 	/* 30-39 */
145 	TERM_YELLOW, TERM_SLATE, TERM_UMBER, TERM_L_WHITE, TERM_YELLOW,
146 	TERM_L_UMBER, TERM_L_UMBER, TERM_L_DARK, TERM_L_DARK, TERM_L_GREEN
147 };
148 
149 
150 /*
151  * Wands (adjectives and colors)
152  */
153 static cptr wand_adj[MAX_METALS] =
154 {
155 	/* 0-9 */
156 	"Aluminium", "Cast Iron", "Chromium", "Copper", "Gold",
157 	"Iron", "Magnesium", "Molybdenum", "Nickel", "Rusty",
158 	/* 10-19 */
159 	"Silver", "Steel", "Tin", "Titanium", "Tungsten",
160 	"Zirconium", "Zinc", "Aluminium-Plated", "Copper-Plated", "Gold-Plated",
161 	/* 20-29 */
162 	"Nickel-Plated", "Silver-Plated", "Steel-Plated", "Tin-Plated", "Zinc-Plated",
163 	"Mithril-Plated", "Mithril", "Runed", "Bronze", "Brass",
164 	/* 30-38 */
165 	"Platinum", "Lead", "Lead-Plated", "Ivory", "Adamantite",
166 	"Uridium", "Long", "Short", "Hexagonal"
167 };
168 
169 static byte wand_col[MAX_METALS] =
170 {
171 	/* 0-9 */
172 	TERM_L_BLUE, TERM_L_DARK, TERM_WHITE, TERM_L_UMBER, TERM_YELLOW,
173 	TERM_SLATE, TERM_L_WHITE, TERM_L_WHITE, TERM_L_UMBER, TERM_RED,
174 	/* 10-19 */
175 	TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE, TERM_WHITE, TERM_WHITE,
176 	TERM_L_WHITE, TERM_L_WHITE, TERM_L_BLUE, TERM_L_UMBER, TERM_YELLOW,
177 	/* 20-29 */
178 	TERM_L_UMBER, TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE, TERM_L_WHITE,
179 	TERM_L_BLUE, TERM_L_BLUE, TERM_UMBER, TERM_L_UMBER, TERM_L_UMBER,
180 	/* 30-38 */
181 	TERM_WHITE, TERM_SLATE, TERM_SLATE, TERM_WHITE, TERM_VIOLET,
182 	TERM_L_RED, TERM_L_BLUE, TERM_BLUE, TERM_RED
183 };
184 
185 
186 /*
187  * Rods (adjectives and colors).
188  * Efficiency -- copied from wand arrays
189  */
190 
191 static cptr rod_adj[MAX_METALS];
192 
193 static byte rod_col[MAX_METALS];
194 
195 
196 /*
197  * Mushrooms (adjectives and colors)
198  */
199 
200 static cptr food_adj[MAX_SHROOM] =
201 {
202 	/* 0-9 */
203 	"Blue", "Black", "Black Spotted", "Brown", "Dark Blue",
204 	"Dark Green", "Dark Red", "Yellow", "Furry", "Green",
205 	/* 10-19 */
206 	"Grey", "Light Blue", "Light Green", "Violet", "Red",
207 	"Slimy", "Tan", "White", "White Spotted", "Wrinkled",
208 	/* 20-24 */
209 	"Strange", "Silver", "Glowing", "Orange", "Dried",
210 };
211 
212 static byte food_col[MAX_SHROOM] =
213 {
214 	/* 0-9 */
215 	TERM_BLUE, TERM_L_DARK, TERM_L_DARK, TERM_UMBER, TERM_BLUE,
216 	TERM_GREEN, TERM_RED, TERM_YELLOW, TERM_L_WHITE, TERM_GREEN,
217 	/* 10-19 */
218 	TERM_SLATE, TERM_L_BLUE, TERM_L_GREEN, TERM_VIOLET, TERM_RED,
219 	TERM_SLATE, TERM_L_UMBER, TERM_WHITE, TERM_WHITE, TERM_UMBER,
220 	/* 20-24 */
221 	TERM_L_BLUE, TERM_WHITE, TERM_YELLOW, TERM_ORANGE, TERM_UMBER,
222 };
223 
224 
225 /*
226  * Color adjectives and colors, for potions.
227  * Hack -- The first four entries are hard-coded.
228  * (water, apple juice, slime mold juice, something)
229  */
230 
231 static cptr potion_adj[MAX_COLORS] =
232 {
233 	/* Fixed colors */
234 	"Clear", "Light Brown", "Icky Green", "xxx",
235 	/* 4-9 */
236 	"Azure",
237 	"Blue", "Blue Speckled", "Black", "Brown", "Brown Speckled",
238 	/* 10-19 */
239 	"Bubbling", "Chartreuse", "Cloudy", "Copper Speckled", "Crimson",
240 	"Cyan", "Dark Blue", "Dark Green", "Dark Red", "Gold Speckled",
241 	/* 20-29 */
242 	"Green", "Green Speckled", "Grey", "Grey Speckled", "Hazy",
243 	"Indigo", "Light Blue", "Light Green", "Magenta", "Metallic Blue",
244 	/* 30-39 */
245 	"Metallic Red", "Metallic Green", "Metallic Purple", "Misty", "Orange",
246 	"Orange Speckled", "Pink", "Pink Speckled", "Puce", "Purple",
247 	/* 40-49 */
248 	"Purple Speckled", "Red", "Red Speckled", "Silver Speckled", "Smoky",
249 	"Tangerine", "Violet", "Vermilion", "White", "Yellow",
250 	/* 50-59 */
251 	"Violet Speckled", "Pungent", "Clotted Red", "Viscous Pink", "Oily Yellow",
252 	"Gloopy Green", "Shimmering", "Coagulated Crimson", "Yellow Speckled",
253 	/* 60-69 */
254 	"Gold", "Manly", "Stinking", "Oily Black", "Ichor", "Ivory White",
255 	"Sky Blue", "Bloody", "Inky Black", "Silver Flecked", "Red Flecked",
256 	/* 70-75 */
257 	"Green Flecked", "Sea Green", "Umber", "Layered", "Fizzy Yellow",
258 	"Fizzy Green",
259 };
260 
261 static byte potion_col[MAX_COLORS] =
262 {
263 	/* Fixed colors */
264 	TERM_WHITE, TERM_L_UMBER, TERM_GREEN, 0,
265 	/* 4-9 */
266 	TERM_L_BLUE,
267 	TERM_BLUE, TERM_BLUE, TERM_L_DARK, TERM_UMBER, TERM_UMBER,
268 	/* 10-19 */
269 	TERM_L_WHITE, TERM_L_GREEN, TERM_WHITE, TERM_L_UMBER, TERM_RED,
270 	TERM_L_BLUE, TERM_BLUE, TERM_GREEN, TERM_RED, TERM_YELLOW,
271 	/* 20-29 */
272 	TERM_GREEN, TERM_GREEN, TERM_SLATE, TERM_SLATE, TERM_L_WHITE,
273 	TERM_VIOLET, TERM_L_BLUE, TERM_L_GREEN, TERM_RED, TERM_BLUE,
274 	/* 30-39 */
275 	TERM_RED, TERM_GREEN, TERM_VIOLET, TERM_L_WHITE, TERM_ORANGE,
276 	TERM_ORANGE, TERM_L_RED, TERM_L_RED, TERM_VIOLET, TERM_VIOLET,
277 	/* 40-49 */
278 	TERM_VIOLET, TERM_RED, TERM_RED, TERM_L_WHITE, TERM_L_DARK,
279 	TERM_ORANGE, TERM_VIOLET, TERM_RED, TERM_WHITE, TERM_YELLOW,
280 	/* 50-59 */
281 	TERM_VIOLET, TERM_L_RED, TERM_RED, TERM_L_RED, TERM_YELLOW,
282 	TERM_GREEN, TERM_VIOLET, TERM_RED, TERM_YELLOW, TERM_YELLOW,
283 	/* 60-69 */
284 	TERM_L_UMBER, TERM_UMBER, TERM_L_DARK, TERM_RED, TERM_WHITE,
285 	TERM_L_BLUE, TERM_RED, TERM_L_DARK, TERM_WHITE, TERM_RED,
286 	/* 70-75 */
287 	TERM_GREEN, TERM_L_GREEN, TERM_UMBER, TERM_L_BLUE, TERM_YELLOW,
288 	TERM_L_GREEN,
289 };
290 
291 
292 /*
293  * Syllables for scrolls (must be 1-4 letters each)
294  */
295 
296 static cptr syllables[MAX_SYLLABLES] =
297 {
298 	"a", "ab", "ag", "aks", "ala", "an", "ankh", "app",
299 	"arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek",
300 	"bie", "bin", "bit", "bjor", "blu", "bot", "bu",
301 	"byt", "comp", "con", "cos", "cre", "dalf", "dan",
302 	"den", "der", "doe", "dok", "eep", "el", "eng", "er", "ere", "erk",
303 	"esh", "evs", "fa", "fid", "flit", "for", "fri", "fu", "gan",
304 	"gar", "glen", "gop", "gre", "ha", "he", "hyd", "i",
305 	"ing", "ion", "ip", "ish", "it", "ite", "iv", "jo",
306 	"kho", "kli", "klis", "la", "lech", "man", "mar",
307 	"me", "mi", "mic", "mik", "mon", "mung", "mur", "nag", "nej",
308 	"nelg", "nep", "ner", "nes", "nis", "nih", "nin", "o",
309 	"od", "ood", "org", "orn", "ox", "oxy", "pay", "pet",
310 	"ple", "plu", "po", "pot", "prok", "re", "rea", "rhov",
311 	"ri", "ro", "rog", "rok", "rol", "sa", "san", "sat",
312 	"see", "sef", "seh", "shu", "ski", "sna", "sne", "snik",
313 	"sno", "so", "sol", "sri", "sta", "sun", "ta", "tab",
314 	"tem", "ther", "ti", "tox", "trol", "tue", "turs", "u",
315 	"ulk", "um", "un", "uni", "ur", "val", "viv", "vly",
316 	"vom", "wah", "wed", "werg", "wex", "whon", "wun", "xi",
317 	"yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on",
318 	"foo", "ju", "xuxu"
319 };
320 
321 
322 /*
323  * Hold the titles of scrolls, 6 to 14 characters each
324  * Also keep an array of scroll colors (always WHITE for now)
325  */
326 static char scroll_adj[MAX_TITLES][16];
327 
328 static byte scroll_col[MAX_TITLES];
329 
330 
331 /*
332  * Certain items, if aware, are known instantly
333  * This function is used only by "flavor_init()"
334  */
object_easy_know(int i)335 static bool object_easy_know(int i)
336 {
337 	object_kind *k_ptr = &k_info[i];
338 
339 	if (FLAG(k_ptr, TR_EASY_KNOW)) return (TRUE);
340 
341 	/* Nope */
342 	return (FALSE);
343 }
344 
345 
346 /*
347  * Certain items have a flavor
348  * This function is used only by "flavor_init()"
349  */
object_flavor(int k_idx)350 static bool object_flavor(int k_idx)
351 {
352 	object_kind *k_ptr = &k_info[k_idx];
353 
354 	/* Analyze the item */
355 	switch (k_ptr->tval)
356 	{
357 		case TV_AMULET:
358 		{
359 			return (0x80 + amulet_col[k_ptr->sval]);
360 		}
361 
362 		case TV_RING:
363 		{
364 			return (0x90 + ring_col[k_ptr->sval]);
365 		}
366 
367 		case TV_STAFF:
368 		{
369 			return (0xA0 + staff_col[k_ptr->sval]);
370 		}
371 
372 		case TV_WAND:
373 		{
374 			return (0xB0 + wand_col[k_ptr->sval]);
375 		}
376 
377 		case TV_ROD:
378 		{
379 			return (0xC0 + rod_col[k_ptr->sval]);
380 		}
381 
382 		case TV_SCROLL:
383 		{
384 			return (0xD0 + scroll_col[k_ptr->sval]);
385 		}
386 
387 		case TV_POTION:
388 		{
389 			return (0xE0 + potion_col[k_ptr->sval]);
390 		}
391 
392 		case TV_FOOD:
393 		{
394 			if (k_ptr->sval < SV_FOOD_MIN_FOOD)
395 			{
396 				return (0xF0 + food_col[k_ptr->sval]);
397 			}
398 
399 			break;
400 		}
401 	}
402 
403 	/* No flavor */
404 	return (0);
405 }
406 
407 
get_table_name(char * out_string,bool quotes)408 void get_table_name(char *out_string, bool quotes)
409 {
410 	int testcounter = 2;
411 
412 	int len = 0;
413 
414 	/* Empty string */
415 	out_string[0] = 0;
416 
417 	if (quotes)
418 	{
419 		strnfcat(out_string, 18, &len, "'");
420 	}
421 
422 	if (one_in_(3))
423 	{
424 		while (testcounter--)
425 			strnfcat(out_string, 18, &len, syllables[randint0(MAX_SYLLABLES)]);
426 	}
427 	else
428 	{
429 		char Syllable[80];
430 
431 		while (testcounter--)
432 		{
433 			(void)get_rnd_line("elvish.txt", 0, Syllable);
434 			strnfcat(out_string, 18, &len, "%s", Syllable);
435 		}
436 	}
437 
438 	if (quotes)
439 	{
440 		out_string[1] = toupper(out_string[1]);
441 		strnfcat(out_string, 18, &len, "'");
442 	}
443 	else
444 	{
445 		out_string[0] = toupper(out_string[0]);
446 	}
447 }
448 
449 
450 /*
451  * Prepare the "variable" part of the "k_info" array.
452  *
453  * The "color"/"metal"/"type" of an item is its "flavor".
454  * For the most part, flavors are assigned randomly each game.
455  *
456  * Initialize descriptions for the "colored" objects, including:
457  * Rings, Amulets, Staffs, Wands, Rods, Food, Potions, Scrolls.
458  *
459  * The first 4 entries for potions are fixed (Water, Apple Juice,
460  * Slime Mold Juice, Unused Potion).
461  *
462  * Scroll titles are always between 6 and 14 letters long.  This is
463  * ensured because every title is composed of whole words, where every
464  * word is from 1 to 8 letters long (one or two syllables of 1 to 4
465  * letters each), and that no scroll is finished until it attempts to
466  * grow beyond 15 letters.  The first time this can happen is when the
467  * current title has 6 letters and the new word has 8 letters, which
468  * would result in a 6 letter scroll title.
469  *
470  * Duplicate titles are avoided by requiring that no two scrolls share
471  * the same first four letters (not the most efficient method, and not
472  * the least efficient method, but it will always work).
473  *
474  * Hack -- make sure everything stays the same for each saved game
475  * This is accomplished by the use of a saved "random seed", as in
476  * "town_gen()".  Since no other functions are called while the special
477  * seed is in effect, so this function is pretty "safe".
478  *
479  * Note that the "hacked seed" may provide an RNG with alternating parity!
480  */
flavor_init(void)481 void flavor_init(void)
482 {
483 	int i, j;
484 
485 	byte temp_col;
486 
487 	cptr temp_adj;
488 
489 
490 	/* Hack -- Use the "simple" RNG */
491 	Rand_quick = TRUE;
492 
493 	/* Hack -- Induce consistant flavors */
494 	Rand_value = seed_flavor;
495 
496 
497 	/* Efficiency -- Rods/Wands share initial array */
498 	for (i = 0; i < MAX_METALS; i++)
499 	{
500 		rod_adj[i] = wand_adj[i];
501 		rod_col[i] = wand_col[i];
502 	}
503 
504 
505 	/* Rings have "ring colors" */
506 	for (i = 0; i < MAX_ROCKS; i++)
507 	{
508 		j = randint0(MAX_ROCKS);
509 		temp_adj = ring_adj[i];
510 		ring_adj[i] = ring_adj[j];
511 		ring_adj[j] = temp_adj;
512 		temp_col = ring_col[i];
513 		ring_col[i] = ring_col[j];
514 		ring_col[j] = temp_col;
515 	}
516 
517 	/* Amulets have "amulet colors" */
518 	for (i = 0; i < MAX_AMULETS; i++)
519 	{
520 		j = randint0(MAX_AMULETS);
521 		temp_adj = amulet_adj[i];
522 		amulet_adj[i] = amulet_adj[j];
523 		amulet_adj[j] = temp_adj;
524 		temp_col = amulet_col[i];
525 		amulet_col[i] = amulet_col[j];
526 		amulet_col[j] = temp_col;
527 	}
528 
529 	/* Staffs */
530 	for (i = 0; i < MAX_WOODS; i++)
531 	{
532 		j = randint0(MAX_WOODS);
533 		temp_adj = staff_adj[i];
534 		staff_adj[i] = staff_adj[j];
535 		staff_adj[j] = temp_adj;
536 		temp_col = staff_col[i];
537 		staff_col[i] = staff_col[j];
538 		staff_col[j] = temp_col;
539 	}
540 
541 	/* Wands */
542 	for (i = 0; i < MAX_METALS; i++)
543 	{
544 		j = randint0(MAX_METALS);
545 		temp_adj = wand_adj[i];
546 		wand_adj[i] = wand_adj[j];
547 		wand_adj[j] = temp_adj;
548 		temp_col = wand_col[i];
549 		wand_col[i] = wand_col[j];
550 		wand_col[j] = temp_col;
551 	}
552 
553 	/* Rods */
554 	for (i = 0; i < MAX_METALS; i++)
555 	{
556 		j = randint0(MAX_METALS);
557 		temp_adj = rod_adj[i];
558 		rod_adj[i] = rod_adj[j];
559 		rod_adj[j] = temp_adj;
560 		temp_col = rod_col[i];
561 		rod_col[i] = rod_col[j];
562 		rod_col[j] = temp_col;
563 	}
564 
565 	/* Foods (Mushrooms) */
566 	for (i = 0; i < MAX_SHROOM; i++)
567 	{
568 		j = randint0(MAX_SHROOM);
569 		temp_adj = food_adj[i];
570 		food_adj[i] = food_adj[j];
571 		food_adj[j] = temp_adj;
572 		temp_col = food_col[i];
573 		food_col[i] = food_col[j];
574 		food_col[j] = temp_col;
575 	}
576 
577 	/* Potions */
578 	for (i = 4; i < MAX_COLORS; i++)
579 	{
580 		j = rand_range(4, MAX_COLORS - 1);
581 		temp_adj = potion_adj[i];
582 		potion_adj[i] = potion_adj[j];
583 		potion_adj[j] = temp_adj;
584 		temp_col = potion_col[i];
585 		potion_col[i] = potion_col[j];
586 		potion_col[j] = temp_col;
587 	}
588 
589 	/* Scrolls (random titles, always white) */
590 	for (i = 0; i < MAX_TITLES; i++)
591 	{
592 		/* Get a new title */
593 		while (TRUE)
594 		{
595 			char buf[80];
596 
597 			int buf_len = 0;
598 
599 			bool okay;
600 
601 			/* Start a new title */
602 			buf[0] = '\0';
603 
604 			/* Collect words until done */
605 			while (1)
606 			{
607 				int q, s;
608 
609 				char tmp[80];
610 
611 				int len = 0;
612 
613 				/* Start a new word */
614 				tmp[0] = '\0';
615 
616 				/* Choose one or two syllables */
617 				s = ((randint0(100) < 30) ? 1 : 2);
618 
619 				/* Add a one or two syllable word */
620 				for (q = 0; q < s; q++)
621 				{
622 					/* Add the syllable */
623 					strnfcat(tmp, 80, &len, syllables[randint0(MAX_SYLLABLES)]);
624 				}
625 
626 				/* Stop before getting too long */
627 				if (strlen(buf) + 1 + strlen(tmp) > 15) break;
628 
629 				/* Add a space + word */
630 				strnfcat(buf, 80, &buf_len, " %s", tmp);
631 			}
632 
633 			/* Save the title */
634 			strcpy(scroll_adj[i], buf + 1);
635 
636 			/* Assume okay */
637 			okay = TRUE;
638 
639 			/* Check for "duplicate" scroll titles */
640 			for (j = 0; j < i; j++)
641 			{
642 				cptr hack1 = scroll_adj[j];
643 				cptr hack2 = scroll_adj[i];
644 
645 				/* Compare first four characters */
646 				if (*hack1++ != *hack2++) continue;
647 				if (*hack1++ != *hack2++) continue;
648 				if (*hack1++ != *hack2++) continue;
649 				if (*hack1++ != *hack2++) continue;
650 
651 				/* Not okay */
652 				okay = FALSE;
653 
654 				/* Stop looking */
655 				break;
656 			}
657 
658 			/* Break when done */
659 			if (okay) break;
660 		}
661 
662 		/* All scrolls are white */
663 		scroll_col[i] = TERM_WHITE;
664 	}
665 
666 
667 	/* Hack -- Use the "complex" RNG */
668 	Rand_quick = FALSE;
669 
670 	/* Analyze every object */
671 	for (i = 1; i < z_info->k_max; i++)
672 	{
673 		object_kind *k_ptr = &k_info[i];
674 
675 		/* Skip "empty" objects */
676 		if (!k_ptr->name) continue;
677 
678 		/* Extract "flavor" (if any) */
679 		k_ptr->flavor = object_flavor(i);
680 
681 		/* No flavor yields aware */
682 		if (!k_ptr->flavor) k_ptr->aware = TRUE;
683 
684 		/* Check for "easily known" */
685 		k_ptr->easy_know = object_easy_know(i);
686 	}
687 }
688 
689 
690 /*
691  * Creates a description of the item "o_ptr", and stores it in "out_val".
692  *
693  * One can choose the "verbosity" of the description, including whether
694  * or not the "number" of items should be described, and how much detail
695  * should be used when describing the item.
696  *
697  * The given "buf" must be 80 chars long to hold the longest possible
698  * description, which can get pretty long, including incriptions, such as:
699  * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)".
700  * Note that the inscription will be clipped to keep the total description
701  * under size - 1 chars (plus a terminator).
702  *
703  * Note the use of "object_desc_num()" and "object_desc_int()" as
704  * hyper-efficient, portable, versions of some common "sprintf()" commands.
705  *
706  * Note that all ego-items (when known) append an "Ego-Item Name", unless
707  * the item is also an artifact, which should NEVER happen.
708  *
709  * Note that all artifacts (when known) append an "Artifact Name", so we
710  * have special processing for "Specials" (artifact Lites, Rings, Amulets).
711  * The "Specials" never use "modifiers" if they are "known", since they
712  * have special "descriptions", such as "The Necklace of the Dwarves".
713  *
714  * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone),
715  * plus the artifact name, just like any other artifact, if known.
716  *
717  * Special Ring's and Amulet's, if not "aware", use the same code as normal
718  * rings and amulets, and if "aware", use the "k_info" base-name (Ring or
719  * Amulet or Necklace).  They will NEVER "append" the "k_info" name.  But,
720  * they will append the artifact name, just like any artifact, if known.
721  *
722  * None of the Special Rings/Amulets are "EASY_KNOW", though they could be,
723  * at least, those which have no "pluses", such as the three artifact lites.
724  *
725  * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware.
726  *
727  * If "pref" then a "numeric" prefix will be pre-pended.
728  *
729  * Mode:
730  *   0 -- The Cloak of Death
731  *   1 -- The Cloak of Death [1,+3]
732  *   2 -- The Cloak of Death [1,+3] (+2 to Stealth)
733  *   3 -- The Cloak of Death [1,+3] (+2 to Stealth) {nifty}
734  */
object_desc(char * buf,const object_type * o_ptr,int pref,int mode,int max)735 void object_desc(char *buf, const object_type *o_ptr, int pref, int mode,
736                  int max)
737 {
738 	cptr basenm, modstr;
739 	int power;
740 
741 	bool aware = FALSE;
742 	bool known = FALSE;
743 
744 	bool append_name = FALSE;
745 
746 	bool show_weapon = FALSE;
747 	bool show_armour = FALSE;
748 
749 	cptr s;
750 
751 	object_type *bow_ptr;
752 
753 	/* damage dice, damage sides, damage bonus, energy */
754 	int dd, ds, db, energy_use;
755 	int tmul;
756 	long avgdam;
757 
758 	int len = 0;
759 
760 	object_kind *k_ptr = &k_info[o_ptr->k_idx];
761 
762 	monster_race *r_ptr = &r_info[o_ptr->pval];
763 
764 	/* See if the object is "aware" */
765 	if (object_aware_p(o_ptr)) aware = TRUE;
766 
767 	/* See if the object is "known" */
768 	if (object_known_p(o_ptr)) known = TRUE;
769 
770 	/* Artifacts are not "aware' unless "known" */
771 	if ((FLAG(o_ptr, TR_INSTA_ART)) && !known) aware = FALSE;
772 
773 	/* Extract default "base" string */
774 	basenm = get_object_name(o_ptr);
775 
776 	/* Assume no "modifier" string */
777 	modstr = "";
778 
779 	/* Empty description */
780 	buf[0] = '\0';
781 
782 	/* Analyze the object */
783 	switch (o_ptr->tval)
784 	{
785 		case TV_SKELETON:
786 		case TV_BOTTLE:
787 		case TV_JUNK:
788 		case TV_SPIKE:
789 		case TV_FLASK:
790 		case TV_CHEST:
791 		{
792 			/* Some objects are easy to describe */
793 			break;
794 		}
795 
796 		case TV_FIGURINE:
797 		case TV_STATUE:
798 		{
799 			/* Figurines/Statues */
800 			cptr tmp = mon_race_name(r_ptr);
801 
802 			char idol_name[512];
803 
804 			if (!FLAG(r_ptr, RF_UNIQUE))
805 			{
806 				strnfmt(idol_name, 512, "%s%s",
807 						(is_a_vowel(*tmp) ? "an " : "a "), tmp);
808 
809 				modstr = idol_name;
810 			}
811 			else
812 			{
813 				modstr = tmp;
814 			}
815 
816 			break;
817 		}
818 
819 		case TV_SHOT:
820 		case TV_BOLT:
821 		case TV_ARROW:
822 		case TV_BOW:
823 		case TV_HAFTED:
824 		case TV_POLEARM:
825 		case TV_SWORD:
826 		case TV_DIGGING:
827 		{
828 			/* Missiles/ Bows/ Weapons */
829 			show_weapon = TRUE;
830 			break;
831 		}
832 
833 		case TV_BOOTS:
834 		case TV_GLOVES:
835 		case TV_CLOAK:
836 		case TV_CROWN:
837 		case TV_HELM:
838 		case TV_SHIELD:
839 		case TV_SOFT_ARMOR:
840 		case TV_HARD_ARMOR:
841 		case TV_DRAG_ARMOR:
842 		{
843 			/* Armour */
844 			show_armour = TRUE;
845 			break;
846 		}
847 
848 		case TV_LITE:
849 		{
850 			/* Lites (including a few "Specials") */
851 			break;
852 		}
853 
854 		case TV_AMULET:
855 		{
856 			/* Amulets (including a few "Specials") */
857 
858 			/* Known artifacts */
859 			if ((FLAG(k_ptr, TR_INSTA_ART)) && aware) break;
860 
861 			/* Color the object */
862 			modstr = amulet_adj[o_ptr->sval];
863 			if (aware) append_name = TRUE;
864 
865 			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
866 				basenm = "& Amulet~";
867 			else
868 				basenm = "& # Amulet~";
869 			break;
870 		}
871 
872 		case TV_RING:
873 		{
874 			/* Rings (including a few "Specials") */
875 
876 			/* Known artifacts */
877 			if ((FLAG(k_ptr, TR_INSTA_ART)) && aware) break;
878 
879 			/* Color the object */
880 			modstr = ring_adj[o_ptr->sval];
881 			if (aware) append_name = TRUE;
882 
883 			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
884 				basenm = "& Ring~";
885 			else
886 				basenm = "& # Ring~";
887 
888 			/* Hack -- The One Ring */
889 			if (!aware && (o_ptr->sval == SV_RING_POWER)) modstr = "Plain Gold";
890 
891 			break;
892 		}
893 
894 		case TV_STAFF:
895 		{
896 			/* Color the object */
897 			modstr = staff_adj[o_ptr->sval];
898 			if (aware) append_name = TRUE;
899 			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
900 				basenm = "& Staff~";
901 			else
902 				basenm = "& # Staff~";
903 			break;
904 		}
905 
906 		case TV_WAND:
907 		{
908 			/* Color the object */
909 			modstr = wand_adj[o_ptr->sval];
910 			if (aware) append_name = TRUE;
911 			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
912 				basenm = "& Wand~";
913 			else
914 				basenm = "& # Wand~";
915 			break;
916 		}
917 
918 		case TV_ROD:
919 		{
920 			/* Color the object */
921 			modstr = rod_adj[o_ptr->sval];
922 			if (aware) append_name = TRUE;
923 			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
924 				basenm = "& Rod~";
925 			else
926 				basenm = "& # Rod~";
927 			break;
928 		}
929 
930 		case TV_SCROLL:
931 		{
932 			/* Color the object */
933 			modstr = scroll_adj[o_ptr->sval];
934 			if (aware) append_name = TRUE;
935 			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
936 				basenm = "& Scroll~";
937 			else
938 				basenm = "& Scroll~ titled \"#\"";
939 			break;
940 		}
941 
942 		case TV_POTION:
943 		{
944 			/* Color the object */
945 			modstr = potion_adj[o_ptr->sval];
946 			if (aware) append_name = TRUE;
947 			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
948 				basenm = "& Potion~";
949 			else
950 				basenm = "& # Potion~";
951 			break;
952 		}
953 
954 		case TV_FOOD:
955 		{
956 			/* Ordinary food is "boring" */
957 			if (o_ptr->sval >= SV_FOOD_MIN_FOOD) break;
958 
959 			/* Color the object */
960 			modstr = food_adj[o_ptr->sval];
961 			if (aware) append_name = TRUE;
962 			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
963 				basenm = "& Mushroom~";
964 			else
965 				basenm = "& # Mushroom~";
966 			break;
967 		}
968 
969 			/*** Magic Books ***/
970 
971 		case TV_LIFE_BOOK:
972 		{
973 			modstr = basenm;
974 			if (mp_ptr->spell_book == TV_LIFE_BOOK)
975 				basenm = "& Book~ of Life Magic #";
976 			else
977 				basenm = "& Life Spellbook~ #";
978 			break;
979 		}
980 
981 		case TV_SORCERY_BOOK:
982 		{
983 			modstr = basenm;
984 			if (mp_ptr->spell_book == TV_LIFE_BOOK)
985 				basenm = "& Book~ of Sorcery #";
986 			else
987 				basenm = "& Sorcery Spellbook~ #";
988 			break;
989 		}
990 
991 		case TV_NATURE_BOOK:
992 		{
993 			modstr = basenm;
994 			if (mp_ptr->spell_book == TV_LIFE_BOOK)
995 				basenm = "& Book~ of Nature Magic #";
996 			else
997 				basenm = "& Nature Spellbook~ #";
998 			break;
999 		}
1000 
1001 		case TV_CHAOS_BOOK:
1002 		{
1003 			modstr = basenm;
1004 			if (mp_ptr->spell_book == TV_LIFE_BOOK)
1005 				basenm = "& Book~ of Chaos Magic #";
1006 			else
1007 				basenm = "& Chaos Spellbook~ #";
1008 			break;
1009 		}
1010 
1011 		case TV_DEATH_BOOK:
1012 		{
1013 			modstr = basenm;
1014 			if (mp_ptr->spell_book == TV_LIFE_BOOK)
1015 				basenm = "& Book~ of Death Magic #";
1016 			else
1017 				basenm = "& Death Spellbook~ #";
1018 			break;
1019 		}
1020 
1021 		case TV_TRUMP_BOOK:
1022 		{
1023 			modstr = basenm;
1024 			if (mp_ptr->spell_book == TV_LIFE_BOOK)
1025 				basenm = "& Book~ of Trump Magic #";
1026 			else
1027 				basenm = "& Trump Spellbook~ #";
1028 			break;
1029 		}
1030 
1031 		case TV_ARCANE_BOOK:
1032 		{
1033 			modstr = basenm;
1034 			if (mp_ptr->spell_book == TV_LIFE_BOOK)
1035 				basenm = "& Book~ of Arcane Magic #";
1036 			else
1037 				basenm = "& Arcane Spellbook~ #";
1038 			break;
1039 		}
1040 
1041 
1042 		case TV_GOLD:
1043 		{
1044 			/* Hack -- Gold/Gems */
1045 			strcpy(buf, basenm);
1046 			return;
1047 		}
1048 
1049 		default:
1050 		{
1051 			/* Used in the "inventory" routine */
1052 			strcpy(buf, "(nothing)");
1053 			return;
1054 		}
1055 	}
1056 
1057 	/* The object "expects" a "number" */
1058 	if (basenm[0] == '&')
1059 	{
1060 		/* Skip the ampersand (and space) */
1061 		s = basenm + 2;
1062 
1063 		/* No prefix */
1064 		if (!pref)
1065 		{
1066 			/* Nothing */
1067 		}
1068 
1069 		/* Hack -- None left */
1070 		else if (o_ptr->number <= 0)
1071 		{
1072 			strnfcat(buf, max, &len, "no more ");
1073 		}
1074 
1075 		/* Extract the number */
1076 		else if (o_ptr->number > 1)
1077 		{
1078 			strnfcat(buf, max, &len, "%d ", o_ptr->number);
1079 		}
1080 
1081 		/* Hack -- The only one of its kind */
1082 		else if (known && (FLAG(o_ptr, TR_INSTA_ART)))
1083 		{
1084 			strnfcat(buf, max, &len, "The ");
1085 		}
1086 
1087 		/* A single one, with a vowel in the modifier */
1088 		else if ((*s == '#') && (is_a_vowel(modstr[0])))
1089 		{
1090 			strnfcat(buf, max, &len, "an ");
1091 		}
1092 
1093 		/* A single one, with a vowel */
1094 		else if (is_a_vowel(*s))
1095 		{
1096 			strnfcat(buf, max, &len, "an ");
1097 		}
1098 
1099 		/* A single one, without a vowel */
1100 		else
1101 		{
1102 			strnfcat(buf, max, &len, "a ");
1103 		}
1104 	}
1105 
1106 	/* Hack -- objects that "never" take an article */
1107 	else
1108 	{
1109 		/* No ampersand */
1110 		s = basenm;
1111 
1112 		/* No pref */
1113 		if (!pref)
1114 		{
1115 			/* Nothing */
1116 		}
1117 
1118 		/* Hack -- all gone */
1119 		else if (o_ptr->number <= 0)
1120 		{
1121 			strnfcat(buf, max, &len, "no more ");
1122 		}
1123 
1124 		/* Prefix a number if required */
1125 		else if (o_ptr->number > 1)
1126 		{
1127 			strnfcat(buf, max, &len, "%d ", o_ptr->number);
1128 		}
1129 
1130 		/* Hack -- The only one of its kind */
1131 		else if (known && (FLAG(o_ptr, TR_INSTA_ART)))
1132 		{
1133 			strnfcat(buf, max, &len, "The ");
1134 		}
1135 
1136 		/* Hack -- single items get no prefix */
1137 		else
1138 		{
1139 			/* Nothing */
1140 		}
1141 	}
1142 
1143 	/* Copy the string */
1144 	while (*s)
1145 	{
1146 		/* Pluralizer */
1147 		if (*s == '~')
1148 		{
1149 			/* Add a plural if needed */
1150 			if (o_ptr->number != 1)
1151 			{
1152 				/* Get previous character */
1153 				char k = s[-1];
1154 
1155 				/* XXX XXX XXX Mega-Hack */
1156 
1157 				/* Hack -- "Cutlass-es" and "Torch-es" */
1158 				if ((k == 's') || (k == 'h'))
1159 				{
1160 					strnfcat(buf, max, &len, "es");
1161 				}
1162 				else
1163 				{
1164 					/* Add an 's' */
1165 					strnfcat(buf, max, &len, "s");
1166 				}
1167 			}
1168 		}
1169 
1170 		/* Modifier */
1171 		else if (*s == '#')
1172 		{
1173 			/* Insert the modifier */
1174 			strnfcat(buf, max, &len, "%s", modstr);
1175 		}
1176 
1177 		/* Normal */
1178 		else
1179 		{
1180 			/* Copy character */
1181 			strnfcat(buf, max, &len, "%c", *s);
1182 		}
1183 
1184 		s++;
1185 	}
1186 
1187 	/* Append the "kind name" to the "base name" */
1188 	if (append_name)
1189 	{
1190 		strnfcat(buf, max, &len, " of %s", get_object_name(o_ptr));
1191 	}
1192 
1193 
1194 	/* Hack -- Append "Artifact" or "Special" names */
1195 	if (known)
1196 	{
1197 		if (o_ptr->inscription && strchr(quark_str(o_ptr->inscription), '#'))
1198 		{
1199 			/* Find the '#' */
1200 			cptr str = strchr(quark_str(o_ptr->inscription), '#');
1201 
1202 			/* Add the false name */
1203 			strnfcat(buf, max, &len, " %s" CLR_DEFAULT, &str[1]);
1204 		}
1205 
1206 		/* Is it a new artifact or ego item? */
1207 		else if (o_ptr->xtra_name)
1208 		{
1209 			strnfcat(buf, max, &len, " %s", quark_str(o_ptr->xtra_name));
1210 		}
1211 	}
1212 
1213 	/* No more details wanted */
1214 	if (mode < 1) return;
1215 
1216 	/* Hack -- Chests must be described in detail */
1217 	if (o_ptr->tval == TV_CHEST)
1218 	{
1219 		/* Not searched yet */
1220 		if (!known)
1221 		{
1222 			/* Nothing */
1223 		}
1224 
1225 		/* May be "empty" */
1226 		else if (!o_ptr->pval)
1227 		{
1228 			strnfcat(buf, max, &len, " (empty)");
1229 		}
1230 
1231 		/* May be "disarmed" */
1232 		else if (o_ptr->pval < 0)
1233 		{
1234 			if (chest_traps[0 - o_ptr->pval])
1235 			{
1236 				strnfcat(buf, max, &len, " (disarmed)");
1237 			}
1238 			else
1239 			{
1240 				strnfcat(buf, max, &len, " (unlocked)");
1241 			}
1242 		}
1243 
1244 		/* Describe the traps, if any */
1245 		else
1246 		{
1247 			/* Describe the traps */
1248 			switch (chest_traps[o_ptr->pval])
1249 			{
1250 				case 0:
1251 				{
1252 					strnfcat(buf, max, &len, " (Locked)");
1253 					break;
1254 				}
1255 				case CHEST_LOSE_STR:
1256 				{
1257 					strnfcat(buf, max, &len, " (Poison Needle)");
1258 					break;
1259 				}
1260 				case CHEST_LOSE_CON:
1261 				{
1262 					strnfcat(buf, max, &len, " (Poison Needle)");
1263 					break;
1264 				}
1265 				case CHEST_POISON:
1266 				{
1267 					strnfcat(buf, max, &len, " (Gas Trap)");
1268 					break;
1269 				}
1270 				case CHEST_PARALYZE:
1271 				{
1272 					strnfcat(buf, max, &len, " (Gas Trap)");
1273 					break;
1274 				}
1275 				case CHEST_EXPLODE:
1276 				{
1277 					strnfcat(buf, max, &len, " (Explosion Device)");
1278 					break;
1279 				}
1280 				case CHEST_SUMMON:
1281 				{
1282 					strnfcat(buf, max, &len, " (Summoning Runes)");
1283 					break;
1284 				}
1285 				default:
1286 				{
1287 					strnfcat(buf, max, &len, " (Multiple Traps)");
1288 					break;
1289 				}
1290 			}
1291 		}
1292 	}
1293 
1294 
1295 	/* Display the item like a weapon */
1296 	if (FLAG(o_ptr, TR_SHOW_MODS)) show_weapon = TRUE;
1297 
1298 	/* Display the item like a weapon */
1299 	if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE;
1300 
1301 	/* Display the item like armour */
1302 	if ((o_ptr->ac) && (o_ptr->tval != TV_WAND)) show_armour = TRUE;
1303 
1304 	/* Dump base weapon info */
1305 	switch (o_ptr->tval)
1306 	{
1307 		case TV_SHOT:
1308 		case TV_BOLT:
1309 		case TV_ARROW:
1310 		case TV_HAFTED:
1311 		case TV_POLEARM:
1312 		case TV_SWORD:
1313 		case TV_DIGGING:
1314 		{
1315 			/* Missiles and Weapons */
1316 
1317 			/* Append a "damage" string */
1318 			strnfcat(buf, max, &len, " (%dd%d)", o_ptr->dd, o_ptr->ds);
1319 
1320 			/* All done */
1321 			break;
1322 		}
1323 
1324 		case TV_BOW:
1325 		{
1326 			/* Bows get a special "damage string" */
1327 
1328 			/* Extract the "base power" */
1329 			switch (o_ptr->sval)
1330 			{
1331 				case SV_SLING:
1332 				{
1333 					power = 2;
1334 					break;
1335 				}
1336 				case SV_SHORT_BOW:
1337 				{
1338 					power = 2;
1339 					break;
1340 				}
1341 				case SV_LONG_BOW:
1342 				{
1343 					if (p_ptr->stat[A_STR].use >= 160)
1344 					{
1345 						power = 3;
1346 					}
1347 					else
1348 					{
1349 						/* hack- weak players cannot use a longbow well */
1350 						power = 2;
1351 					}
1352 					break;
1353 				}
1354 				case SV_LIGHT_XBOW:
1355 				{
1356 					power = 4;
1357 					break;
1358 				}
1359 				case SV_HEAVY_XBOW:
1360 				{
1361 					power = 5;
1362 					break;
1363 				}
1364 				default:
1365 				{
1366 					msgf("Unknown firing multiplier.");
1367 					power = 0;
1368 				}
1369 			}
1370 
1371 			/* Apply the "Extra Might" flag */
1372 			if (FLAG(o_ptr, TR_XTRA_MIGHT)) power++;
1373 
1374 			/* Append a special "damage" string */
1375 			strnfcat(buf, max, &len, " (x%d)", power);
1376 
1377 			/* All done */
1378 			break;
1379 		}
1380 	}
1381 
1382 
1383 	/* Add the weapon bonuses */
1384 	if (known)
1385 	{
1386 		/* Show the tohit/todam on request */
1387 		if (show_weapon)
1388 		{
1389 			strnfcat(buf, max, &len, " (%+d,%+d%%)", o_ptr->to_h,
1390 					deadliness_calc(o_ptr->to_d) - 100);
1391 		}
1392 
1393 		/* Show the tohit if needed */
1394 		else if (o_ptr->to_h)
1395 		{
1396 			strnfcat(buf, max, &len, " (%+d)", o_ptr->to_h);
1397 		}
1398 
1399 		/* Show the todam if needed */
1400 		else if (o_ptr->to_d)
1401 		{
1402 			strnfcat(buf, max, &len, " (%+d%%)", o_ptr->to_d * 5);
1403 		}
1404 	}
1405 
1406 	bow_ptr = &p_ptr->equipment[EQUIP_BOW];
1407 
1408 	/* if have a firing weapon + ammo matches bow */
1409 	if (bow_ptr->k_idx && (p_ptr->ammo_tval == o_ptr->tval))
1410 	{
1411 		/* See if the bow is "known" - then set damage bonus */
1412 		if (object_known_p(bow_ptr))
1413 		{
1414 			db = bow_ptr->to_d;
1415 		}
1416 		else
1417 		{
1418 			db = 0;
1419 		}
1420 
1421 		/* effect of player */
1422 		db += p_ptr->dis_to_d;
1423 
1424 		/* effect of ammo */
1425 		if (known) db += o_ptr->to_d;
1426 
1427 		dd = o_ptr->dd;
1428 		ds = o_ptr->ds;
1429 
1430 		/* effect of damage dice x2 */
1431 		avgdam = avg_dam(db, dd, ds);
1432 
1433 		/* Bow properties */
1434 		energy_use = p_ptr->bow_energy;
1435 		tmul = p_ptr->ammo_mult;
1436 
1437 		/* Get extra "power" from "extra might" */
1438 		if (FLAG(p_ptr, TR_XTRA_MIGHT)) tmul++;
1439 
1440 		/* launcher multiplier */
1441 		avgdam *= tmul;
1442 
1443 		/* display (shot damage/ avg damage) */
1444 		strnfcat(buf, max, &len, " (%d/", avgdam / 200);
1445 
1446 		tmul = p_ptr->num_fire;
1447 		if (tmul == 0)
1448 		{
1449 			strnfcat(buf, max, &len, "0)");
1450 		}
1451 		else
1452 		{
1453 			/* calc effects of energy  x2 */
1454 			avgdam *= (1 + p_ptr->num_fire);
1455 
1456 			/* rescale */
1457 			avgdam /= 4 * energy_use;
1458 			strnfcat(buf, max, &len, "%d)", avgdam);
1459 		}
1460 	}
1461 
1462 	/* Add the armor bonuses */
1463 	if (known)
1464 	{
1465 		/* Show the armor class info */
1466 		if (show_armour)
1467 		{
1468 			strnfcat(buf, max, &len, " [%d,%+d]", o_ptr->ac,  o_ptr->to_a);
1469 		}
1470 
1471 		/* No base armor, but does increase armor */
1472 		else if (o_ptr->to_a)
1473 		{
1474 			strnfcat(buf, max, &len, " [%+d]", o_ptr->to_a);
1475 		}
1476 	}
1477 
1478 	/* Hack -- always show base armor */
1479 	else if (show_armour)
1480 	{
1481 		strnfcat(buf, max, &len, " [%d]", o_ptr->ac);
1482 	}
1483 
1484 
1485 	/* No more details wanted */
1486 	if (mode < 2) return;
1487 
1488 
1489 	/*
1490 	 * Hack -- Wands and Staffs have charges.  Make certain how many charges
1491 	 * a stack of staffs really has is clear. -LM-
1492 	 */
1493 	if (known && ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)))
1494 	{
1495 		/* Dump " (N charges)" */
1496 		strnfcat(buf, max, &len, " (");
1497 
1498 		/* Clear explaination for staffs. */
1499 		if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1))
1500 		{
1501 			strnfcat(buf, max, &len, "%dx ", o_ptr->number);
1502 		}
1503 
1504 		if (o_ptr->pval == 1)
1505 		{
1506 			strnfcat(buf, max, &len, "%d charge)", o_ptr->pval);
1507 		}
1508 		else
1509 		{
1510 			strnfcat(buf, max, &len, "%d charges)", o_ptr->pval);
1511 		}
1512 	}
1513 	/* Hack -- Rods have a "charging" indicator.  Now that stacks of rods may
1514 	 * be in any state of charge or discharge, this now includes a number. -LM-
1515 	 */
1516 	else if (o_ptr->tval == TV_ROD)
1517 	{
1518 		/* Hack -- Dump " (# charging)" if relevant */
1519 		if (o_ptr->timeout)
1520 		{
1521 			/* Stacks of rods display an exact count of charging rods. */
1522 			if (o_ptr->number > 1)
1523 			{
1524 				/* Paranoia. */
1525 				if (k_ptr->pval == 0) k_ptr->pval = 1;
1526 
1527 				/*
1528 				 * Find out how many rods are charging, by dividing
1529 				 * current timeout by each rod's maximum timeout.
1530 				 * Ensure that any remainder is rounded up.  Display
1531 				 * very discharged stacks as merely fully discharged.
1532 				 */
1533 				power = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval;
1534 				if (power > o_ptr->number) power = o_ptr->number;
1535 
1536 				/* Display prettily. */
1537 				strnfcat(buf, max, &len, " (%d charging)", power);
1538 			}
1539 
1540 			/* "one Rod of Perception (1 charging)" would look tacky. */
1541 			else
1542 			{
1543 				strnfcat(buf, max, &len, " (charging)");
1544 			}
1545 		}
1546 	}
1547 
1548 	/* Hack -- Process Lanterns/Torches */
1549 	else if (o_ptr->tval == TV_LITE)
1550 	{
1551 		if (FLAG(o_ptr, TR_LITE))
1552 		{
1553 			/* Hack - tell us when lites of everburning are "empty" */
1554 			if ((o_ptr->sval <= SV_LITE_LANTERN) && !o_ptr->timeout)
1555 			{
1556 				strnfcat(buf, max, &len, " (empty)");
1557 			}
1558 		}
1559 		else
1560 		{
1561 			/* Hack -- Turns of light for normal lites */
1562 			strnfcat(buf, max, &len, " (with %d turns of light)", o_ptr->timeout);
1563 		}
1564 	}
1565 
1566 
1567 	/* Dump "pval" flags for wearable items */
1568 	if (known && (FLAG(o_ptr, TR_PVAL_MASK)))
1569 	{
1570 		/* Start the display */
1571 		strnfcat(buf, max, &len, " (%+d", o_ptr->pval);
1572 
1573 		/* Do not display the "pval" flags */
1574 		if (FLAG(o_ptr, TR_HIDE_TYPE))
1575 		{
1576 			/* Nothing */
1577 		}
1578 
1579 		/* Speed */
1580 		else if (FLAG(o_ptr, TR_SPEED))
1581 		{
1582 			/* Dump " to speed" */
1583 			strnfcat(buf, max, &len, " to speed");
1584 		}
1585 
1586 		/* Attack speed */
1587 		else if (FLAG(o_ptr, TR_BLOWS))
1588 		{
1589 			if (ABS(o_ptr->pval) == 1)
1590 			{
1591 				/* Add " attack" */
1592 				strnfcat(buf, max, &len, " attack");
1593 			}
1594 			else
1595 			{
1596 				/* Add "attacks" */
1597 				strnfcat(buf, max, &len, " attacks");
1598 			}
1599 		}
1600 
1601 		/* Finish the display */
1602 		strnfcat(buf, max, &len, ")");
1603 	}
1604 
1605 	/* Indicate charging objects, but not rods. */
1606 	if (known && o_ptr->timeout && (o_ptr->tval != TV_ROD)
1607 		&& (o_ptr->tval != TV_LITE))
1608 	{
1609 		/* Hack -- Dump " (charging)" if relevant */
1610 		strnfcat(buf, max, &len, " (charging)");
1611 	}
1612 
1613 
1614 	/* No more details wanted */
1615 	if (mode < 3) return;
1616 
1617 	/* Use the standard inscription if available */
1618 	if (o_ptr->inscription)
1619 	{
1620 		cptr tmp = quark_str(o_ptr->inscription);
1621 
1622 		/* Append the inscription */
1623 		strnfcat(buf, max, &len, " {");
1624 
1625 		/* Scan for the '#' character which marks a fake name. */
1626 		while(*tmp && (*tmp != '#'))
1627 		{
1628 			strnfcat(buf, max, &len, "%c", *tmp);
1629 
1630 			tmp++;
1631 		}
1632 
1633 		/* Finish the inscription */
1634 		strnfcat(buf, max, &len, CLR_DEFAULT "}");
1635 	}
1636 
1637 	/* Use the game-generated "feeling" otherwise, if available */
1638 	else if (o_ptr->feeling)
1639 	{
1640 		/* Append the inscription */
1641 		strnfcat(buf, max, &len, " {%s" CLR_DEFAULT "}", game_inscriptions[o_ptr->feeling]);
1642 	}
1643 
1644 	/* Note "cursed" if the item is known to be cursed */
1645 	else if (cursed_p(o_ptr) && (known || (o_ptr->info & (OB_SENSE))))
1646 	{
1647 		/* Append the inscription */
1648 		strnfcat(buf, max, &len, " {cursed}");
1649 	}
1650 
1651 	/* Mega-Hack -- note empty wands/staffs */
1652 	else if (!known && (o_ptr->info & (OB_EMPTY)))
1653 	{
1654 		/* Append the inscription */
1655 		strnfcat(buf, max, &len, " {empty}");
1656 	}
1657 
1658 	/* Note "tried" if the object has been tested unsuccessfully */
1659 	else if (!aware && object_tried_p(o_ptr))
1660 	{
1661 		/* Append the inscription */
1662 		strnfcat(buf, max, &len, " {tried}");
1663 	}
1664 
1665 	/* Note the discount, if any */
1666 	else if (o_ptr->discount)
1667 	{
1668 		/* Append the inscription */
1669 		strnfcat(buf, max, &len, " {%d%% off}", o_ptr->discount);
1670 	}
1671 }
1672 
1673 /*
1674  * Wrapper around object_desc() for the '%v'
1675  * format option.  This allows object_desc() to be
1676  * called in a format string.
1677  *
1678  * The parameters are object_type (o_ptr), pref (int), mode(int).
1679  */
object_fmt(char * buf,uint max,cptr fmt,va_list * vp)1680 void object_fmt(char *buf, uint max, cptr fmt, va_list *vp)
1681 {
1682 	const object_type *o_ptr;
1683 	int pref;
1684 	int mode;
1685 
1686 	/* Unused parameter */
1687 	(void)fmt;
1688 
1689 	/* Get the object */
1690 	o_ptr = va_arg(*vp, const object_type*);
1691 
1692 	/* Get the pref */
1693 	pref = va_arg(*vp, int);
1694 
1695 	/* Get the mode */
1696 	mode = va_arg(*vp, int);
1697 
1698 	object_desc(buf, o_ptr, pref, mode, max);
1699 }
1700 
1701 
1702 /*
1703  * Hack -- describe an item currently in a store's inventory
1704  * This allows an item to *look* like the player is "aware" of it
1705  */
object_desc_store(char * buf,const object_type * o_ptr,int pref,int mode,int size)1706 void object_desc_store(char *buf, const object_type *o_ptr, int pref,
1707                        int mode, int size)
1708 {
1709 	byte hack_flavor;
1710 	bool hack_aware;
1711 	byte info;
1712 
1713 	/* Hack - we will reset the object to exactly like it was */
1714 	object_type *q_ptr = (object_type *)o_ptr;
1715 
1716 	/* Save the "flavor" */
1717 	hack_flavor = k_info[o_ptr->k_idx].flavor;
1718 
1719 	/* Save the "aware" flag */
1720 	hack_aware = k_info[o_ptr->k_idx].aware;
1721 
1722 	/* Save the "info" */
1723 	info = o_ptr->info;
1724 
1725 	/* Clear the flavor */
1726 	k_info[o_ptr->k_idx].flavor = FALSE;
1727 
1728 	/* If this is a shop item or in you are in wizard mode play with objects */
1729 	if (q_ptr->info & OB_STOREB)
1730 	{
1731 		/* Make it known */
1732 		q_ptr->info |= (OB_KNOWN);
1733 
1734 		/* Force "aware" for description */
1735 		k_info[o_ptr->k_idx].aware = TRUE;
1736 	}
1737 
1738 	/* Describe the object */
1739 	object_desc(buf, q_ptr, pref, mode, size);
1740 
1741 	/* Restore "flavor" value */
1742 	k_info[o_ptr->k_idx].flavor = hack_flavor;
1743 
1744 	/* Restore "aware" flag */
1745 	k_info[o_ptr->k_idx].aware = hack_aware;
1746 
1747 	/* Restore the "info" */
1748 	q_ptr->info = info;
1749 }
1750 
1751 /*
1752  * Wrapper around object_desc_store() for the '%v'
1753  * format option.  This allows object_desc() to be
1754  * called in a format string.
1755  *
1756  * The parameters are object_type (o_ptr), pref (int), mode(int).
1757  */
object_store_fmt(char * buf,uint max,cptr fmt,va_list * vp)1758 void object_store_fmt(char *buf, uint max, cptr fmt, va_list *vp)
1759 {
1760 	const object_type *o_ptr;
1761 	int pref;
1762 	int mode;
1763 
1764 	/* Unused parameter */
1765 	(void)fmt;
1766 
1767 	/* Get the object */
1768 	o_ptr = va_arg(*vp, const object_type*);
1769 
1770 	/* Get the pref */
1771 	pref = va_arg(*vp, int);
1772 
1773 	/* Get the mode */
1774 	mode = va_arg(*vp, int);
1775 
1776 	object_desc_store(buf, o_ptr, pref, mode, max);
1777 }
1778 
1779