Mercurial > hg > early-roguelike
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 |