comparison urogue/things.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children 5a94c9b3181e
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 things.c - functions for dealing with things like potions and scrolls
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
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 <string.h>
20 #include <ctype.h>
21 #include "rogue.h"
22
23 /*
24 inv_name()
25 return the name of something as it would appear in an inventory.
26 */
27
28 char *
29 inv_name(struct object *obj, int lowercase)
30 {
31 char *pb;
32 char buf[1024];
33
34 switch(obj->o_type)
35 {
36 case SCROLL:
37 if (obj->o_count == 1)
38 sprintf(prbuf, "A %s%sscroll ",
39 obj->o_flags & CANRETURN ? "claimed " : "",
40 blesscurse(obj->o_flags));
41 else
42 sprintf(prbuf, "%d %s%sscrolls ",
43 obj->o_count,
44 obj->o_flags & CANRETURN ? "claimed " : "",
45 blesscurse(obj->o_flags));
46
47 pb = &prbuf[strlen(prbuf)];
48
49 if (know_items[TYP_SCROLL][obj->o_which])
50 sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
51 else if (guess_items[TYP_SCROLL][obj->o_which])
52 sprintf(pb, "called %s", guess_items[TYP_SCROLL][obj->o_which]);
53 else
54 sprintf(pb, "titled '%s'", s_names[obj->o_which]);
55 break;
56
57 case POTION:
58 if (obj->o_count == 1)
59 sprintf(prbuf, "A %s%spotion ",
60 obj->o_flags & CANRETURN ? "claimed " : "",
61 blesscurse(obj->o_flags));
62 else
63 sprintf(prbuf, "%d %s%spotions ",
64 obj->o_count,
65 obj->o_flags & CANRETURN ? "claimed " : "",
66 blesscurse(obj->o_flags));
67
68 pb = &prbuf[strlen(prbuf)];
69
70 if (know_items[TYP_POTION][obj->o_which])
71 sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name,
72 p_colors[obj->o_which]);
73 else if (guess_items[TYP_POTION][obj->o_which])
74 sprintf(pb, "called %s(%s)", guess_items[TYP_POTION][obj->o_which],
75 p_colors[obj->o_which]);
76 else
77 {
78 if (obj->o_count == 1)
79 sprintf(prbuf, "A%s %s potion",
80 obj->o_flags & CANRETURN ? " claimed" :
81 (char *) vowelstr(p_colors[obj->o_which]),
82 p_colors[obj->o_which]);
83 else
84 sprintf(prbuf, "%d %s%s potions",
85 obj->o_count,
86 obj->o_flags & CANRETURN ? "claimed " : "",
87 (char *) p_colors[obj->o_which]);
88 }
89 break;
90
91 case FOOD:
92 if (obj->o_count == 1)
93 sprintf(prbuf, "A%s %s",
94 obj->o_flags & CANRETURN ? " claimed" :
95 (char *) vowelstr(fd_data[obj->o_which].mi_name),
96 fd_data[obj->o_which].mi_name);
97 else
98 sprintf(prbuf, "%d %s%ss", obj->o_count,
99 obj->o_flags & CANRETURN ? "claimed " : "",
100 fd_data[obj->o_which].mi_name);
101 break;
102
103 case WEAPON:
104 if (obj->o_count > 1)
105 sprintf(prbuf, "%d ", obj->o_count);
106 else if ((obj->o_flags & (ISZAPPED | CANRETURN | ISPOISON | ISSILVER | ISTWOH)) ||
107 ((obj->o_flags & (ISKNOW | ISZAPPED)) == (ISKNOW | ISZAPPED)))
108 strcpy(prbuf, "A ");
109 else
110 sprintf(prbuf, "A%s ", vowelstr(weaps[obj->o_which].w_name));
111
112 pb = &prbuf[strlen(prbuf)];
113
114 if ((obj->o_flags & ISKNOW) && (obj->o_flags & ISZAPPED))
115 sprintf(pb, "charged%s ", charge_str(obj,buf));
116
117 pb = &prbuf[strlen(prbuf)];
118
119 if (obj->o_flags & CANRETURN)
120 sprintf(pb, "claimed ");
121
122 pb = &prbuf[strlen(prbuf)];
123
124 if (obj->o_flags & ISPOISON)
125 sprintf(pb, "poisoned ");
126
127 pb = &prbuf[strlen(prbuf)];
128
129 if (obj->o_flags & ISSILVER)
130 sprintf(pb, "silver ");
131
132 if (obj->o_flags & ISTWOH)
133 sprintf(pb, "two-handed ");
134
135 pb = &prbuf[strlen(prbuf)];
136
137 if (obj->o_flags & ISKNOW)
138 sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus, buf),
139 weaps[obj->o_which].w_name);
140 else
141 sprintf(pb, "%s", weaps[obj->o_which].w_name);
142
143 if (obj->o_count > 1)
144 strcat(prbuf, "s");
145
146 break;
147
148 case ARMOR:
149 if (obj->o_flags & ISKNOW)
150 sprintf(prbuf, "%s%s %s",
151 obj->o_flags & CANRETURN ? "claimed " : "",
152 num(armors[obj->o_which].a_class - obj->o_ac, 0, buf),
153 armors[obj->o_which].a_name);
154 else
155 sprintf(prbuf, "%s%s",
156 obj->o_flags & CANRETURN ? "claimed " : "",
157 armors[obj->o_which].a_name);
158
159 break;
160
161 case ARTIFACT:
162 sprintf(prbuf, "the %s", arts[obj->o_which].ar_name);
163
164 if (obj->o_flags & CANRETURN)
165 strcat(prbuf, " (claimed)");
166
167 break;
168
169 case STICK:
170 sprintf(prbuf, "A %s%s%s ",
171 obj->o_flags & CANRETURN ? "claimed " : "",
172 blesscurse(obj->o_flags), ws_type[obj->o_which]);
173
174 pb = &prbuf[strlen(prbuf)];
175
176 if (know_items[TYP_STICK][obj->o_which])
177 sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name,
178 charge_str(obj,buf), ws_made[obj->o_which]);
179 else if (guess_items[TYP_STICK][obj->o_which])
180 sprintf(pb, "called %s(%s)", guess_items[TYP_STICK][obj->o_which],
181 ws_made[obj->o_which]);
182 else
183 sprintf(&prbuf[2], "%s%s %s",
184 obj->o_flags & CANRETURN ? "claimed " : "",
185 ws_made[obj->o_which],
186 ws_type[obj->o_which]);
187
188 break;
189
190 case RING:
191 if (know_items[TYP_RING][obj->o_which])
192 sprintf(prbuf, "A%s%s ring of %s(%s)",
193 obj->o_flags & CANRETURN ? " claimed" : "", ring_num(obj,buf),
194 r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
195 else if (guess_items[TYP_RING][obj->o_which])
196 sprintf(prbuf, "A %sring called %s(%s)",
197 obj->o_flags & CANRETURN ? "claimed " : "",
198 guess_items[TYP_RING][obj->o_which], r_stones[obj->o_which]);
199 else
200 sprintf(prbuf, "A%s %s ring",
201 obj->o_flags & CANRETURN ? "claimed " :
202 (char *)vowelstr(r_stones[obj->o_which]),
203 r_stones[obj->o_which]);
204 break;
205
206 case GOLD:
207 sprintf(prbuf, "%d gold pieces", obj->o_count);
208 break;
209
210 default:
211 debug("Picked up something funny.");
212 sprintf(prbuf, "Something bizarre %s", unctrl(obj->o_type));
213 break;
214 }
215
216 /* Is it marked? */
217
218 if (obj->o_mark[0])
219 {
220 pb = &prbuf[strlen(prbuf)];
221 sprintf(pb, " <%s>", obj->o_mark);
222 }
223
224 if (obj == cur_armor)
225 strcat(prbuf, " (being worn)");
226
227 if (obj == cur_weapon)
228 strcat(prbuf, " (weapon in hand)");
229
230 if (obj == cur_ring[LEFT_1])
231 strcat(prbuf, " (on left hand)");
232 else if (obj == cur_ring[LEFT_2])
233 strcat(prbuf, " (on left hand)");
234 else if (obj == cur_ring[LEFT_3])
235 strcat(prbuf, " (on left hand)");
236 else if (obj == cur_ring[LEFT_4])
237 strcat(prbuf, " (on left hand)");
238 else if (obj == cur_ring[LEFT_5])
239 strcat(prbuf, " (on left hand)");
240 else if (obj == cur_ring[RIGHT_1])
241 strcat(prbuf, " (on right hand)");
242 else if (obj == cur_ring[RIGHT_2])
243 strcat(prbuf, " (on right hand)");
244 else if (obj == cur_ring[RIGHT_3])
245 strcat(prbuf, " (on right hand)");
246 else if (obj == cur_ring[RIGHT_4])
247 strcat(prbuf, " (on right hand)");
248 else if (obj == cur_ring[RIGHT_5])
249 strcat(prbuf, " (on right hand)");
250
251 if (obj->o_flags & ISPROT)
252 strcat(prbuf, " [protected]");
253
254 if (lowercase && isupper(prbuf[0]))
255 prbuf[0] = (char) tolower(prbuf[0]);
256 else if (!lowercase && islower(*prbuf))
257 *prbuf = (char) toupper(*prbuf);
258
259 if (!lowercase)
260 strcat(prbuf, ".");
261
262 return(prbuf);
263 }
264
265 /*
266 rem_obj()
267 Remove an object from the level.
268 */
269
270 void
271 rem_obj(struct linked_list *item, int dis)
272 {
273 struct linked_list *llptr;
274 struct object *objptr, *op;
275 int x, y;
276
277 if (item == NULL)
278 return;
279
280 detach(lvl_obj, item);
281 objptr = OBJPTR(item);
282
283 if ( (llptr = objptr->next_obj) != NULL )
284 {
285 detach((objptr->next_obj), llptr);
286 attach(lvl_obj, llptr);
287
288 op = OBJPTR(llptr);
289
290 op->next_obj = objptr->next_obj;
291
292 if (op->next_obj)
293 objptr->next_obj->l_prev = NULL;
294
295 y = op->o_pos.y;
296 x = op->o_pos.x;
297
298 if (cansee(y, x))
299 mvwaddch(cw, y, x, op->o_type);
300
301 mvaddch(y, x, op->o_type);
302 }
303 else
304 {
305 y = objptr->o_pos.y;
306 x = objptr->o_pos.x;
307
308 /* problems if dropped in rock */
309
310 mvaddch(y,x,(roomin((objptr->o_pos)) == NULL ? PASSAGE : FLOOR));
311 }
312
313 if (dis)
314 discard(item);
315 }
316
317 /*
318 add_obj()
319 adds an object to the level
320 */
321
322 void
323 add_obj(struct linked_list *item, int y, int x)
324 {
325 struct linked_list *llptr;
326 struct object*objptr;
327
328 llptr = find_obj(y, x);
329
330 if (llptr)
331 {
332 objptr = OBJPTR(llptr);
333 attach((objptr->next_obj), item);
334 }
335 else
336 {
337 attach(lvl_obj, item);
338 objptr = OBJPTR(item);
339 objptr->next_obj = NULL;
340 objptr->o_pos.y = y;
341 objptr->o_pos.x = x;
342 mvaddch(y, x, objptr->o_type);
343 }
344 }
345
346 /*
347 drop()
348 put something down
349 */
350
351 int
352 drop(struct linked_list *item)
353 {
354 char ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
355 struct object *obj;
356
357 switch (ch)
358 {
359 case GOLD:
360 case POTION:
361 case SCROLL:
362 case FOOD:
363 case WEAPON:
364 case ARMOR:
365 case RING:
366 case STICK:
367 case FLOOR:
368 case PASSAGE:
369 case POOL:
370 case ARTIFACT:
371 if (item == NULL && (item = get_item("drop", 0)) == NULL)
372 return(FALSE);
373 break;
374
375 default:
376 msg("You can't drop something here.");
377 return(FALSE);
378 }
379
380 obj = OBJPTR(item);
381
382 if (!dropcheck(obj))
383 return(FALSE);
384
385 /* Curse a dropped scare monster scroll */
386
387 if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
388 {
389 if (obj->o_flags & ISBLESSED)
390 obj->o_flags &= ~ISBLESSED;
391 else
392 obj->o_flags |= ISCURSED;
393 }
394
395 /* Take it out of the pack */
396
397 if (obj->o_count >= 2 && obj->o_group == 0)
398 {
399 struct linked_list *nitem = new_item(sizeof *obj);
400
401 obj->o_count--;
402 obj = OBJPTR(nitem);
403 *obj = *(OBJPTR(item));
404 obj->o_count = 1;
405 item = nitem;
406 }
407 else
408 rem_pack(obj);
409
410 if (ch == POOL)
411 {
412 msg("The pool bubbles briefly as your %s sinks out of sight.",
413 inv_name(obj, TRUE));
414 discard(item);
415 item = NULL;
416 }
417 else /* Link it into the level object list */
418 {
419 add_obj(item, hero.y, hero.x);
420 mvaddch(hero.y, hero.x, obj->o_type);
421 }
422
423 if (obj->o_type == ARTIFACT)
424 has_artifact &= ~(1 << obj->o_which);
425
426 updpack();
427 return(TRUE);
428 }
429
430 /*
431 dropcheck()
432 do special checks for dropping or unweilding|unwearing|unringing
433 */
434
435 int
436 dropcheck(struct object *op)
437 {
438 if (op == NULL)
439 return(TRUE);
440
441 if (op != cur_armor && op != cur_weapon &&
442 op != cur_ring[LEFT_1] && op != cur_ring[LEFT_2] &&
443 op != cur_ring[LEFT_3] && op != cur_ring[LEFT_4] &&
444 op != cur_ring[LEFT_5] &&
445 op != cur_ring[RIGHT_1] && op != cur_ring[RIGHT_2] &&
446 op != cur_ring[RIGHT_3] && op != cur_ring[RIGHT_4] &&
447 op != cur_ring[RIGHT_5])
448 return(TRUE);
449
450 if (op->o_flags & ISCURSED)
451 {
452 msg("You can't. It appears to be cursed.");
453 return(FALSE);
454 }
455
456 if (op == cur_weapon)
457 cur_weapon = NULL;
458 else if (op == cur_armor)
459 {
460 waste_time();
461 cur_armor = NULL;
462 }
463 else if (op == cur_ring[LEFT_1] || op == cur_ring[LEFT_2] ||
464 op == cur_ring[LEFT_3] || op == cur_ring[LEFT_4] ||
465 op == cur_ring[LEFT_5] ||
466 op == cur_ring[RIGHT_1] || op == cur_ring[RIGHT_2] ||
467 op == cur_ring[RIGHT_3] || op == cur_ring[RIGHT_4] ||
468 op == cur_ring[RIGHT_5])
469 {
470 if (op == cur_ring[LEFT_1])
471 cur_ring[LEFT_1] = NULL;
472 else if (op == cur_ring[LEFT_2])
473 cur_ring[LEFT_2] = NULL;
474 else if (op == cur_ring[LEFT_3])
475 cur_ring[LEFT_3] = NULL;
476 else if (op == cur_ring[LEFT_4])
477 cur_ring[LEFT_4] = NULL;
478 else if (op == cur_ring[LEFT_5])
479 cur_ring[LEFT_5] = NULL;
480 else if (op == cur_ring[RIGHT_1])
481 cur_ring[RIGHT_1] = NULL;
482 else if (op == cur_ring[RIGHT_2])
483 cur_ring[RIGHT_2] = NULL;
484 else if (op == cur_ring[RIGHT_3])
485 cur_ring[RIGHT_3] = NULL;
486 else if (op == cur_ring[RIGHT_4])
487 cur_ring[RIGHT_4] = NULL;
488 else if (op == cur_ring[RIGHT_5])
489 cur_ring[RIGHT_5] = NULL;
490
491 switch (op->o_which)
492 {
493 case R_ADDSTR:
494 chg_str(-op->o_ac, FALSE, FALSE);
495 break;
496 case R_ADDHIT:
497 chg_dext(-op->o_ac, FALSE, FALSE);
498 break;
499 case R_ADDINTEL:
500 pstats.s_intel -= op->o_ac;
501 break;
502 case R_ADDWISDOM:
503 pstats.s_wisdom -= op->o_ac;
504 break;
505
506 case R_SEEINVIS:
507 if (find_slot(FUSE_UNSEE,FUSE) == NULL)
508 {
509 turn_off(player, CANSEE);
510 msg("The tingling feeling leaves your eyes.");
511 }
512
513 light(&hero);
514 mvwaddch(cw, hero.y, hero.x, PLAYER);
515 break;
516
517 case R_LIGHT:
518 if (roomin(hero) != NULL)
519 {
520 light(&hero);
521 mvwaddch(cw, hero.y, hero.x, PLAYER);
522 }
523 break;
524 }
525 }
526 return(TRUE);
527 }
528
529 /*
530 new_thing()
531 return a new thing
532 */
533
534 struct linked_list *
535 new_thing(void)
536 {
537 int j, k;
538 struct linked_list *item;
539 struct object *cur;
540 short blesschance = srnd(100);
541 short cursechance = srnd(100);
542
543 item = new_item(sizeof *cur);
544 cur = OBJPTR(item);
545 cur->o_hplus = cur->o_dplus = 0;
546 cur->o_damage = cur->o_hurldmg = "0d0";
547 cur->o_ac = 11;
548 cur->o_count = 1;
549 cur->o_group = 0;
550 cur->o_flags = 0;
551 cur->o_weight = 0;
552 cur->o_mark[0] = '\0';
553
554 /*
555 * Decide what kind of object it will be If we haven't had food for a
556 * while, let it be food.
557 */
558
559 switch (no_food > 3 ? TYP_FOOD : pick_one(things, numthings))
560 {
561 case TYP_POTION:
562 cur->o_type = POTION;
563 cur->o_which = pick_one(p_magic, maxpotions);
564 cur->o_weight = things[TYP_POTION].mi_wght;
565
566 if (cursechance < p_magic[cur->o_which].mi_curse)
567 cur->o_flags |= ISCURSED;
568 else if (blesschance < p_magic[cur->o_which].mi_bless)
569 cur->o_flags |= ISBLESSED;
570 break;
571
572 case TYP_SCROLL:
573 cur->o_type = SCROLL;
574 cur->o_which = pick_one(s_magic, maxscrolls);
575 cur->o_weight = things[TYP_SCROLL].mi_wght;
576
577 if (cursechance < s_magic[cur->o_which].mi_curse)
578 cur->o_flags |= ISCURSED;
579 else if (blesschance < s_magic[cur->o_which].mi_bless)
580 cur->o_flags |= ISBLESSED;
581 break;
582
583 case TYP_FOOD:
584 no_food = 0;
585 cur->o_type = FOOD;
586 cur->o_which = pick_one(fd_data, maxfoods);
587 cur->o_weight = 2;
588 cur->o_count += extras();
589 break;
590
591 case TYP_WEAPON:
592 cur->o_type = WEAPON;
593 cur->o_which = rnd(maxweapons);
594 init_weapon(cur, cur->o_which);
595
596 if (cursechance < 10)
597 {
598 short bad = (rnd(10) < 1) ? 2 : 1;
599
600 cur->o_flags |= ISCURSED;
601 cur->o_hplus -= bad;
602 cur->o_dplus -= bad;
603 }
604 else if (blesschance < 15)
605 {
606 short good = (rnd(10) < 1) ? 2 : 1;
607
608 cur->o_hplus += good;
609 cur->o_dplus += good;
610 }
611 break;
612
613 case TYP_ARMOR:
614 cur->o_type = ARMOR;
615
616 for (j = 0; j < maxarmors; j++)
617 if (blesschance < armors[j].a_prob)
618 break;
619
620 if (j == maxarmors)
621 {
622 debug("Picked a bad armor %d", blesschance);
623 j = 0;
624 }
625
626 cur->o_which = j;
627 cur->o_ac = armors[j].a_class;
628
629 if (((k = rnd(100)) < 20) && j != MITHRIL)
630 {
631 cur->o_flags |= ISCURSED;
632 cur->o_ac += rnd(3) + 1;
633 }
634 else if (k < 28 || j == MITHRIL)
635 cur->o_ac -= rnd(3) + 1;
636
637 if (j == MITHRIL)
638 cur->o_flags |= ISPROT;
639
640 cur->o_weight = armors[j].a_wght;
641
642 break;
643
644 case TYP_RING:
645 cur->o_type = RING;
646 cur->o_which = pick_one(r_magic, maxrings);
647 cur->o_weight = things[TYP_RING].mi_wght;
648
649 if (cursechance < r_magic[cur->o_which].mi_curse)
650 cur->o_flags |= ISCURSED;
651 else if (blesschance < r_magic[cur->o_which].mi_bless)
652 cur->o_flags |= ISBLESSED;
653
654 switch (cur->o_which)
655 {
656 case R_ADDSTR:
657 case R_ADDWISDOM:
658 case R_ADDINTEL:
659 case R_PROTECT:
660 case R_ADDHIT:
661 case R_ADDDAM:
662 case R_CARRYING:
663 cur->o_ac = rnd(2) + 1; /* From 1 to 3 */
664
665 if (cur->o_flags & ISCURSED)
666 cur->o_ac = -cur->o_ac;
667
668 if (cur->o_flags & ISBLESSED)
669 cur->o_ac++;
670
671 break;
672
673 case R_RESURRECT:
674 case R_TELCONTROL:
675 case R_VREGEN:
676 case R_REGEN:
677 case R_PIETY:
678 case R_WIZARD:
679 cur->o_ac = 0;
680
681 if (cur->o_flags & ISCURSED)
682 cur->o_ac = -1;
683
684 if (cur->o_flags & ISBLESSED)
685 cur->o_ac = 1;
686
687 break;
688
689 case R_DIGEST:
690
691 if (cur->o_flags & ISCURSED)
692 cur->o_ac = -1;
693 else if (cur->o_flags & ISBLESSED)
694 cur->o_ac = 2;
695 else
696 cur->o_ac = 1;
697 break;
698
699 default:
700 cur->o_ac = 0;
701 break;
702 }
703 break;
704
705 case TYP_STICK:
706 cur->o_type = STICK;
707 cur->o_which = pick_one(ws_magic, maxsticks);
708 fix_stick(cur);
709
710 if (cursechance < ws_magic[cur->o_which].mi_curse)
711 cur->o_flags |= ISCURSED;
712 else if (blesschance < ws_magic[cur->o_which].mi_bless)
713 cur->o_flags |= ISBLESSED;
714
715 break;
716
717 default:
718 debug("Picked a bad kind of object");
719 wait_for(' ');
720 }
721
722 return(item);
723 }
724
725 /*
726 spec_item()
727 provide a new item tailored to specification
728 */
729
730 struct linked_list *
731 spec_item(char type, int which, int hitp, int damage)
732 {
733 struct linked_list *item;
734 struct object *obj;
735
736 item = new_item(sizeof *obj);
737 obj = OBJPTR(item);
738
739 obj->o_count = 1;
740 obj->o_group = 0;
741 obj->o_type = type;
742 obj->o_which = which;
743 obj->o_damage = obj->o_hurldmg = "0d0";
744 obj->o_hplus = 0;
745 obj->o_dplus = 0;
746 obj->o_flags = 0;
747 obj->o_mark[0] = '\0';
748 obj->o_text = NULL;
749 obj->o_launch = 0;
750 obj->o_weight = 0;
751
752 switch(type) /* Handle special characteristics */
753 {
754 case WEAPON:
755 init_weapon(obj, which);
756 obj->o_hplus = hitp;
757 obj->o_dplus = damage;
758 obj->o_ac = 10;
759 break;
760
761 case ARMOR:
762 obj->o_ac = armors[which].a_class - hitp;
763 break;
764
765 case RING:
766 obj->o_ac = hitp;
767 break;
768
769 case STICK:
770 fix_stick(obj);
771 obj->o_charges = hitp;
772 break;
773
774 case GOLD:
775 obj->o_type = GOLD;
776 obj->o_count = GOLDCALC;
777 obj->o_ac = 11;
778 break;
779 }
780
781 if (hitp > 0 || damage > 0)
782 obj->o_flags |= ISBLESSED;
783 else if (hitp < 0 || damage < 0)
784 obj->o_flags |= ISCURSED;
785
786 return(item);
787 }
788
789 /*
790 pick_one()
791 pick an item out of a list of nitems possible magic items
792 */
793
794 int
795 pick_one(struct magic_item *magic, int nitems)
796 {
797 int i;
798 struct magic_item *end;
799 struct magic_item *start = magic;
800
801 for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
802 if (i <= magic->mi_prob)
803 break;
804
805 if (magic == end)
806 {
807 if (wizard)
808 {
809 add_line("Bad pick_one: %d from %d items", i, nitems);
810
811 for (magic = start; magic < end; magic++)
812 add_line("%s: %d%%", magic->mi_name, magic->mi_prob);
813
814 end_line();
815 }
816 magic = start;
817 }
818
819 return((int)(magic - start));
820 }
821
822
823 /*
824 blesscurse()
825 returns whether the object is blessed or cursed
826 */
827
828 char *
829 blesscurse(long flags)
830 {
831 if (flags & ISKNOW)
832 {
833 if (flags & ISCURSED)
834 return("cursed ");
835
836 if (flags & ISBLESSED)
837 return("blessed ");
838
839 return("normal ");
840 }
841
842 return("");
843 }
844
845 /*
846 extras()
847 Return the number of extra food items to be created
848 */
849
850 int
851 extras(void)
852 {
853 int i = rnd(100);
854
855 if (i < 10)
856 return(2);
857 else if (i < 20)
858 return(1);
859 else
860 return(0);
861 }
862
863 /*
864 name_type()
865 Returns a string identifying a pack item's type
866 */
867
868 char *
869 name_type(int type)
870 {
871 switch(type)
872 {
873 case ARMOR:
874 return ("armor");
875
876 case WEAPON:
877 return ("weapons");
878
879 case SCROLL:
880 return ("scrolls");
881
882 case RING:
883 return ("rings");
884
885 case STICK:
886 return ("staffs");
887
888 case POTION:
889 return ("potions");
890
891 case FOOD:
892 return ("food");
893
894 case GOLD:
895 return ("gold");
896
897 default:
898 return ("items");
899 }
900 }
901
902 /*
903 make_item()
904 adds a linked_list structure to the top of an object for interfacing
905 with other routines
906 */
907
908 linked_list *
909 make_item(object *obj_p)
910 {
911 linked_list *item_p = new_list();
912
913 item_p->l_next = item_p->l_prev = NULL;
914
915 item_p->data.obj = obj_p;
916
917 return(item_p);
918 }
919
920 /*
921 is_member()
922 Checks to see if a character is a member of an array
923 */
924
925 int
926 is_member(char *list_p, int member)
927 {
928 while (*list_p != 0)
929 {
930 if (*list_p++ == member)
931 return(TRUE);
932 }
933
934 return(FALSE);
935 }