root/trunk/src/obj-make.c

Revision 907, 31.9 kB (checked in by takkaria, 6 hours ago)

This is the big object list reordering. Savefile compat broken for sanity's sake. Graphics also broken, but will be fixed before release -- don't worry!

First off, this is an attempt to make the item list have a decent order, such that similar items are grouped together. Second, it's an attempt to make the object list more interesting; to remove needless duplication, purely bad items, and to add more variety. This involves a lot of things, which are summarised below. This is not a full changelog.

  • The mushrooms have been redesigned mostly from scratch. One mushroom (Sprinting) doesn't have an implementation right now.
  • Per suggestions on r.g.r.a, healing potions now have significant nutritional content.
  • Use enums in tvalsval.h rather than #defines.

#312:

  • Make scrolls appear in piles sometimes.

#313:

  • Changes here have been made already; the three temporary new mentioned have not been added but will be.

#316:

  • Tone down Rods of Fire Bolts a little.
  • Make rods start at dlev8 at the earliest.
  • Object/Treasure detection merged some time ago now.
  • Don't remove staff of CLW or steal anything from OAngband.

#320: (Rings)

  • Sustain rings combined
  • Bad rings removed
  • Give elemental rings brands, though currently non-functional
  • Add a whole bunch of rings based mostly on suggestions from the forum and r.g.r.a

#321: (Amulets)

  • DOOM removed
  • Adornment made rarer
  • Resistance kept
  • Amulet of Inertia kept (FA, but -3 speed)

#350: (Scrolls)

  • ?Deep descent added.
  • Redundant scrolls can stay; not too much of an issue.

#445: (Combat gear)

  • Body armour changes:
    • There are now only 17 types of body armour.
    • Body armour ACs are even-numbered until you reach the very top-end.
  • Footwear changes:
    • Footwear now goes: leather sandals -> boots -> iron shod -> steel shod -> mithril shod.
    • Add some Ethereal Slippers. (weightless, no AC, ignore elements)
  • Handwear changes:
    • Gauntlets now base AC of 3
    • Mithril Gauntlets with IGNORE_ACID, base AC 5
    • Cesti -> Caestus, now base AC 2 but +3 to-dam (brass knuckles)
    • Add Alchemist's Gloves, which ignore the elements and have only magical AC
    • Add commented-out Mining Gloves
  • Shield changes:
    • Shields now go: Wicker -> Small Metal -> Leather -> Large Metal -> Mithril
    • ACs of the above are 2, 4, 6, 8, 10
    • Weights adjusted so they go from 3lbs to 15lbs.
  • Cloak changes:
    • Shadow Cloak -> Elven Cloak, add stealth.
    • Add Ethereal Cloak, ignores elements and weighs nothing (but also 0 AC).
    • Add Fur Cloak, base AC of 3 but heavy.
  • Weapon changes:
    • Remove Gnomish Shovel, Dwarven Shovel, Pick, Dwarven Pick.
    • Remove the Sabre; tweak artifacts to use rapier.
    • Remove broken daggers/swords (and Narsil).
    • Return the Great in Two-Handed "Great" Flail. Rename Two-Handed to Zweihander. (Moria)
    • Merge short + small swords. Remove damage duplication between swords.
    • Add a Great Hammer (8d1), and a Maul (4d4).
    • Make Tridents 1d10.

#540: (Tweak the Elven rings again)

  • give Narya back resist fear
  • give Nenya sustain con
  • remove sust str/wis from Vilya but add sust con. (based on a suggestion by Timo)
