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