comparison xrogue/things.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children ce0cf824c192
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 things.c - functions for dealing with things like potions and scrolls
3
4 XRogue: Expeditions into the Dungeons of Doom
5 Copyright (C) 1991 Robert Pietkivitch
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <curses.h>
20 #include <ctype.h>
21 #include "rogue.h"
22
23 /*
24 * print out the number of charges on a stick
25 */
26
27 char *
28 charge_str(obj)
29 register struct object *obj;
30 {
31 static char buf[20];
32
33 if (!(obj->o_flags & ISKNOW))
34 buf[0] = '\0';
35 else if (terse)
36 sprintf(buf, " [%d]", obj->o_charges);
37 else
38 sprintf(buf, " [%d charges]", obj->o_charges);
39 return buf;
40 }
41
42 /*
43 * inv_name:
44 * return the name of something as it would appear in an
45 * inventory.
46 */
47
48 char *
49 inv_name(obj, drop)
50 register struct object *obj;
51 bool drop;
52 {
53 register char *pb;
54
55 pb = prbuf;
56 pb[0] = '\0';
57 switch(obj->o_type) {
58 case SCROLL:
59 if (obj->o_count == 1)
60 sprintf(pb, "A %sscroll ", blesscurse(obj->o_flags));
61 else
62 sprintf(pb, "%d %sscrolls ",
63 obj->o_count, blesscurse(obj->o_flags));
64 pb = &pb[strlen(pb)];
65 if (s_know[obj->o_which] || (obj->o_flags & ISPOST))
66 sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
67 else if (s_guess[obj->o_which])
68 sprintf(pb, "named %s", s_guess[obj->o_which]);
69 else
70 sprintf(pb, "titled '%s'", s_names[obj->o_which]);
71 when POTION:
72 if (obj->o_count == 1)
73 sprintf(pb, "A %spotion ", blesscurse(obj->o_flags));
74 else
75 sprintf(pb, "%d %spotions ",
76 obj->o_count, blesscurse(obj->o_flags));
77 pb = &pb[strlen(pb)];
78 if (p_know[obj->o_which])
79 sprintf(pb, "of %s (%s)", p_magic[obj->o_which].mi_name,
80 p_kind(obj));
81 else if (obj->o_flags & ISPOST)
82 sprintf(pb, "of %s", p_magic[obj->o_which].mi_name);
83 else if (p_guess[obj->o_which])
84 sprintf(pb, "named %s (%s)", p_guess[obj->o_which],
85 p_colors[obj->o_which]);
86 else {
87 pb = prbuf;
88 if (obj->o_count == 1)
89 sprintf(pb, "A%s %s potion",
90 vowelstr(p_colors[obj->o_which]),
91 p_colors[obj->o_which]);
92 else
93 sprintf(pb, "%d %s potions",
94 obj->o_count, p_colors[obj->o_which]);
95 }
96 when FOOD:
97 if (obj->o_count == 1)
98 sprintf(pb, "A%s %s", vowelstr(foods[obj->o_which].mi_name),
99 foods[obj->o_which].mi_name);
100 else
101 sprintf(pb, "%d %ss", obj->o_count,foods[obj->o_which].mi_name);
102 when WEAPON:
103 if (obj->o_count > 1)
104 sprintf(pb, "%d ", obj->o_count);
105 else
106 strcpy(pb, "A ");
107 pb = &pb[strlen(pb)];
108 if (obj->o_flags & ISKNOW) {
109 strcat(pb, num(obj->o_hplus, obj->o_dplus));
110 strcat (pb, " ");
111 }
112 strcat(pb, weaps[obj->o_which].w_name);
113 if (obj->o_count > 1)
114 strcat(pb, "s");
115 if (obj == cur_weapon)
116 strcat(pb, " (weapon in hand)");
117 if (obj->o_flags & ISPOISON)
118 strcat(pb, " {Poisoned}");
119 when ARMOR:
120 if (obj->o_flags & ISKNOW) {
121 strcat(pb, num(armors[obj->o_which].a_class - obj->o_ac, 0));
122 strcat(pb, " ");
123 }
124 strcat(pb, armors[obj->o_which].a_name);
125 if (obj == cur_armor)
126 strcat(pb, " (being worn)");
127 when STICK:
128 sprintf(pb, "A %s%s ",
129 blesscurse(obj->o_flags), ws_type[obj->o_which]);
130 pb = &pb[strlen(pb)];
131 if (ws_know[obj->o_which] || obj->o_flags & ISKNOW)
132 sprintf(pb, "of %s%s (%s)", ws_magic[obj->o_which].mi_name,
133 charge_str(obj), ws_made[obj->o_which]);
134 else if (obj->o_flags & ISPOST)
135 sprintf(pb, "of %s", ws_magic[obj->o_which].mi_name);
136 else if (ws_guess[obj->o_which])
137 sprintf(pb, "named %s (%s)", ws_guess[obj->o_which],
138 ws_made[obj->o_which]);
139 else {
140 pb = prbuf;
141 sprintf(pb, "A %s %s", ws_made[obj->o_which],
142 ws_type[obj->o_which]);
143 }
144 if (obj == cur_weapon)
145 strcat(prbuf, " (weapon in hand)");
146 when RING:
147 if (r_know[obj->o_which] || obj->o_flags & ISKNOW)
148 sprintf(pb, "A%s ring of %s (%s)", ring_num(obj),
149 r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
150 else if (obj->o_flags & ISPOST)
151 sprintf(pb, "A ring of %s", r_magic[obj->o_which].mi_name);
152 else if (r_guess[obj->o_which])
153 sprintf(pb, "A ring named %s (%s)",
154 r_guess[obj->o_which], r_stones[obj->o_which]);
155 else
156 sprintf(pb, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
157 r_stones[obj->o_which]);
158 if (obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] ||
159 obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4])
160 strcat(pb, " (on left hand)");
161 if (obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
162 obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4])
163 strcat(pb, " (on right hand)");
164 when RELIC:
165 if (obj->o_flags & ISKNOW)
166 switch(obj->o_which) {
167 case QUILL_NAGROM:
168 sprintf(pb, "%s%s", rel_magic[obj->o_which].mi_name,
169 charge_str(obj));
170 otherwise:
171 strcpy(pb, rel_magic[obj->o_which].mi_name);
172 }
173 else switch(obj->o_which) {
174 case MUSTY_DAGGER:
175 strcpy(pb, "Two very fine daggers marked MDDE");
176 when EMORI_CLOAK:
177 strcpy(pb, "A silk cloak");
178 when HEIL_ANKH:
179 strcpy(pb, "A golden ankh");
180 when MING_STAFF:
181 strcpy(pb, "A finely carved staff");
182 when ORCUS_WAND:
183 strcpy(pb, "A sparkling ivory wand");
184 when ASMO_ROD:
185 strcpy(pb, "A glistening ebony rod");
186 when YENDOR_AMULET:
187 strcpy(pb, "A silver amulet");
188 when STONEBONES_AMULET:
189 strcpy(pb, "A stone amulet");
190 when BRIAN_MANDOLIN:
191 strcpy(pb, "A gleaming mandolin");
192 when HRUGGEK_MSTAR:
193 strcpy(pb, "A silvery morning star");
194 when AXE_AKLAD:
195 strcpy(pb, "A jewel encrusted axe");
196 when QUILL_NAGROM:
197 strcpy(pb, "A bright white feather");
198 when GERYON_HORN:
199 strcpy(pb, "A jet black horn");
200 when YEENOGHU_FLAIL:
201 strcpy(pb, "A shimmering flail");
202 when SURTUR_RING:
203 strcpy(pb, "A fiery red ring");
204 when ALTERAN_CARD:
205 strcpy(pb, "A rectangular piece of wood");
206 otherwise:
207 strcpy(pb, "A wholly magical item");
208 }
209
210 /* Take care of wielding and wearing */
211 switch (obj->o_which) {
212 case EMORI_CLOAK:
213 if (cur_armor == NULL && cur_misc[WEAR_CLOAK] == NULL)
214 strcat(pb, " (being worn)");
215 if (obj->o_charges)
216 strcat(pb, " [charged]");
217 else
218 strcat(pb, " [discharged]");
219 when HEIL_ANKH:
220 if (cur_relic[HEIL_ANKH]) strcat(pb, " (in palm)");
221 when EYE_VECNA:
222 if (cur_relic[EYE_VECNA]) strcat(pb, " (in forehead)");
223 when STONEBONES_AMULET:
224 if (cur_relic[STONEBONES_AMULET])
225 strcat(pb, " (in chest)");
226 when YENDOR_AMULET:
227 if (cur_relic[YENDOR_AMULET])
228 strcat(pb, " (in chest)");
229 when MUSTY_DAGGER:
230 case HRUGGEK_MSTAR:
231 case AXE_AKLAD:
232 case YEENOGHU_FLAIL:
233 case MING_STAFF:
234 case ASMO_ROD:
235 case ORCUS_WAND:
236 if (cur_weapon == obj) strcat(pb, " (weapon in hand)");
237 when SURTUR_RING:
238 if (cur_relic[SURTUR_RING])
239 strcat(pb, " (in nose)");
240 }
241 when MM:
242 if (m_know[obj->o_which])
243 {
244 misc_name(pb,obj);
245 }
246 else {
247 switch (obj->o_which) {
248 case MM_JUG:
249 case MM_BEAKER:
250 case MM_KEOGHTOM:
251 strcpy(pb, "A crystalline jar");
252 when MM_BOOK:
253 case MM_SKILLS:
254 strcpy(pb, "A dusty book");
255 when MM_ELF_BOOTS:
256 case MM_DANCE:
257 strcpy(pb, "A pair of old boots");
258 when MM_BRACERS:
259 strcpy(pb, "A set of bracers");
260 when MM_OPEN:
261 case MM_HUNGER:
262 strcpy(pb, "A mysterious chime");
263 when MM_DISP:
264 case MM_R_POWERLESS:
265 case MM_PROTECT:
266 strcpy(pb, "A dark looking cloak");
267 when MM_DRUMS:
268 strcpy(pb, "A drum set");
269 when MM_DISAPPEAR:
270 case MM_CHOKE:
271 strcpy(pb, "A small pouch of dust");
272 when MM_G_DEXTERITY:
273 case MM_G_OGRE:
274 case MM_FUMBLE:
275 strcpy(pb, "A set of gauntlets");
276 when MM_ADAPTION:
277 case MM_JEWEL:
278 case MM_STRANGLE:
279 strcpy(pb, "A little necklace");
280 when MM_CRYSTAL:
281 strcpy(pb, "An unusual looking rock");
282 otherwise:
283 strcpy(pb, "A magical item");
284 }
285 if (m_guess[obj->o_which]) {
286 strcat(pb, " named: ");
287 strcat(pb, m_guess[obj->o_which]);
288 }
289 }
290 if (obj == cur_misc[WEAR_BOOTS] ||
291 obj == cur_misc[WEAR_BRACERS] ||
292 obj == cur_misc[WEAR_CLOAK] ||
293 obj == cur_misc[WEAR_GAUNTLET] ||
294 obj == cur_misc[WEAR_NECKLACE] ||
295 obj == cur_misc[WEAR_JEWEL])
296 strcat(pb, " (being worn)");
297 when GOLD:
298 sprintf(pb, "%d Pieces of Gold", obj->o_count);
299 otherwise:
300 debug("Picked up something funny");
301 sprintf(pb, "Something totally bizarre %s", unctrl(obj->o_type));
302 wait_for(' ');
303 }
304
305 /* Is it marked? */
306 if (obj->o_mark[0]) {
307 pb = &pb[strlen(pb)];
308 sprintf(pb, " <%s>", obj->o_mark);
309 }
310
311 if (obj->o_flags & ISPROT)
312 strcat(pb, " [protected]");
313 if (drop && isupper(prbuf[0]))
314 prbuf[0] = tolower(prbuf[0]);
315 else if (!drop && islower(*prbuf))
316 *prbuf = toupper(*prbuf);
317 if (!drop)
318 strcat(pb, ".");
319 /*
320 * Truncate if long. Use cols-4 to offset the "pack letter" of a normal
321 * inventory listing.
322 */
323 prbuf[cols-4] = '\0';
324 return prbuf;
325 }
326
327 /*
328 * weap_name:
329 * Return the name of a weapon.
330 */
331
332 char *
333 weap_name(obj)
334 register struct object *obj;
335 {
336 switch (obj->o_type) {
337 case WEAPON:
338 return(weaps[obj->o_which].w_name);
339 when MISSILE:
340 return(ws_magic[obj->o_which].mi_name);
341 when RELIC:
342 switch (obj->o_which) {
343 case MUSTY_DAGGER:
344 return("daggers");
345 when YEENOGHU_FLAIL:
346 return("flail");
347 when AXE_AKLAD:
348 return("axe");
349 when HRUGGEK_MSTAR:
350 return("morning star");
351 when MING_STAFF:
352 return("staff");
353 when ORCUS_WAND:
354 return("wand");
355 when ASMO_ROD:
356 return("rod");
357 }
358 }
359 return("weapon");
360 }
361
362 /*
363 * drop:
364 * put something down
365 */
366
367 drop(item)
368 struct linked_list *item;
369 {
370 register char ch = 0;
371 register struct linked_list *obj, *nobj;
372 register struct object *op;
373
374 if (item == NULL) {
375 /* We charge 2 movement times to drop something */
376 if (player.t_action == C_DROP && player.t_using != NULL) {
377 obj = player.t_using;
378 player.t_using = NULL;
379 player.t_action = A_NIL;
380 }
381
382 /* t_action == C_DROP always when called from command() */
383 else {
384 if ((obj = get_item(pack, "drop", ALL, FALSE, FALSE)) == NULL) {
385 player.t_action = A_NIL;
386 player.t_using = NULL;
387 return(FALSE);
388 }
389 if (player.t_action == C_DROP) {
390 player.t_using = obj;
391 player.t_no_move = 2 * movement(&player);
392 return(FALSE); /* We'll come back after we've waited */
393 }
394 }
395
396 switch(ch = mvwinch(stdscr, hero.y, hero.x)) {
397 case PASSAGE:
398 case SCROLL:
399 case POTION:
400 case WEAPON:
401 case FLOOR:
402 case STICK:
403 case ARMOR:
404 case POOL:
405 case RELIC:
406 case GOLD:
407 case FOOD:
408 case RING:
409 case MM:
410 break;
411 default:
412 msg("You can't leave it here");
413 return(FALSE);
414 }
415 }
416 else {
417 obj = item;
418 }
419 op = OBJPTR(obj);
420 if (!dropcheck(op))
421 return(FALSE);
422
423 /*
424 * If it is a scare monster scroll, curse it
425 */
426 if (op->o_type == SCROLL && op->o_which == S_SCARE) {
427 if (op->o_flags & ISBLESSED)
428 op->o_flags &= ~ISBLESSED;
429 else op->o_flags |= ISCURSED;
430 }
431
432 /*
433 * Take it out of the pack
434 */
435 if (op->o_count >= 2 && op->o_group == 0)
436 {
437 nobj = new_item(sizeof *op);
438 op->o_count--;
439 op = OBJPTR(nobj);
440 *op = *(OBJPTR(obj));
441 op->o_count = 1;
442 obj = nobj;
443 }
444 else {
445 detach(pack, obj);
446 inpack--;
447 }
448 if(ch == POOL) {
449 msg("Gloop... Your %s sinks out of sight. ",inv_name(op,TRUE));
450 o_discard(obj);
451 }
452 else if (levtype == POSTLEV) {
453 op->o_pos = hero; /* same place as hero */
454 fall(obj,FALSE);
455 if (item == NULL) /* if item wasn't sold */
456 msg("Thanks for your donation to the Fiend's flea market.");
457 }
458 else {
459 /*
460 * Link it into the level object list
461 */
462 attach(lvl_obj, obj);
463 mvaddch(hero.y, hero.x, op->o_type);
464 op->o_pos = hero;
465 msg("Dropped %s", inv_name(op, TRUE));
466 }
467 updpack(FALSE, &player);
468 return (TRUE);
469 }
470
471 /*
472 * do special checks for dropping or unweilding|unwearing|unringing
473 */
474
475 dropcheck(op)
476 register struct object *op;
477 {
478 int save_max;
479
480 if (op == NULL)
481 return TRUE;
482 if (levtype == POSTLEV) {
483 if ((op->o_flags & ISCURSED) && (op->o_flags & ISKNOW)) {
484 msg("The trader does not accept shoddy merchandise.");
485 return(FALSE);
486 }
487 }
488
489 /* Player will not drop a relic */
490 if (op->o_type == RELIC) {
491 /*
492 * There is a 1% cumulative chance per relic that trying to get
493 * rid of it will cause the relic to turn on the player.
494 */
495 if (rnd(150) < cur_relic[op->o_which]++) {
496 msg("The artifact turns on you! ");
497 msg("It crushes your mind!!! --More--");
498 pstats.s_hpt = -1;
499 wait_for (' ');
500 death(D_RELIC);
501 }
502 else {
503 if (terse) msg("You can't release it.");
504 else msg("You cannot bring yourself to release it.");
505 return FALSE;
506 }
507 }
508
509 /* If we aren't wearing it, we can drop it */
510 if (!is_current(op)) return TRUE;
511
512 /* At this point, we know we are wearing the item */
513 if (op->o_flags & ISCURSED) {
514 msg("You can't. It appears to be cursed.");
515 return FALSE;
516 }
517 if (op->o_type == RING && cur_misc[WEAR_GAUNTLET] != NULL) {
518 msg ("You have to remove your gauntlets first!");
519 return FALSE;
520 }
521 cur_null(op); /* set current to NULL */
522 if (op->o_type == RING) {
523 switch (op->o_which) {
524 case R_ADDSTR: save_max = max_stats.s_str;
525 chg_str(-op->o_ac);
526 max_stats.s_str = save_max;
527 when R_ADDHIT: pstats.s_dext -= op->o_ac;
528 when R_ADDINTEL: pstats.s_intel -= op->o_ac;
529 when R_ADDWISDOM: pstats.s_wisdom -= op->o_ac;
530 when R_SEEINVIS: if (!ISWEARING(R_SEEINVIS) &&
531 find_slot(unsee) == 0) {
532 turn_off(player, CANSEE);
533 msg("The tingling feeling leaves your eyes. ");
534 }
535 light(&hero);
536 mvwaddch(cw, hero.y, hero.x, PLAYER);
537 when R_WARMTH: if (!ISWEARING(R_WARMTH) && !find_slot(nocold))
538 turn_off(player, NOCOLD);
539 when R_FIRE: if (!ISWEARING(R_FIRE) &&
540 !cur_relic[SURTUR_RING] &&
541 !find_slot(nofire))
542 turn_off(player, NOFIRE);
543 when R_LIGHT: {
544 if(roomin(&hero) != NULL) {
545 light(&hero);
546 mvwaddch(cw, hero.y, hero.x, PLAYER);
547 }
548 }
549 when R_SEARCH: kill_daemon(ring_search);
550 when R_TELEPORT: kill_daemon(ring_teleport);
551 }
552 }
553 else if (op->o_type == MM) {
554 switch (op->o_which) {
555 case MM_ADAPTION:
556 turn_off(player, NOGAS);
557 turn_off(player, NOACID);
558
559 when MM_STRANGLE:
560 msg("You can breathe again.....whew!");
561 kill_daemon(strangle);
562
563 when MM_DANCE:
564 turn_off(player, ISDANCE);
565 msg ("Your feet take a break.....whew!");
566
567 when MM_FUMBLE:
568 kill_daemon(fumble);
569
570 when MM_G_OGRE:
571 case MM_G_DEXTERITY:
572 save_max = max_stats.s_str;
573 chg_str(-op->o_ac);
574 max_stats.s_str = save_max;
575 }
576 }
577 return TRUE;
578 }
579
580 /*
581 * return a new thing
582 */
583
584 struct linked_list *
585 new_thing(thing_type, allow_curse)
586 int thing_type;
587 bool allow_curse;
588 {
589 register struct linked_list *item;
590 register struct object *cur;
591 register int j;
592 register int blesschance, cursechance;
593
594 item = new_item(sizeof *cur);
595 cur = OBJPTR(item);
596 cur->o_hplus = cur->o_dplus = 0;
597 strcpy(cur->o_damage,"0d0");
598 strcpy(cur->o_hurldmg,"0d0");
599 cur->o_ac = 0;
600 cur->o_count = 1;
601 cur->o_group = 0;
602 cur->contents = NULL;
603 cur->o_flags = 0;
604 cur->o_weight = 0;
605 cur->o_mark[0] = '\0';
606 /*
607 * Decide what kind of object it will be
608 * If we haven't had food for a while, let it be food.
609 */
610 blesschance = rnd(100);
611 if (allow_curse) cursechance = rnd(100);
612 else cursechance = 100; /* No chance of curse */
613
614 /* Get the type of item (pick one if 'any' is specified) */
615 if (thing_type == ALL) j = pick_one(things, NUMTHINGS);
616 else j = thing_type;
617
618 /*
619 * make sure he gets his vitamins
620 */
621 if (thing_type == ALL && no_food > 4)
622 j = 2;
623 /*
624 * limit the number of foods on a level because it sometimes
625 * gets out of hand in the "deep" levels where there is a
626 * treasure room on most every level with lots of food in it
627 */
628 while (thing_type == ALL && levtype != POSTLEV && foods_this_level > 1 &&
629 j == 2)
630 j = pick_one(things, NUMTHINGS); /* not too many.... */
631 switch (j)
632 {
633 case TYP_POTION:
634 cur->o_type = POTION;
635 do {
636 cur->o_which = pick_one(p_magic, MAXPOTIONS);
637 } while (!allow_curse && p_magic[cur->o_which].mi_curse == 100);
638 cur->o_weight = things[TYP_POTION].mi_wght;
639 if (cursechance < p_magic[cur->o_which].mi_curse)
640 cur->o_flags |= ISCURSED;
641 else if (blesschance < p_magic[cur->o_which].mi_bless)
642 cur->o_flags |= ISBLESSED;
643
644 /* If we made a gain ability potion, see what kind it is */
645 if (cur->o_which == P_ABIL) cur->o_kind = rnd(NUMABILITIES);
646
647 when TYP_SCROLL:
648 cur->o_type = SCROLL;
649 do {
650 cur->o_which = pick_one(s_magic, MAXSCROLLS);
651 } while (!allow_curse && s_magic[cur->o_which].mi_curse == 100);
652 cur->o_weight = things[TYP_SCROLL].mi_wght;
653 if (cursechance < s_magic[cur->o_which].mi_curse)
654 cur->o_flags |= ISCURSED;
655 else if (blesschance < s_magic[cur->o_which].mi_bless)
656 cur->o_flags |= ISBLESSED;
657 when TYP_FOOD:
658 no_food = 0;
659 cur->o_type = FOOD;
660 cur->o_weight = things[TYP_FOOD].mi_wght;
661 cur->o_count += extras();
662 foods_this_level += cur->o_count;
663 cur->o_which = pick_one(foods, MAXFOODS);
664 when TYP_WEAPON:
665 cur->o_type = WEAPON;
666 cur->o_which = rnd(MAXWEAPONS);
667 init_weapon(cur, cur->o_which);
668 if (cursechance < 20)
669 {
670
671 cur->o_flags |= ISCURSED;
672 cur->o_hplus -= rnd(3) + 1;
673 cur->o_dplus -= rnd(3) + 1;
674 }
675 else if (blesschance < 50) {
676
677 cur->o_hplus += rnd(5) + 1;
678 cur->o_dplus += rnd(5) + 1;
679 }
680 when TYP_ARMOR:
681 cur->o_type = ARMOR;
682 for (j = 0; j < MAXARMORS; j++)
683 if (blesschance < armors[j].a_prob)
684 break;
685 if (j == MAXARMORS)
686 {
687 debug("Picked a bad armor %d", blesschance);
688 wait_for(' ');
689 j = 0;
690 }
691 cur->o_which = j;
692 cur->o_ac = armors[j].a_class;
693 cur->o_weight = armors[j].a_wght;
694 if (cursechance < 20)
695 {
696 cur->o_flags |= ISCURSED;
697 cur->o_ac += rnd(4)+1;
698 }
699 else if (blesschance < 40)
700 cur->o_ac -= rnd(3)+1;
701 when TYP_RING:
702 cur->o_type = RING;
703 do {
704 cur->o_which = pick_one(r_magic, MAXRINGS);
705 } while (!allow_curse && r_magic[cur->o_which].mi_curse == 100);
706 cur->o_weight = things[TYP_RING].mi_wght;
707 if (cursechance < r_magic[cur->o_which].mi_curse)
708 cur->o_flags |= ISCURSED;
709 switch (cur->o_which)
710 {
711 case R_ADDSTR:
712 case R_ADDWISDOM:
713 case R_ADDINTEL:
714 case R_PROTECT:
715 case R_ADDHIT:
716 case R_ADDDAM:
717 cur->o_ac = rnd(2) + 1;
718 if (cur->o_flags & ISCURSED)
719 cur->o_ac = -cur->o_ac;
720 if (blesschance < r_magic[cur->o_which].mi_bless)
721 cur->o_ac+=rnd(vlevel/10)+1;
722 when R_DIGEST:
723 if (cur->o_flags & ISCURSED)
724 cur->o_ac = -1;
725 else if (blesschance < r_magic[cur->o_which].mi_bless)
726 cur->o_ac = 2;
727 else cur->o_ac = 1;
728 }
729 when TYP_STICK:
730 cur->o_type = STICK;
731 do {
732 cur->o_which = pick_one(ws_magic, MAXSTICKS);
733 } while (!allow_curse && ws_magic[cur->o_which].mi_curse == 100);
734 fix_stick(cur);
735 if (cursechance < ws_magic[cur->o_which].mi_curse)
736 cur->o_flags |= ISCURSED;
737 else if (blesschance < ws_magic[cur->o_which].mi_bless)
738 cur->o_flags |= ISBLESSED;
739 when TYP_MM:
740 cur->o_type = MM;
741 do {
742 cur->o_which = pick_one(m_magic, MAXMM);
743 } while (!allow_curse && m_magic[cur->o_which].mi_curse == 100);
744 cur->o_weight = things[TYP_MM].mi_wght;
745 if (cursechance < m_magic[cur->o_which].mi_curse)
746 cur->o_flags |= ISCURSED;
747 else if (blesschance < m_magic[cur->o_which].mi_bless)
748 cur->o_flags |= ISBLESSED;
749 switch (cur->o_which) {
750 case MM_JUG:
751 switch(rnd(11)) {
752 case 0: cur->o_ac = P_PHASE;
753 when 1: cur->o_ac = P_CLEAR;
754 when 2: cur->o_ac = P_SEEINVIS;
755 when 3: cur->o_ac = P_HEALING;
756 when 4: cur->o_ac = P_MFIND;
757 when 5: cur->o_ac = P_TFIND;
758 when 6: cur->o_ac = P_HASTE;
759 when 7: cur->o_ac = P_RESTORE;
760 when 8: cur->o_ac = P_FLY;
761 when 9: cur->o_ac = P_SKILL;
762 when 10:cur->o_ac = P_FFIND;
763 }
764 when MM_HUNGER:
765 case MM_CHOKE:
766 cur->o_ac = (2 + rnd(2)) * 3;
767 when MM_OPEN:
768 case MM_DRUMS:
769 case MM_DISAPPEAR:
770 case MM_KEOGHTOM:
771 cur->o_ac = (5 + rnd(6)) * 3;
772 when MM_BRACERS:
773 if (cur->o_flags & ISCURSED)
774 cur->o_ac = -(rnd(5)+1);
775 else
776 cur->o_ac = rnd(5)+1;
777 when MM_PROTECT:
778 if (cur->o_flags & ISCURSED)
779 cur->o_ac = -(rnd(5)+1);
780 else
781 cur->o_ac = rnd(5)+1;
782 when MM_DISP:
783 cur->o_ac = 3;
784 when MM_SKILLS: /* set it to a character class */
785 cur->o_ac = rnd(NUM_CHARTYPES-1);
786 when MM_CRYSTAL:
787 cur->o_ac = 1; /* Use it just once */
788 otherwise:
789 cur->o_ac = 0;
790 }
791 otherwise:
792 debug("Picked a bad kind of object");
793 wait_for(' ');
794 }
795 return item;
796 }
797
798 /*
799 * provide a new item tailored to specification
800 */
801
802 struct linked_list *
803 spec_item(type, which, hit, damage)
804 int type, which, hit, damage;
805 {
806 register struct linked_list *item;
807 register struct object *obj;
808
809 item = new_item(sizeof *obj);
810 obj = OBJPTR(item);
811 obj->o_count = 1;
812 obj->o_group = 0;
813 obj->contents = NULL;
814 obj->o_type = type;
815 obj->o_which = which;
816 strcpy(obj->o_damage,"0d0");
817 strcpy(obj->o_hurldmg,"0d0");
818 obj->o_hplus = 0;
819 obj->o_dplus = 0;
820 obj->o_flags = 0;
821 obj->o_mark[0] = '\0';
822 obj->o_launch = 0;
823 obj->o_weight = 0;
824
825 /* Handle special characteristics */
826 switch (type) {
827 case WEAPON:
828 init_weapon(obj, which);
829 obj->o_hplus = hit;
830 obj->o_dplus = damage;
831 obj->o_ac = 10;
832
833 if (hit < 0 || damage < 0) obj->o_flags |= ISCURSED;
834
835 when ARMOR:
836 obj->o_ac = armors[which].a_class - hit;
837 if (hit < 0) obj->o_flags |= ISCURSED;
838
839 when RING:
840 obj->o_ac = hit;
841 switch (obj->o_which) {
842 case R_ADDSTR:
843 case R_ADDWISDOM:
844 case R_ADDINTEL:
845 case R_PROTECT:
846 case R_ADDHIT:
847 case R_ADDDAM:
848 case R_DIGEST:
849 if (hit < 0) obj->o_flags |= ISCURSED;
850 }
851
852 when STICK:
853 fix_stick(obj);
854 obj->o_charges = hit;
855
856 when GOLD:
857 obj->o_type = GOLD;
858 obj->o_count = GOLDCALC;
859 obj->o_ac = 11;
860
861 when MM:
862 obj->o_type = MM;
863 obj->o_ac = hit;
864
865 when RELIC:
866 /* Handle weight here since these are all created uniquely */
867 obj->o_weight = things[TYP_RELIC].mi_wght;
868 if (obj->o_which == EMORI_CLOAK)
869 obj->o_charges = 1;
870
871 }
872 return(item);
873 }
874
875 /*
876 * pick an item out of a list of nitems possible magic items
877 */
878
879 pick_one(magic, nitems)
880 register struct magic_item *magic;
881 int nitems;
882 {
883 register struct magic_item *end;
884 register int i;
885 register struct magic_item *start;
886
887 start = magic;
888 for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
889 if (i < magic->mi_prob)
890 break;
891 if (magic == end)
892 {
893 if (wizard)
894 {
895 msg("bad pick_one: %d from %d items", i, nitems);
896 for (magic = start; magic < end; magic++)
897 msg("%s: %d%%", magic->mi_name, magic->mi_prob);
898 }
899 magic = start;
900 }
901 return magic - start;
902 }
903
904
905 /* blesscurse returns whether, according to the flag, the object is
906 * blessed, cursed, or neither
907 */
908
909 char *
910 blesscurse(flags)
911 int flags;
912 {
913 if (flags & ISKNOW) {
914 if (flags & ISCURSED) return("cursed ");
915 if (flags & ISBLESSED) return("blessed ");
916 return("normal ");
917 }
918 return("");
919 }
920
921 /*
922 * p_kind returns the type of potion for some types of identified potions;
923 * otherwise, it returns the color.
924 */
925
926 char *
927 p_kind(obj)
928 struct object *obj; /* We assume that obj points to a potion */
929 {
930 if (obj->o_which == P_ABIL) return(abilities[obj->o_kind].w_string);
931 else return(p_colors[obj->o_which]);
932 }
933
934 /*
935 * extras:
936 * Return the number of extra items to be created
937 */
938
939 extras()
940 {
941 reg int i;
942
943 i = rnd(100);
944 if (i < 3) /* 3% for 2 more */
945 return (2);
946 else if (i < 6) /* 6% for 1 more */
947 return (1);
948 else /* otherwise no more */
949 return (0);
950 }
951