Line 
1 /*
2  * File: obj-make.c
3  * Purpose: Object generation functions.
4  *
5  * Copyright (c) 1987-2007 Angband contributors
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 #include "angband.h"
19 #include "tvalsval.h"
20
21
22 static u32b obj_total[MAX_DEPTH];
23 static byte *obj_alloc;
24
25 /* Don't worry about probabilities for anything past dlev100 */
26 #define MAX_O_DEPTH             100
27
28 /*
29  * Free object allocation info.
30  */
31 void free_obj_alloc(void)
32 {
33         FREE(obj_alloc);
34 }
35
36
37 /*
38  * Using k_info[], init rarity data for the entire dungeon.
39  */
40 bool init_obj_alloc(void)
41 {
42         int k_max = z_info->k_max;
43         int item, lev;
44
45
46         /* Free obj_allocs if allocated */
47         FREE(obj_alloc);
48
49         /* Allocate and wipe */
50         obj_alloc = C_ZNEW((MAX_O_DEPTH + 1) * k_max, byte);
51
52         /* Wipe the totals */
53         C_WIPE(obj_total, MAX_O_DEPTH + 1, u32b);
54
55
56         /* Init allocation data */
57         for (item = 1; item < k_max; item++)
58         {
59                 object_kind *k_ptr = &k_info[item];
60
61                 int min = k_ptr->alloc_min;
62                 int max = k_ptr->alloc_max;
63
64                 /* If an item doesn't have a rarity, move on */
65                 if (!k_ptr->alloc_prob) continue;
66
67                 /* Go through all the dungeon levels */
68                 for (lev = 0; lev <= MAX_O_DEPTH; lev++)
69                 {
70                         int rarity = k_ptr->alloc_prob;
71
72                         /* Give out-of-depth items a tiny chance at being made */
73                         if ((lev < min) || (lev > max)) rarity = 0;
74
75                         /* Save the probability */
76                         obj_total[lev] += rarity;
77                         obj_alloc[(lev * k_max) + item] = rarity;
78                 }
79         }
80
81         return TRUE;
82 }
83
84
85
86
87 /*
88  * Choose an object kind given a dungeon level to choose it for.
89  */
90 s16b get_obj_num(int level)
91 {
92         /* This is the base index into obj_alloc for this dlev */
93         size_t ind, item;
94         u32b value;
95
96         /* Occasional level boost */
97         if ((level > 0) && one_in_(GREAT_OBJ))
98         {
99                 /* What a bizarre calculation */
100                 level = 1 + (level * MAX_O_DEPTH / randint1(MAX_O_DEPTH));
101         }
102
103         /* Paranoia */
104         level = MIN(level, MAX_O_DEPTH);
105         level = MAX(level, 0);
106
107         /* Pick an object */
108         ind = level * z_info->k_max;
109         value = randint0(obj_total[level]);
110         for (item = 1; item < z_info->k_max; item++)
111         {
112                 /* Found it */
113                 if (value < obj_alloc[ind + item]) break;
114
115                 /* Decrement */
116                 value -= obj_alloc[ind + item];
117         }
118
119
120         /* Return the item index */
121         return item;
122 }
123
124
125
126
127 /*
128  * Help determine an "enchantment bonus" for an object.
129  *
130  * To avoid floating point but still provide a smooth distribution of bonuses,
131  * we simply round the results of division in such a way as to "average" the
132  * correct floating point value.
133  *
134  * This function has been changed.  It uses "Rand_normal()" to choose values
135  * from a normal distribution, whose mean moves from zero towards the max as
136  * the level increases, and whose standard deviation is equal to 1/4 of the
137  * max, and whose values are forced to lie between zero and the max, inclusive.
138  *
139  * Since the "level" rarely passes 100 before Morgoth is dead, it is very
140  * rare to get the "full" enchantment on an object, even a deep levels.
141  *
142  * It is always possible (albeit unlikely) to get the "full" enchantment.
143  *
144  * A sample distribution of values from "m_bonus(10, N)" is shown below:
145  *
146  *   N       0     1     2     3     4     5     6     7     8     9    10
147  * ---    ----  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----
148  *   0   66.37 13.01  9.73  5.47  2.89  1.31  0.72  0.26  0.12  0.09  0.03
149  *   8   46.85 24.66 12.13  8.13  4.20  2.30  1.05  0.36  0.19  0.08  0.05
150  *  16   30.12 27.62 18.52 10.52  6.34  3.52  1.95  0.90  0.31  0.15  0.05
151  *  24   22.44 15.62 30.14 12.92  8.55  5.30  2.39  1.63  0.62  0.28  0.11
152  *  32   16.23 11.43 23.01 22.31 11.19  7.18  4.46  2.13  1.20  0.45  0.41
153  *  40   10.76  8.91 12.80 29.51 16.00  9.69  5.90  3.43  1.47  0.88  0.65
154  *  48    7.28  6.81 10.51 18.27 27.57 11.76  7.85  4.99  2.80  1.22  0.94
155  *  56    4.41  4.73  8.52 11.96 24.94 19.78 11.06  7.18  3.68  1.96  1.78
156  *  64    2.81  3.07  5.65  9.17 13.01 31.57 13.70  9.30  6.04  3.04  2.64
157  *  72    1.87  1.99  3.68  7.15 10.56 20.24 25.78 12.17  7.52  4.42  4.62
158  *  80    1.02  1.23  2.78  4.75  8.37 12.04 27.61 18.07 10.28  6.52  7.33
159  *  88    0.70  0.57  1.56  3.12  6.34 10.06 15.76 30.46 12.58  8.47 10.38
160  *  96    0.27  0.60  1.25  2.28  4.30  7.60 10.77 22.52 22.51 11.37 16.53
161  * 104    0.22  0.42  0.77  1.36  2.62  5.33  8.93 13.05 29.54 15.23 22.53
162  * 112    0.15  0.20  0.56  0.87  2.00  3.83  6.86 10.06 17.89 27.31 30.27
163  * 120    0.03  0.11  0.31  0.46  1.31  2.48  4.60  7.78 11.67 25.53 45.72
164  * 128    0.02  0.01  0.13  0.33  0.83  1.41  3.24  6.17  9.57 14.22 64.07
165  */
166 static s16b m_bonus(int max, int level)
167 {
168         int bonus, stand, extra, value;
169
170
171         /* Paranoia -- enforce maximal "level" */
172         if (level > MAX_DEPTH - 1) level = MAX_DEPTH - 1;
173
174
175         /* The "bonus" moves towards the max */
176         bonus = ((max * level) / MAX_DEPTH);
177
178         /* Hack -- determine fraction of error */
179         extra = ((max * level) % MAX_DEPTH);
180
181         /* Hack -- simulate floating point computations */
182         if (randint0(MAX_DEPTH) < extra) bonus++;
183
184
185         /* The "stand" is equal to one quarter of the max */
186         stand = (max / 4);
187
188         /* Hack -- determine fraction of error */
189         extra = (max % 4);
190
191         /* Hack -- simulate floating point computations */
192         if (randint0(4) < extra) stand++;
193
194
195         /* Choose an "interesting" value */
196         value = Rand_normal(bonus, stand);
197
198         /* Enforce the minimum value */
199         if (value < 0) return (0);
200
201         /* Enforce the maximum value */
202         if (value > max) return (max);
203
204         /* Result */
205         return (value);
206 }
207
208
209
210
211 /*
212  * Cheat -- describe a created object for the user
213  */
214 static void object_mention(const object_type *o_ptr)
215 {
216         char o_name[80];
217
218         /* Describe */
219         object_desc_spoil(o_name, sizeof(o_name), o_ptr, FALSE, ODESC_BASE);
220
221         /* Provide a silly message */
222         if (artifact_p(o_ptr))
223                 msg_format("Artifact (%s)", o_name);
224         else if (ego_item_p(o_ptr))
225                 msg_format("Ego-item (%s)", o_name);
226         else
227                 msg_format("Object (%s)", o_name);
228 }
229
230
231 /*
232  * Attempt to change an object into an ego-item -MWK-
233  * Better only called by apply_magic().
234  * The return value says if we picked a cursed item (if allowed) and is
235  * passed on to a_m_aux1/2().
236  * If no legal ego item is found, this routine returns 0, resulting in
237  * an unenchanted item.
238  */
239 static int make_ego_item(object_type *o_ptr, int level, bool force_uncursed)
240 {
241         int i, j;
242
243         int e_idx;
244
245         long value, total;
246
247         ego_item_type *e_ptr;
248
249         alloc_entry *table = alloc_ego_table;
250
251
252         /* Fail if object already is ego or artifact */
253         if (o_ptr->name1) return (FALSE);
254         if (o_ptr->name2) return (FALSE);
255
256         /* Boost level (like with object base types) */
257         if (level > 0)
258         {
259                 /* Occasional "boost" */
260                 if (one_in_(GREAT_EGO))
261                 {
262                         /* The bizarre calculation again */
263                         level = 1 + (level * MAX_DEPTH / randint1(MAX_DEPTH));
264                 }
265         }
266
267         /* Reset total */
268         total = 0L;
269
270         /* Process probabilities */
271         for (i = 0; i < alloc_ego_size; i++)
272         {
273                 /* Default */
274                 table[i].prob3 = 0;
275
276                 /* Objects are sorted by depth */
277                 if (table[i].level > level) continue;
278
279                 /* Get the index */
280                 e_idx = table[i].index;
281
282                 /* Get the actual kind */
283                 e_ptr = &e_info[e_idx];
284
285                 /* Avoid cursed items if specified */
286                 if (force_uncursed && (e_ptr->flags3 & TR3_LIGHT_CURSE)) continue;
287
288                 /* Test if this is a legal ego-item type for this object */
289                 for (j = 0; j < EGO_TVALS_MAX; j++)
290                 {
291                         /* Require identical base type */
292                         if (o_ptr->tval == e_ptr->tval[j])
293                         {
294                                 /* Require sval in bounds, lower */
295                                 if (o_ptr->sval >= e_ptr->min_sval[j])
296                                 {
297                                         /* Require sval in bounds, upper */
298                                         if (o_ptr->sval <= e_ptr->max_sval[j])
299                                         {
300                                                 /* Accept */
301                                                 table[i].prob3 = table[i].prob2;
302                                         }
303                                 }
304                         }
305                 }
306
307                 /* Total */
308                 total += table[i].prob3;
309         }
310
311         /* No legal ego-items -- create a normal unenchanted one */
312         if (total == 0) return (0);
313
314
315         /* Pick an ego-item */
316         value = randint0(total);
317
318         /* Find the object */
319         for (i = 0; i < alloc_ego_size; i++)
320         {
321                 /* Found the entry */
322                 if (value < table[i].prob3) break;
323
324                 /* Decrement */
325                 value = value - table[i].prob3;
326         }
327
328         /* We have one */
329         e_idx = (byte)table[i].index;
330         o_ptr->name2 = e_idx;
331
332         return ((e_info[e_idx].flags3 & TR3_LIGHT_CURSE) ? -2 : 2);
333 }
334
335
336 /**
337  * Copy artifact data to a normal object, and set various slightly hacky
338  * globals.
339  */
340 static void copy_artifact_data(object_type *o_ptr, artifact_type *a_ptr)
341 {
342         /* Hack -- Mark the artifact as "created" */
343         a_ptr->cur_num = 1;
344
345         /* Extract the other fields */
346         o_ptr->pval = a_ptr->pval;
347         o_ptr->ac = a_ptr->ac;
348         o_ptr->dd = a_ptr->dd;
349         o_ptr->ds = a_ptr->ds;
350         o_ptr->to_a = a_ptr->to_a;
351         o_ptr->to_h = a_ptr->to_h;
352         o_ptr->to_d = a_ptr->to_d;
353         o_ptr->weight = a_ptr->weight;
354
355         /* Hack -- extract the "cursed" flag */
356         if (a_ptr->flags3 & TR3_LIGHT_CURSE)
357                 o_ptr->flags3 |= TR3_LIGHT_CURSE;
358
359         /* Mega-Hack -- increase the rating */
360         rating += 10;
361
362         /* Mega-Hack -- increase the rating again */
363         if (a_ptr->cost > 50000L) rating += 10;
364
365         /* Set the good item flag */
366         good_item_flag = TRUE;
367
368         /* Cheat -- peek at the item */
369         if (cheat_peek) object_mention(o_ptr);
370 }
371
372
373 /*
374  * Mega-Hack -- Attempt to create one of the "Special Objects".
375  *
376  * We are only called from "make_object()", and we assume that
377  * "apply_magic()" is called immediately after we return.
378  *
379  * Note -- see "make_artifact()" and "apply_magic()".
380  *
381  * We *prefer* to create the special artifacts in order, but this is
382  * normally outweighed by the "rarity" rolls for those artifacts.  The
383  * only major effect of this logic is that the Phial (with rarity one)
384  * is always the first special artifact created.
385  */
386 static bool make_artifact_special(object_type *o_ptr, int level)
387 {
388         int i;
389
390         int k_idx;
391
392
393         /* No artifacts, do nothing */
394         if (adult_no_artifacts) return (FALSE);
395
396         /* No artifacts in the town */
397         if (!p_ptr->depth) return (FALSE);
398
399         /* Check the special artifacts */
400         for (i = 0; i < ART_MIN_NORMAL; ++i)
401         {
402                 artifact_type *a_ptr = &a_info[i];
403
404                 /* Skip "empty" artifacts */
405                 if (!a_ptr->name) continue;
406
407                 /* Cannot make an artifact twice */
408                 if (a_ptr->cur_num) continue;
409
410                 /* Enforce minimum "depth" (loosely) */
411                 if (a_ptr->level > p_ptr->depth)
412                 {
413                         /* Get the "out-of-depth factor" */
414                         int d = (a_ptr->level - p_ptr->depth) * 2;
415
416                         /* Roll for out-of-depth creation */
417                         if (randint0(d) != 0) continue;
418                 }
419
420                 /* Artifact "rarity roll" */
421                 if (randint0(a_ptr->rarity) != 0) continue;
422
423                 /* Find the base object */
424                 k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
425
426                 /* Enforce minimum "object" level (loosely) */
427                 if (k_info[k_idx].level > level)
428                 {
429                         /* Get the "out-of-depth factor" */
430                         int d = (k_info[k_idx].level - level) * 5;
431
432                         /* Roll for out-of-depth creation */
433                         if (randint0(d) != 0) continue;
434                 }
435
436                 /* Assign the template */
437                 object_prep(o_ptr, k_idx);
438
439                 /* Mark the item as an artifact */
440                 o_ptr->name1 = i;
441
442                 /* Copy across all the data from the artifact struct */
443                 copy_artifact_data(o_ptr, a_ptr);
444
445                 /* Success */
446                 return TRUE;
447         }
448
449         /* Failure */
450         return FALSE;
451 }
452
453
454 /*
455  * Attempt to change an object into an artifact
456  *
457  * This routine should only be called by "apply_magic()"
458  *
459  * Note -- see "make_artifact_special()" and "apply_magic()"
460  */
461 static bool make_artifact(object_type *o_ptr)
462 {
463         int i;
464
465
466         /* No artifacts, do nothing */
467         if (adult_no_artifacts) return (FALSE);
468
469         /* No artifacts in the town */
470         if (!p_ptr->depth) return (FALSE);
471
472         /* Paranoia -- no "plural" artifacts */
473         if (o_ptr->number != 1) return (FALSE);
474
475         /* Check the artifact list (skip the "specials") */
476         for (i = ART_MIN_NORMAL; i < z_info->a_max; i++)
477         {
478                 artifact_type *a_ptr = &a_info[i];
479
480                 /* Skip "empty" items */
481                 if (!a_ptr->name) continue;
482
483                 /* Cannot make an artifact twice */
484                 if (a_ptr->cur_num) continue;
485
486                 /* Must have the correct fields */
487                 if (a_ptr->tval != o_ptr->tval) continue;
488                 if (a_ptr->sval != o_ptr->sval) continue;
489
490                 /* XXX XXX Enforce minimum "depth" (loosely) */
491                 if (a_ptr->level > p_ptr->depth)
492                 {
493                         /* Get the "out-of-depth factor" */
494                         int d = (a_ptr->level - p_ptr->depth) * 2;
495
496                         /* Roll for out-of-depth creation */
497                         if (randint0(d) != 0) continue;
498                 }
499
500                 /* We must make the "rarity roll" */
501                 if (randint0(a_ptr->rarity) != 0) continue;
502
503                 /* Mark the item as an artifact */
504                 o_ptr->name1 = i;
505
506                 /* Copy across all the data from the artifact struct */
507                 copy_artifact_data(o_ptr, a_ptr);
508
509                 return TRUE;
510         }
511
512         return FALSE;
513 }
514
515
516
517
518 /*
519  * Apply magic to an item known to be a "weapon"
520  *
521  * Hack -- note special base damage dice boosting
522  * Hack -- note special processing for weapon/digger
523  * Hack -- note special rating boost for dragon scale mail
524  */
525 static void a_m_aux_1(object_type *o_ptr, int level, int power)
526 {
527         int tohit1 = randint1(5) + m_bonus(5, level);
528         int tohit2 = m_bonus(10, level);
529
530         int todam1 = randint1(5) + m_bonus(5, level);
531         int todam2 = m_bonus(10, level);
532
533         switch (power)
534         {
535                 case -2:
536                         o_ptr->to_h -= tohit2;
537                         o_ptr->to_d -= todam2;
538
539                 case -1:
540                         o_ptr->to_h -= tohit1;
541                         o_ptr->to_d -= todam1;
542                         break;
543
544                 case 2:
545                         o_ptr->to_h += tohit2;
546                         o_ptr->to_d += todam2;
547
548                 case 1:
549                         o_ptr->to_h += tohit1;
550                         o_ptr->to_d += todam1;
551                         break;
552         }
553
554
555         /* Analyze type */
556         switch (o_ptr->tval)
557         {
558                 case TV_DIGGING:
559                 {
560                         /* Very bad */
561                         if (power < -1)
562                         {
563                                 /* Hack -- Horrible digging bonus */
564                                 o_ptr->pval = 0 - (5 + randint1(5));
565                         }
566
567                         /* Bad */
568                         else if (power < 0)
569                         {
570                                 /* Hack -- Reverse digging bonus */
571                                 o_ptr->pval = -o_ptr->pval;
572                         }
573
574                         break;
575                 }
576
577
578                 case TV_HAFTED:
579                 case TV_POLEARM:
580                 case TV_SWORD:
581                 {
582                         /* Very Good */
583                         if (power > 1)
584                         {
585                                 /* Hack -- Super-charge the damage dice */
586                                 while ((o_ptr->dd * o_ptr->ds > 0) &&
587                                        one_in_(10L * o_ptr->dd * o_ptr->ds))
588                                 {
589                                         o_ptr->dd++;
590                                 }
591
592                                 /* Hack -- Lower the damage dice */
593                                 if (o_ptr->dd > 9) o_ptr->dd = 9;
594                         }
595
596                         break;
597                 }
598
599
600                 case TV_BOLT:
601                 case TV_ARROW:
602                 case TV_SHOT:
603                 {
604                         /* Very good */
605                         if (power > 1)
606                         {
607                                 /* Hack -- super-charge the damage dice */
608                                 while ((o_ptr->dd * o_ptr->ds > 0) &&
609                                        one_in_(10L * o_ptr->dd * o_ptr->ds))
610                                 {
611                                         o_ptr->dd++;
612                                 }
613
614                                 /* Hack -- restrict the damage dice */
615                                 if (o_ptr->dd > 9) o_ptr->dd = 9;
616                         }
617
618                         break;
619                 }
620         }
621 }
622
623
624 /*
625  * Apply magic to armour
626  */
627 static void a_m_aux_2(object_type *o_ptr, int level, int power)
628 {
629         int toac1 = randint1(5) + m_bonus(5, level);
630         int toac2 = m_bonus(10, level);
631
632
633         if (power == -2)
634                 o_ptr->to_a -= toac1 + toac2;
635         else if (power == -1)
636                 o_ptr->to_a -= toac1;
637         else if (power == 1)
638                 o_ptr->to_a += toac1;
639         else if (power == 2)
640                 o_ptr->to_a += toac1 + toac2;
641
642
643         /* Analyze type */
644         switch (o_ptr->tval)
645         {
646                 case TV_DRAG_ARMOR:
647                 {
648                         /* Rating boost */
649                         rating += 30;
650
651                         /* Mention the item */
652                         if (cheat_peek) object_mention(o_ptr);
653
654                         break;
655                 }
656         }
657 }
658
659
660
661 /*
662  * Apply magic to an item known to be a "ring" or "amulet"
663  *
664  * Hack -- note special rating boost for ring of speed
665  * Hack -- note special rating boost for certain amulets
666  * Hack -- note special "pval boost" code for ring of speed
667  * Hack -- note that some items must be cursed (or blessed)
668  */
669 static void a_m_aux_3(object_type *o_ptr, int level, int power)
670 {
671         if (power < 0)
672                 o_ptr->flags3 |= TR3_LIGHT_CURSE;
673
674         /* Apply magic (good or bad) according to type */
675         switch (o_ptr->tval)
676         {
677                 case TV_RING:
678                 {
679                         /* Analyze */
680                         switch (o_ptr->sval)
681                         {
682                                 /* Strength, Constitution, Dexterity, Intelligence */
683                                 case SV_RING_STRENGTH:
684                                 case SV_RING_CONSTITUTION:
685                                 case SV_RING_DEXTERITY:
686                                 case SV_RING_INTELLIGENCE:
687                                 {
688                                         /* Stat bonus */
689                                         o_ptr->pval = 1 + m_bonus(5, level);
690
691                                         /* Cursed */
692                                         if (power < 0)
693                                                 o_ptr->pval = -o_ptr->pval;
694
695                                         break;
696                                 }
697
698                                 /* Ring of Speed! */
699                                 case SV_RING_SPEED:
700                                 {
701                                         /* Base speed (1 to 10) */
702                                         o_ptr->pval = randint1(5) + m_bonus(5, level);
703
704                                         /* Super-charge the ring */
705                                         while (randint0(100) < 50) o_ptr->pval++;
706
707                                         /* Cursed Ring */
708                                         if (power < 0)
709                                         {
710                                                 /* Reverse pval */
711                                                 o_ptr->pval = -o_ptr->pval;
712                                         }
713                                         else
714                                         {
715                                                 /* Rating boost */
716                                                 rating += 25;
717
718                                                 /* Mention the item */
719                                                 if (cheat_peek) object_mention(o_ptr);
720                                         }
721
722                                         break;
723                                 }
724
725                                 /* Searching */
726                                 case SV_RING_SEARCHING:
727                                 {
728                                         /* Bonus to searching */
729                                         o_ptr->pval = 1 + m_bonus(5, level);
730
731                                         /* Cursed */
732                                         if (power < 0)
733                                                 o_ptr->pval = -o_ptr->pval;
734
735                                         break;
736                                 }
737
738                                 /* Light, Dark */
739                                 case SV_RING_LIGHT:
740                                 case SV_RING_DARK:
741                                 {
742                                         /* Searching bonus */
743                                         o_ptr->pval = 1 + m_bonus(5, level);
744
745                                         break;
746                                 }
747
748                                 /* Flames, Acid, Ice, Lightning */
749                                 case SV_RING_FLAMES:
750                                 case SV_RING_ACID:
751                                 case SV_RING_ICE:
752                                 case SV_RING_LIGHTNING:
753                                 {
754                                         /* Bonus to armor class */
755                                         o_ptr->to_a = 5 + randint1(5) + m_bonus(10, level);
756
757                                         break;
758                                 }
759
760                                 /* Ring of damage */
761                                 case SV_RING_DAMAGE:
762                                 {
763                                         /* Bonus to damage */
764                                         o_ptr->to_d = 5 + randint1(3) + m_bonus(7, level);
765
766                                         /* Cursed */
767                                         if (power < 0)
768                                                 o_ptr->to_d = -o_ptr->to_d;
769
770                                         break;
771                                 }
772
773                                 /* Ring of Accuracy */
774                                 case SV_RING_ACCURACY:
775                                 {
776                                         /* Bonus to hit */
777                                         o_ptr->to_h = 5 + randint1(3) + m_bonus(7, level);
778
779                                         /* Cursed */
780                                         if (power < 0)
781                                                 o_ptr->to_h = -o_ptr->to_h;
782
783                                         break;
784                                 }
785
786                                 /* Ring of Protection */
787                                 case SV_RING_PROTECTION:
788                                 {
789                                         /* Bonus to armor class */
790                                         o_ptr->to_a = 5 + randint1(5) + m_bonus(10, level);
791
792                                         /* Cursed */
793                                         if (power < 0)
794                                                 o_ptr->to_a = -o_ptr->to_a;
795
796                                         break;
797                                 }
798
799                                 /* Ring of Slaying */
800                                 case SV_RING_SLAYING:
801                                 {
802                                         /* Bonus to damage and to hit */
803                                         o_ptr->to_d = randint1(5) + m_bonus(5, level);
804                                         o_ptr->to_h = randint1(5) + m_bonus(5, level);
805
806                                         /* Cursed -- reverse bonuses */
807             &nbs