Mercurial > hg > early-roguelike
comparison xrogue/pack.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 pack.c - Routines to deal with the pack. | |
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 * add_pack: | |
25 * Pick up an object and add it to the pack. If the argument is non-null | |
26 * use it as the linked_list pointer instead of gettting it off the ground. | |
27 */ | |
28 | |
29 bool | |
30 add_pack(item, silent) | |
31 register struct linked_list *item; | |
32 bool silent; | |
33 { | |
34 register struct linked_list *ip, *lp = NULL, *ap; | |
35 register struct object *obj, *op = NULL; | |
36 register bool exact, from_floor; | |
37 bool giveflag = 0; | |
38 static long cleric = C_CLERIC, | |
39 monk = C_MONK, | |
40 magician = C_MAGICIAN, | |
41 assassin = C_ASSASSIN, | |
42 druid = C_DRUID, | |
43 thief = C_THIEF, | |
44 fighter = C_FIGHTER, | |
45 ranger = C_RANGER, | |
46 paladin = C_PALADIN; | |
47 | |
48 if (item == NULL) | |
49 { | |
50 from_floor = TRUE; | |
51 if ((item = find_obj(hero.y, hero.x)) == NULL) | |
52 return(FALSE); | |
53 } | |
54 else | |
55 from_floor = FALSE; | |
56 obj = OBJPTR(item); | |
57 /* | |
58 * If it is gold, just add its value to rogue's purse and get rid | |
59 * of it. | |
60 */ | |
61 if (obj->o_type == GOLD) { | |
62 register struct linked_list *mitem; | |
63 register struct thing *tp; | |
64 | |
65 if (!silent) { | |
66 if (!terse) addmsg("You found "); | |
67 msg("%d gold pieces.", obj->o_count); | |
68 } | |
69 | |
70 /* First make sure no greedy monster is after this gold. | |
71 * If so, make the monster run after the rogue instead. | |
72 */ | |
73 for (mitem = mlist; mitem != NULL; mitem = next(mitem)) { | |
74 tp = THINGPTR(mitem); | |
75 if (tp->t_dest == &obj->o_pos) tp->t_dest = &hero; | |
76 } | |
77 | |
78 purse += obj->o_count; | |
79 if (from_floor) { | |
80 detach(lvl_obj, item); | |
81 if ((ap = find_obj(hero.y, hero.x)) == NULL) | |
82 mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR)); | |
83 else | |
84 mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type); | |
85 } | |
86 o_discard(item); | |
87 return(TRUE); | |
88 } | |
89 | |
90 /* | |
91 * see if he can carry any more weight | |
92 */ | |
93 if (itemweight(obj) + pstats.s_pack > pstats.s_carry) { | |
94 msg("Too much for you to carry."); | |
95 return FALSE; | |
96 } | |
97 /* | |
98 * Link it into the pack. Search the pack for a object of similar type | |
99 * if there isn't one, stuff it at the beginning, if there is, look for one | |
100 * that is exactly the same and just increment the count if there is. | |
101 * it that. Food is always put at the beginning for ease of access, but | |
102 * is not ordered so that you can't tell good food from bad. First check | |
103 * to see if there is something in thr same group and if there is then | |
104 * increment the count. | |
105 */ | |
106 if (obj->o_group) | |
107 { | |
108 for (ip = pack; ip != NULL; ip = next(ip)) | |
109 { | |
110 op = OBJPTR(ip); | |
111 if (op->o_group == obj->o_group) | |
112 { | |
113 /* | |
114 * Put it in the pack and notify the user | |
115 */ | |
116 op->o_count += obj->o_count; | |
117 if (from_floor) | |
118 { | |
119 detach(lvl_obj, item); | |
120 if ((ap = find_obj(hero.y, hero.x)) == NULL) | |
121 mvaddch(hero.y,hero.x, | |
122 (roomin(&hero)==NULL ? PASSAGE : FLOOR)); | |
123 else | |
124 mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type); | |
125 } | |
126 o_discard(item); | |
127 item = ip; | |
128 goto picked_up; | |
129 } | |
130 } | |
131 } | |
132 | |
133 /* | |
134 * Check for and deal with scare monster scrolls | |
135 */ | |
136 if (obj->o_type == SCROLL && obj->o_which == S_SCARE) | |
137 if (obj->o_flags & ISCURSED) | |
138 { | |
139 msg("The scroll turns to dust as you pick it up."); | |
140 detach(lvl_obj, item); | |
141 if ((ap = find_obj(hero.y, hero.x)) == NULL) | |
142 mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR)); | |
143 else | |
144 mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type); | |
145 return(TRUE); | |
146 } | |
147 | |
148 /* | |
149 * Search for an object of the same type | |
150 */ | |
151 exact = FALSE; | |
152 for (ip = pack; ip != NULL; ip = next(ip)) | |
153 { | |
154 op = OBJPTR(ip); | |
155 if (obj->o_type == op->o_type) | |
156 break; | |
157 } | |
158 if (ip == NULL) | |
159 { | |
160 /* | |
161 * Put it at the end of the pack since it is a new type | |
162 */ | |
163 for (ip = pack; ip != NULL; ip = next(ip)) | |
164 { | |
165 op = OBJPTR(ip); | |
166 if (op->o_type != FOOD) | |
167 break; | |
168 lp = ip; | |
169 } | |
170 } | |
171 else | |
172 { | |
173 /* | |
174 * Search for an object which is exactly the same | |
175 */ | |
176 while (ip != NULL && op->o_type == obj->o_type) | |
177 { | |
178 if (op->o_which == obj->o_which) | |
179 { | |
180 exact = TRUE; | |
181 break; | |
182 } | |
183 lp = ip; | |
184 if ((ip = next(ip)) == NULL) | |
185 break; | |
186 op = OBJPTR(ip); | |
187 } | |
188 } | |
189 /* | |
190 * Check if there is room | |
191 */ | |
192 if (ip == NULL || !exact || !ISMULT(obj->o_type)) { | |
193 if (inpack == MAXPACK-1) { | |
194 msg(terse ? "No room." : "You can't carry anything else."); | |
195 return(FALSE); | |
196 } | |
197 } | |
198 inpack++; | |
199 if (from_floor) | |
200 { | |
201 detach(lvl_obj, item); | |
202 if ((ap = find_obj(hero.y, hero.x)) == NULL) | |
203 mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR)); | |
204 else | |
205 mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type); | |
206 } | |
207 if (ip == NULL) | |
208 { | |
209 /* | |
210 * Didn't find an exact match, just stick it here | |
211 */ | |
212 if (pack == NULL) | |
213 pack = item; | |
214 else | |
215 { | |
216 lp->l_next = item; | |
217 item->l_prev = lp; | |
218 item->l_next = NULL; | |
219 } | |
220 } | |
221 else | |
222 { | |
223 /* | |
224 * If we found an exact match. If it is food, | |
225 * increase the count, otherwise put it with its clones. | |
226 */ | |
227 if (exact && ISMULT(obj->o_type)) | |
228 { | |
229 op->o_count += obj->o_count; | |
230 inpack--; /* adjust for previous addition */ | |
231 o_discard(item); | |
232 item = ip; | |
233 goto picked_up; | |
234 } | |
235 if ((item->l_prev = prev(ip)) != NULL) | |
236 item->l_prev->l_next = item; | |
237 else | |
238 pack = item; | |
239 item->l_next = ip; | |
240 ip->l_prev = item; | |
241 } | |
242 picked_up: | |
243 /* | |
244 * Notify the user | |
245 */ | |
246 obj = OBJPTR(item); | |
247 if (!silent) | |
248 { | |
249 if (!terse) | |
250 addmsg("You now have "); | |
251 msg("%s (%c)", inv_name(obj, !terse), pack_char(pack, obj)); | |
252 } | |
253 | |
254 /* Relics do strange things when you pick them up */ | |
255 if (obj->o_type == RELIC) { | |
256 switch (obj->o_which) { | |
257 /* the ankh of Heil gives you prayers */ | |
258 case HEIL_ANKH: | |
259 msg("The ankh welds itself into your hand. "); | |
260 if (player.t_ctype != C_CLERIC && player.t_ctype != C_PALADIN) | |
261 fuse(prayer_recovery, (VOID *)NULL, SPELLTIME, AFTER); | |
262 /* start a fuse to change player into a paladin */ | |
263 if (quest_item != HEIL_ANKH) { | |
264 msg("You hear a strange, distant hypnotic calling... "); | |
265 if (player.t_ctype != C_PALADIN && obj->o_which ==HEIL_ANKH) | |
266 fuse(changeclass, &paladin, roll(8, 8), AFTER); | |
267 } | |
268 | |
269 /* A cloak must be worn. */ | |
270 when EMORI_CLOAK: | |
271 if (cur_armor != NULL || cur_misc[WEAR_CLOAK]) { | |
272 msg("The cloak insists you remove your current garments."); | |
273 if (!dropcheck(cur_armor != NULL ? cur_armor | |
274 : cur_misc[WEAR_CLOAK])) { | |
275 pstats.s_hpt = -1; | |
276 msg("The cloak constricts around you..."); | |
277 msg("It draws your life force from you!!! --More--"); | |
278 wait_for(' '); | |
279 death(D_RELIC); | |
280 } | |
281 } | |
282 if (obj->o_charges < 0) /* should never happen, but.... */ | |
283 obj->o_charges = 0; | |
284 if (obj->o_charges == 0) | |
285 fuse(cloak_charge, obj, CLOAK_TIME, AFTER); | |
286 /* start a fuse to change player into a monk */ | |
287 if (quest_item != EMORI_CLOAK) { | |
288 msg("You suddenly become calm and quiet. "); | |
289 if (player.t_ctype != C_MONK && obj->o_which == EMORI_CLOAK) | |
290 fuse(changeclass, &monk, roll(8, 8), AFTER); | |
291 } | |
292 | |
293 /* The amulet must be worn. */ | |
294 when STONEBONES_AMULET: | |
295 case YENDOR_AMULET: | |
296 if (cur_misc[WEAR_JEWEL] || cur_relic[STONEBONES_AMULET] || | |
297 cur_relic[YENDOR_AMULET]) { | |
298 msg("You have an urge to remove your current amulet."); | |
299 } | |
300 if((cur_misc[WEAR_JEWEL] && !dropcheck(cur_misc[WEAR_JEWEL])) || | |
301 cur_relic[STONEBONES_AMULET] || cur_relic[YENDOR_AMULET]) { | |
302 pstats.s_hpt = -1; | |
303 msg("The %s begins pulsating... ",inv_name(obj, TRUE)); | |
304 msg("It fades completely away! --More--"); | |
305 wait_for(' '); | |
306 death(D_RELIC); | |
307 } | |
308 msg("The %s welds itself into your chest. ",inv_name(obj,TRUE)); | |
309 /* start a fuse to change into a magician */ | |
310 if (quest_item != STONEBONES_AMULET) { | |
311 if (player.t_ctype != C_MAGICIAN && | |
312 obj->o_which == STONEBONES_AMULET) { | |
313 msg("You sense approaching etheric forces... "); | |
314 fuse(changeclass, &magician, roll(8, 8), AFTER); | |
315 } | |
316 } | |
317 | |
318 /* The eye is now inserted in forehead */ | |
319 when EYE_VECNA: | |
320 msg("The eye forces itself into your forehead! "); | |
321 pstats.s_hpt -= (rnd(80)+21); | |
322 if (pstats.s_hpt <= 0) { | |
323 pstats.s_hpt = -1; | |
324 msg ("The pain is too much for you to bear! --More--"); | |
325 wait_for(' '); | |
326 death(D_RELIC); | |
327 } | |
328 waste_time(); | |
329 msg("The excruciating pain slowly turns into a dull throb."); | |
330 /* start a fuse to change player into an assassin */ | |
331 if (quest_item != EYE_VECNA) { | |
332 msg("Your blood rushes and you begin to sweat profusely... "); | |
333 if (player.t_ctype != C_ASSASSIN && obj->o_which == EYE_VECNA) | |
334 fuse(changeclass, &assassin, roll(8, 8), AFTER); | |
335 } | |
336 | |
337 when QUILL_NAGROM: | |
338 fuse(quill_charge,(VOID *)NULL, 8, AFTER); | |
339 /* start a fuse to change player into a druid */ | |
340 if (quest_item != QUILL_NAGROM) { | |
341 msg("You begin to see things differently... "); | |
342 if (player.t_ctype != C_DRUID && obj->o_which == QUILL_NAGROM) | |
343 fuse(changeclass, &druid, roll(8, 8), AFTER); | |
344 } | |
345 | |
346 /* Weapons will insist on being wielded. */ | |
347 when MUSTY_DAGGER: | |
348 case HRUGGEK_MSTAR: | |
349 case YEENOGHU_FLAIL: | |
350 case AXE_AKLAD: | |
351 /* set a daemon to eat gold for daggers and axe */ | |
352 if (obj->o_which == MUSTY_DAGGER || obj->o_which == AXE_AKLAD) { | |
353 if (purse > 0) msg("Your purse feels lighter! "); | |
354 else purse = 1; /* fudge to get right msg from eat_gold() */ | |
355 | |
356 eat_gold(obj); | |
357 daemon(eat_gold, obj, AFTER); | |
358 } | |
359 /* start a fuse to change player into a thief */ | |
360 if (quest_item != MUSTY_DAGGER) { | |
361 if (player.t_ctype != C_THIEF && | |
362 obj->o_which == MUSTY_DAGGER) { | |
363 msg("You look about furtively. "); | |
364 fuse(changeclass, &thief, roll(8, 8), AFTER); | |
365 } | |
366 } | |
367 /* start a fuse to change player into a fighter */ | |
368 if (quest_item != AXE_AKLAD) { | |
369 if (player.t_ctype != C_FIGHTER && | |
370 obj->o_which == AXE_AKLAD) { | |
371 msg("Your bones feel strengthened. "); | |
372 fuse(changeclass, &fighter, roll(8, 8), AFTER); | |
373 } | |
374 } | |
375 if (cur_weapon != NULL) { | |
376 msg("The artifact insists you release your current weapon!"); | |
377 if (!dropcheck(cur_weapon)) { | |
378 pstats.s_hpt = -1; | |
379 msg("The artifact forces your weapon into your heart! "); | |
380 msg("It hums with satisfaction! --More--"); | |
381 wait_for(' '); | |
382 death(D_RELIC); | |
383 } | |
384 } | |
385 cur_weapon = obj; | |
386 | |
387 /* acquire a sense of smell */ | |
388 when SURTUR_RING: | |
389 msg("The ring forces itself through your nose!"); | |
390 pstats.s_hpt -= rnd(40)+1; | |
391 if (pstats.s_hpt < 0) { | |
392 pstats.s_hpt = -1; | |
393 msg("The pain is too much for you to bear! --More--"); | |
394 wait_for(' '); | |
395 death(D_RELIC); | |
396 } | |
397 waste_time(); | |
398 turn_on(player, NOFIRE); | |
399 msg("The pain slowly subsides.. "); | |
400 | |
401 /* become a wandering musician */ | |
402 when BRIAN_MANDOLIN: | |
403 msg("You hear an ancient haunting sound... "); | |
404 /* start a fuse to change player into a ranger */ | |
405 if (quest_item != BRIAN_MANDOLIN) { | |
406 msg("You are transfixed with empathy. "); | |
407 if (player.t_ctype != C_RANGER && obj->o_which == BRIAN_MANDOLIN) | |
408 fuse(changeclass, &ranger, roll(8, 8), AFTER); | |
409 } | |
410 | |
411 /* add to the music */ | |
412 when GERYON_HORN: | |
413 msg("You begin to hear trumpets!"); | |
414 /* start a fuse to change player into a cleric */ | |
415 if (quest_item != GERYON_HORN) { | |
416 msg("You follow their calling. "); | |
417 if (player.t_ctype != C_CLERIC && obj->o_which == GERYON_HORN) | |
418 fuse(changeclass, &cleric, roll(8, 8), AFTER); | |
419 } | |
420 | |
421 /* the card can not be picked up, it must be traded for */ | |
422 when ALTERAN_CARD: | |
423 if (giveflag == FALSE) { | |
424 if (!wizard) { | |
425 msg("You look at the dark card and it chills you to the bone!! "); | |
426 msg("You stand for a moment, face to face with death... --More--"); | |
427 wait_for(' '); | |
428 pstats.s_hpt = -1; | |
429 death(D_CARD); | |
430 } | |
431 else { | |
432 msg("Got it! "); | |
433 if (purse > 0) msg("Your purse feels lighter! "); | |
434 else purse = 1; /* fudge to get right msg */ | |
435 | |
436 eat_gold(obj); | |
437 daemon(eat_gold, obj, AFTER); | |
438 } | |
439 } | |
440 else { | |
441 msg("You accept it hesitantly... "); | |
442 if (purse > 0) msg("Your purse feels lighter! "); | |
443 else purse = 1; /* fudge to get right msg */ | |
444 | |
445 eat_gold(obj); | |
446 daemon(eat_gold, obj, AFTER); | |
447 } | |
448 | |
449 otherwise: | |
450 break; | |
451 } | |
452 cur_relic[obj->o_which]++; /* Note that we have it */ | |
453 } | |
454 | |
455 updpack(FALSE, &player); | |
456 return(TRUE); | |
457 } | |
458 | |
459 /* | |
460 * inventory: | |
461 * list what is in the pack | |
462 */ | |
463 | |
464 inventory(list, type) | |
465 register struct linked_list *list; | |
466 register int type; | |
467 { | |
468 register struct object *obj; | |
469 register char ch; | |
470 register int n_objs, cnt, maxx = 0, curx; | |
471 char inv_temp[2*LINELEN+1]; | |
472 | |
473 cnt = 0; | |
474 n_objs = 0; | |
475 for (ch = 'a'; list != NULL; ch++, list = next(list)) { | |
476 obj = OBJPTR(list); | |
477 if (!is_type(obj, type)) | |
478 continue; | |
479 switch (n_objs++) { | |
480 /* | |
481 * For the first thing in the inventory, just save the string | |
482 * in case there is only one. | |
483 */ | |
484 case 0: | |
485 sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE)); | |
486 break; | |
487 /* | |
488 * If there is more than one, clear the screen, print the | |
489 * saved message and fall through to ... | |
490 */ | |
491 case 1: | |
492 if (slow_invent) | |
493 msg(inv_temp); | |
494 else | |
495 { | |
496 wclear(hw); | |
497 waddstr(hw, inv_temp); | |
498 waddch(hw, '\n'); | |
499 | |
500 maxx = strlen(inv_temp); /* Length of the listing */ | |
501 } | |
502 /* | |
503 * Print the line for this object | |
504 */ | |
505 default: | |
506 if (ch > 'z') | |
507 ch = 'A'; | |
508 if (slow_invent) | |
509 msg("%c) %s", ch, inv_name(obj, FALSE)); | |
510 else { | |
511 if (++cnt >= lines - 2) { /* if bottom of screen */ | |
512 dbotline(hw, morestr); | |
513 cnt = 0; | |
514 wclear(hw); | |
515 } | |
516 sprintf(inv_temp, "%c) %s\n", ch, inv_name(obj, FALSE)); | |
517 curx = strlen(inv_temp) - 1; /* Don't count new-line */ | |
518 if (curx > maxx) maxx = curx; | |
519 waddstr(hw, inv_temp); | |
520 } | |
521 } | |
522 } | |
523 if (n_objs == 0) { | |
524 if (terse) | |
525 msg(type == ALL ? "Empty-handed." : | |
526 "Nothing appropriate"); | |
527 else | |
528 msg(type == ALL ? "You are empty-handed." : | |
529 "You don't have anything appropriate"); | |
530 return FALSE; | |
531 } | |
532 if (n_objs == 1) { | |
533 msg(inv_temp); | |
534 return TRUE; | |
535 } | |
536 if (!slow_invent) | |
537 { | |
538 waddstr(hw, spacemsg); | |
539 curx = strlen(spacemsg); | |
540 if (curx > maxx) maxx = curx; | |
541 | |
542 /* | |
543 * If we have fewer than half a screenful, don't clear the screen. | |
544 * Leave an extra blank line at the bottom and 3 blank columns | |
545 * to he right. | |
546 */ | |
547 if (menu_overlay && n_objs < lines - 3) { | |
548 over_win(cw, hw, n_objs + 2, maxx + 3, n_objs, curx, ' '); | |
549 return TRUE; | |
550 } | |
551 | |
552 draw(hw); | |
553 wait_for(' '); | |
554 restscr(cw); | |
555 } | |
556 return TRUE; | |
557 } | |
558 | |
559 /* | |
560 * picky_inven: | |
561 * Allow player to inventory a single item | |
562 */ | |
563 | |
564 void | |
565 picky_inven() | |
566 { | |
567 register struct linked_list *item; | |
568 register char ch, mch; | |
569 | |
570 if (pack == NULL) | |
571 msg("You aren't carrying anything"); | |
572 else if (next(pack) == NULL) | |
573 msg("a) %s", inv_name(OBJPTR(pack), FALSE)); | |
574 else | |
575 { | |
576 msg(terse ? "Item: " : "Which item do you wish to inventory: "); | |
577 mpos = 0; | |
578 if ((mch = wgetch(cw)) == ESC) | |
579 { | |
580 msg(""); | |
581 return; | |
582 } | |
583 | |
584 /* Check for a special character */ | |
585 switch (mch) { | |
586 case FOOD: | |
587 case SCROLL: | |
588 case POTION: | |
589 case RING: | |
590 case STICK: | |
591 case RELIC: | |
592 case ARMOR: | |
593 case WEAPON: | |
594 case MM: | |
595 msg(""); | |
596 if (get_item(pack, (char *)NULL, mch, FALSE, FALSE) == NULL) { | |
597 if (terse) msg("No '%c' in your pack.", mch); | |
598 else msg("You have no '%c' in your pack.", mch); | |
599 } | |
600 return; | |
601 } | |
602 | |
603 for (ch = 'a', item = pack; item != NULL; item = next(item), ch++) | |
604 if (ch == mch) | |
605 { | |
606 msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE)); | |
607 return; | |
608 } | |
609 if (!terse) | |
610 msg("'%s' not in pack.", unctrl(mch)); | |
611 msg("Range is 'a' to '%c'", --ch); | |
612 } | |
613 } | |
614 | |
615 /* | |
616 * get_item: | |
617 * pick something out of a pack for a purpose | |
618 */ | |
619 | |
620 struct linked_list * | |
621 get_item(list, purpose, type, askfirst, showcost) | |
622 reg struct linked_list *list; | |
623 char *purpose; /* NULL if we should be silent (no prompts) */ | |
624 int type; | |
625 bool askfirst, showcost; | |
626 { | |
627 reg struct linked_list *item; | |
628 reg struct object *obj; | |
629 reg int cnt, pagecnt, ch, och, maxx, curx, confused; | |
630 struct linked_list *saveitem = NULL; | |
631 char description[2*LINELEN+1]; | |
632 char cost[LINELEN/2]; | |
633 char cap_purpose[LINELEN]; /* capitalize the "doings" */ | |
634 | |
635 cap_purpose[0] = '\0'; | |
636 | |
637 /* Get a capitalized purpose for starting sentences */ | |
638 if (purpose) { | |
639 strcpy(cap_purpose, purpose); | |
640 cap_purpose[0] = toupper(cap_purpose[0]); | |
641 } | |
642 | |
643 /* | |
644 * If this is the player's pack and the player is confused, we | |
645 * might just take anything. | |
646 */ | |
647 if (list == player.t_pack && on(player, ISHUH) && rnd(100) < 70) | |
648 confused = 1; | |
649 else confused = 0; | |
650 | |
651 cnt = 0; | |
652 if (list == NULL) { | |
653 msg("You aren't carrying anything."); | |
654 return NULL; | |
655 } | |
656 /* see if we have any of the type requested */ | |
657 for(ch = 'a',item = list ; item != NULL ; item = next(item), ch++) { | |
658 obj = OBJPTR(item); | |
659 if (is_type(obj, type)) { | |
660 cnt++; | |
661 saveitem = item; | |
662 } | |
663 } | |
664 if (cnt == 0) { | |
665 if (purpose) msg("Nothing to %s", purpose); | |
666 after = FALSE; | |
667 return NULL; | |
668 } | |
669 else if (cnt == 1) { /* only found one of 'em */ | |
670 obj = OBJPTR(saveitem); | |
671 for(;;) { | |
672 if (purpose) { /* Should we prompt the player? */ | |
673 msg("%s what (* for the item)?", cap_purpose); | |
674 ch = wgetch(cw); | |
675 } | |
676 else { | |
677 ch = pack_char(list, obj); | |
678 msg("%c) %s", ch, inv_name(obj,FALSE)); | |
679 } | |
680 | |
681 if (ch == '*') { | |
682 mpos = 0; | |
683 msg("%c) %s",pack_char(list, obj),inv_name(obj,FALSE)); | |
684 continue; | |
685 } | |
686 if (ch == ESC) { | |
687 msg(""); | |
688 after = FALSE; | |
689 return NULL; | |
690 } | |
691 for(item = list,och = 'a'; item != NULL; item = next(item),och++) { | |
692 if (ch == och) break; | |
693 if (och == 'z') och = 'A' - 1; | |
694 } | |
695 if (item == NULL) { | |
696 msg("Please specify a letter between 'a' and '%c'", | |
697 och == 'A' ? 'z' : och-1); | |
698 continue; | |
699 } | |
700 if (is_type (OBJPTR(item), type)) { | |
701 if (purpose) mpos = 0; | |
702 return item; | |
703 } | |
704 else | |
705 msg ("You can't %s that!", purpose); | |
706 | |
707 } | |
708 } | |
709 for(;;) { | |
710 if (!askfirst && purpose) { | |
711 msg("%s what? (* for list): ", cap_purpose); | |
712 ch = wgetch(cw); | |
713 } | |
714 else ch = '*'; | |
715 | |
716 mpos = 0; | |
717 if (ch == ESC) { /* abort if escape hit */ | |
718 after = FALSE; | |
719 msg(""); /* clear display */ | |
720 return NULL; | |
721 } | |
722 | |
723 if (ch == '*') { | |
724 wclear(hw); | |
725 pagecnt = 0; | |
726 maxx = 0; | |
727 for(item = list,ch = 'a'; item != NULL ; item = next(item), ch++) { | |
728 obj = OBJPTR(item); | |
729 if (!is_type(OBJPTR(item), type)) | |
730 continue; | |
731 cost[0] = '\0'; | |
732 if (showcost) { | |
733 sprintf(description, "[%ld] ", get_worth(obj)); | |
734 sprintf(cost, "%8.8s", description); | |
735 } | |
736 sprintf(description,"%c) %s%s\n\r",ch,cost,inv_name(obj,FALSE)); | |
737 waddstr(hw, description); | |
738 curx = strlen(description) - 2; /* Don't count \n or \r */ | |
739 if (maxx < curx) maxx = curx; | |
740 if (++pagecnt >= lines - 2 && next(item) != NULL) { | |
741 pagecnt = 0; | |
742 dbotline(hw, spacemsg); | |
743 wclear(hw); | |
744 } | |
745 if (ch == 'z') ch = 'A' - 1; | |
746 } | |
747 | |
748 /* Put in the prompt */ | |
749 if (purpose) sprintf(description, "%s what? ", cap_purpose); | |
750 else strcpy(description, spacemsg); | |
751 waddstr(hw, description); | |
752 curx = strlen(description); | |
753 if (maxx < curx) maxx = curx; | |
754 | |
755 /* Write the screen */ | |
756 if ((menu_overlay && cnt < lines - 3) || cnt == 1) { | |
757 over_win(cw, hw, cnt + 2, maxx + 3, cnt, curx, NULL); | |
758 cnt = -1; /* Indicate we used over_win */ | |
759 } | |
760 else draw(hw); | |
761 | |
762 if (purpose) { | |
763 do { | |
764 ch = wgetch(cw); | |
765 } until (isalpha(ch) || ch == ESC); | |
766 } | |
767 else { | |
768 ch = pack_char(list, OBJPTR(saveitem)); /* Pick a valid item */ | |
769 wait_for(' '); | |
770 } | |
771 | |
772 /* Redraw original screen */ | |
773 if (cnt < 0) { | |
774 clearok(cw, FALSE); /* Setup to redraw current screen */ | |
775 touchwin(cw); /* clearing first */ | |
776 draw(cw); | |
777 } | |
778 else restscr(cw); | |
779 | |
780 if(ch == ESC) { | |
781 after = FALSE; | |
782 msg(""); /* clear top line */ | |
783 return NULL; /* all done if abort */ | |
784 } | |
785 /* ch has item to get from list */ | |
786 } | |
787 | |
788 for (item = list,och = 'a'; item != NULL; item = next(item),och++) { | |
789 if (confused) { | |
790 /* | |
791 * Confused is incremented each time so that if the rnd(cnt) | |
792 * clause keeps failing, confused will equal cnt for the | |
793 * last item of the correct type and rnd(cnt) < cnt will | |
794 * have to be true. | |
795 */ | |
796 if (is_type(OBJPTR(item), type) && rnd(cnt) < confused++) | |
797 break; | |
798 } | |
799 else if (ch == och) break; | |
800 if (och == 'z') och = 'A' - 1; | |
801 } | |
802 | |
803 if (item == NULL) { | |
804 msg("Please specify a letter between 'a' and '%c' ", | |
805 och == 'A' ? 'z' : och-1); | |
806 continue; | |
807 } | |
808 | |
809 if (is_type(OBJPTR(item), type)) | |
810 return (item); | |
811 else | |
812 msg ("You can't %s that!", purpose); | |
813 } | |
814 } | |
815 | |
816 pack_char(list, obj) | |
817 register struct object *obj; | |
818 struct linked_list *list; | |
819 { | |
820 register struct linked_list *item; | |
821 register char c; | |
822 | |
823 c = 'a'; | |
824 for (item = list; item != NULL; item = next(item)) { | |
825 if (OBJPTR(item) == obj) | |
826 return c; | |
827 else { | |
828 if (c == 'z') c = 'A'; | |
829 else c++; | |
830 } | |
831 } | |
832 return 'z'; | |
833 } | |
834 | |
835 /* | |
836 * cur_null: | |
837 * This updates cur_weapon etc for dropping things | |
838 */ | |
839 | |
840 cur_null(op) | |
841 reg struct object *op; | |
842 { | |
843 if (op == cur_weapon) cur_weapon = NULL; | |
844 else if (op == cur_armor) cur_armor = NULL; | |
845 else if (op == cur_ring[LEFT_1]) cur_ring[LEFT_1] = NULL; | |
846 else if (op == cur_ring[LEFT_2]) cur_ring[LEFT_2] = NULL; | |
847 else if (op == cur_ring[LEFT_3]) cur_ring[LEFT_3] = NULL; | |
848 else if (op == cur_ring[LEFT_4]) cur_ring[LEFT_4] = NULL; | |
849 else if (op == cur_ring[RIGHT_1]) cur_ring[RIGHT_1] = NULL; | |
850 else if (op == cur_ring[RIGHT_2]) cur_ring[RIGHT_2] = NULL; | |
851 else if (op == cur_ring[RIGHT_3]) cur_ring[RIGHT_3] = NULL; | |
852 else if (op == cur_ring[RIGHT_4]) cur_ring[RIGHT_4] = NULL; | |
853 else if (op == cur_misc[WEAR_BOOTS]) cur_misc[WEAR_BOOTS] = NULL; | |
854 else if (op == cur_misc[WEAR_JEWEL]) cur_misc[WEAR_JEWEL] = NULL; | |
855 else if (op == cur_misc[WEAR_GAUNTLET]) cur_misc[WEAR_GAUNTLET] = NULL; | |
856 else if (op == cur_misc[WEAR_CLOAK]) cur_misc[WEAR_CLOAK] = NULL; | |
857 else if (op == cur_misc[WEAR_BRACERS]) cur_misc[WEAR_BRACERS] = NULL; | |
858 else if (op == cur_misc[WEAR_NECKLACE]) cur_misc[WEAR_NECKLACE] = NULL; | |
859 } | |
860 | |
861 /* | |
862 * idenpack: | |
863 * Identify all the items in the pack | |
864 */ | |
865 | |
866 idenpack() | |
867 { | |
868 reg struct linked_list *pc; | |
869 | |
870 for (pc = pack ; pc != NULL ; pc = next(pc)) | |
871 whatis(pc); | |
872 } | |
873 | |
874 is_type (obj, type) | |
875 register struct object *obj; | |
876 register int type; | |
877 { | |
878 register bool current; | |
879 | |
880 if (type == obj->o_type) | |
881 return (TRUE); | |
882 | |
883 switch (type) { | |
884 case ALL: | |
885 return (TRUE); | |
886 when READABLE: | |
887 if (obj->o_type == SCROLL || | |
888 (obj->o_type == MM && obj->o_which == MM_SKILLS)) | |
889 return (TRUE); | |
890 when QUAFFABLE: | |
891 if (obj->o_type == POTION || | |
892 (obj->o_type == MM && obj->o_which == MM_JUG)) | |
893 return (TRUE); | |
894 when ZAPPABLE: | |
895 if (obj->o_type == STICK) return (TRUE); | |
896 if (obj->o_type == RELIC) | |
897 switch (obj->o_which) { | |
898 case MING_STAFF: | |
899 case ASMO_ROD: | |
900 case ORCUS_WAND: | |
901 case EMORI_CLOAK: | |
902 return (TRUE); | |
903 } | |
904 when WEARABLE: | |
905 case REMOVABLE: | |
906 current = is_current(obj); | |
907 | |
908 /* | |
909 * Don't wear thing we are already wearing or remove things | |
910 * we aren't wearing. | |
911 */ | |
912 if (type == WEARABLE && current) return (FALSE); | |
913 else if (type == REMOVABLE && !current) return (FALSE); | |
914 | |
915 switch (obj->o_type) { | |
916 case RELIC: | |
917 switch (obj->o_which) { | |
918 case HEIL_ANKH: | |
919 case EMORI_CLOAK: | |
920 return (TRUE); | |
921 } | |
922 when MM: | |
923 switch (obj->o_which) { | |
924 case MM_ELF_BOOTS: | |
925 case MM_DANCE: | |
926 case MM_BRACERS: | |
927 case MM_DISP: | |
928 case MM_PROTECT: | |
929 case MM_G_DEXTERITY: | |
930 case MM_G_OGRE: | |
931 case MM_JEWEL: | |
932 case MM_R_POWERLESS: | |
933 case MM_FUMBLE: | |
934 case MM_STRANGLE: | |
935 case MM_ADAPTION: | |
936 return (TRUE); | |
937 } | |
938 when ARMOR: | |
939 case RING: | |
940 return (TRUE); | |
941 } | |
942 when CALLABLE: | |
943 switch (obj->o_type) { | |
944 case RING: if (!r_know[obj->o_which]) return(TRUE); | |
945 when POTION: if (!p_know[obj->o_which]) return(TRUE); | |
946 when STICK: if (!ws_know[obj->o_which]) return(TRUE); | |
947 when SCROLL: if (!s_know[obj->o_which]) return(TRUE); | |
948 when MM: if (!m_know[obj->o_which]) return(TRUE); | |
949 } | |
950 when WIELDABLE: | |
951 switch (obj->o_type) { | |
952 case STICK: | |
953 case WEAPON: | |
954 return(TRUE); | |
955 when RELIC: | |
956 switch (obj->o_which) { | |
957 case MUSTY_DAGGER: | |
958 case HRUGGEK_MSTAR: | |
959 case YEENOGHU_FLAIL: | |
960 case AXE_AKLAD: | |
961 case MING_STAFF: | |
962 case ORCUS_WAND: | |
963 case ASMO_ROD: | |
964 return(TRUE); | |
965 } | |
966 } | |
967 when IDENTABLE: | |
968 if (!(obj->o_flags & ISKNOW) && obj->o_type != FOOD) | |
969 return (TRUE); | |
970 if (obj->o_type == MM) { | |
971 switch (obj->o_which) { | |
972 case MM_JUG: | |
973 /* Can still identify a jug if we don't know the potion */ | |
974 if (obj->o_ac != JUG_EMPTY && !p_know[obj->o_ac]) | |
975 return (TRUE); | |
976 } | |
977 } | |
978 when USEABLE: | |
979 if (obj->o_type == MM) { | |
980 switch(obj->o_which) { | |
981 case MM_BEAKER: | |
982 case MM_BOOK: | |
983 case MM_OPEN: | |
984 case MM_HUNGER: | |
985 case MM_DRUMS: | |
986 case MM_DISAPPEAR: | |
987 case MM_CHOKE: | |
988 case MM_KEOGHTOM: | |
989 case MM_CRYSTAL: | |
990 return (TRUE); | |
991 } | |
992 } | |
993 else if (obj->o_type == RELIC) { | |
994 switch (obj->o_which) { | |
995 case EMORI_CLOAK: | |
996 case BRIAN_MANDOLIN: | |
997 case HEIL_ANKH: | |
998 case YENDOR_AMULET: | |
999 case STONEBONES_AMULET: | |
1000 case GERYON_HORN: | |
1001 case EYE_VECNA: | |
1002 case QUILL_NAGROM: | |
1003 case SURTUR_RING: | |
1004 case ALTERAN_CARD: | |
1005 return (TRUE); | |
1006 } | |
1007 } | |
1008 else if (obj->o_type == POTION) { | |
1009 /* | |
1010 * only assassins can use poison | |
1011 */ | |
1012 if (player.t_ctype == C_ASSASSIN && obj->o_which == P_POISON) | |
1013 return(TRUE); | |
1014 } | |
1015 when PROTECTABLE: | |
1016 switch (obj->o_type) { | |
1017 case WEAPON: | |
1018 if ((obj->o_flags & ISMETAL) == 0) return (FALSE); | |
1019 | |
1020 /* Fall through */ | |
1021 case ARMOR: | |
1022 return (TRUE); | |
1023 | |
1024 when MM: | |
1025 if (obj->o_which == MM_BRACERS) return (TRUE); | |
1026 } | |
1027 } | |
1028 return(FALSE); | |
1029 } | |
1030 | |
1031 del_pack(item) | |
1032 register struct linked_list *item; | |
1033 { | |
1034 register struct object *obj; | |
1035 | |
1036 obj = OBJPTR(item); | |
1037 if (obj->o_count > 1) { | |
1038 obj->o_count--; | |
1039 } | |
1040 else { | |
1041 cur_null(obj); | |
1042 detach(pack, item); | |
1043 o_discard(item); | |
1044 inpack--; | |
1045 } | |
1046 } | |
1047 | |
1048 /* | |
1049 * carry_obj: | |
1050 * Check to see if a monster is carrying something and, if so, give | |
1051 * it to him. | |
1052 */ | |
1053 | |
1054 carry_obj(mp, chance) | |
1055 register struct thing *mp; | |
1056 int chance; | |
1057 { | |
1058 reg struct linked_list *item; | |
1059 reg struct object *obj; | |
1060 | |
1061 /* | |
1062 * If there is no chance, just return. | |
1063 * Note that this means there must be a "chance" in order for | |
1064 * the creature to carry a relic. | |
1065 */ | |
1066 if (chance <= 0) return; | |
1067 | |
1068 /* | |
1069 * check for the relic/artifacts | |
1070 * Do the relics first so they end up last in the pack. Attach() | |
1071 * always adds things to the beginning. This way they will be the | |
1072 * last things dropped when the creature is killed. This will ensure | |
1073 * the relic will be on top if there is a stack of item lying on the | |
1074 * floor and so the hero will know where it is if he's trying to | |
1075 * avoid it. Note that only UNIQUEs carry relics. | |
1076 */ | |
1077 if (on(*mp, ISUNIQUE)) { | |
1078 if (on(*mp, CARRYMDAGGER)) { | |
1079 item = spec_item(RELIC, MUSTY_DAGGER, NULL, NULL); | |
1080 obj = OBJPTR(item); | |
1081 obj->o_pos = mp->t_pos; | |
1082 attach(mp->t_pack, item); | |
1083 } | |
1084 | |
1085 if (on(*mp, CARRYCLOAK)) { | |
1086 item = spec_item(RELIC, EMORI_CLOAK, NULL, NULL); | |
1087 obj = OBJPTR(item); | |
1088 obj->o_pos = mp->t_pos; | |
1089 attach(mp->t_pack, item); | |
1090 } | |
1091 | |
1092 if (on(*mp, CARRYANKH)) { | |
1093 item = spec_item(RELIC, HEIL_ANKH, NULL, NULL); | |
1094 obj = OBJPTR(item); | |
1095 obj->o_pos = mp->t_pos; | |
1096 attach(mp->t_pack, item); | |
1097 } | |
1098 | |
1099 if (on(*mp, CARRYSTAFF)) { | |
1100 item = spec_item(RELIC, MING_STAFF, NULL, NULL); | |
1101 obj = OBJPTR(item); | |
1102 obj->o_pos = mp->t_pos; | |
1103 attach(mp->t_pack, item); | |
1104 } | |
1105 | |
1106 if (on(*mp, CARRYWAND)) { | |
1107 item = spec_item(RELIC, ORCUS_WAND, NULL, NULL); | |
1108 obj = OBJPTR(item); | |
1109 obj->o_pos = mp->t_pos; | |
1110 attach(mp->t_pack, item); | |
1111 } | |
1112 | |
1113 if (on(*mp, CARRYROD)) { | |
1114 item = spec_item(RELIC, ASMO_ROD, NULL, NULL); | |
1115 obj = OBJPTR(item); | |
1116 obj->o_pos = mp->t_pos; | |
1117 attach(mp->t_pack, item); | |
1118 } | |
1119 | |
1120 if (on(*mp, CARRYYAMULET)) { | |
1121 item = spec_item(RELIC, YENDOR_AMULET, NULL, NULL); | |
1122 obj = OBJPTR(item); | |
1123 obj->o_pos = mp->t_pos; | |
1124 attach(mp->t_pack, item); | |
1125 } | |
1126 | |
1127 if (on(*mp, CARRYBAMULET)) { | |
1128 item = spec_item(RELIC, STONEBONES_AMULET, NULL, NULL); | |
1129 obj = OBJPTR(item); | |
1130 obj->o_pos = mp->t_pos; | |
1131 attach(mp->t_pack, item); | |
1132 } | |
1133 | |
1134 if (on(*mp, CARRYMANDOLIN)) { | |
1135 item = spec_item(RELIC, BRIAN_MANDOLIN, NULL, NULL); | |
1136 obj = OBJPTR(item); | |
1137 obj->o_pos = mp->t_pos; | |
1138 attach(mp->t_pack, item); | |
1139 } | |
1140 if (on(*mp, CARRYEYE)) { | |
1141 item = spec_item(RELIC, EYE_VECNA, NULL, NULL); | |
1142 obj = OBJPTR(item); | |
1143 obj->o_pos = mp->t_pos; | |
1144 attach(mp->t_pack, item); | |
1145 } | |
1146 if (on(*mp, CARRYAXE)) { | |
1147 item = spec_item(RELIC, AXE_AKLAD, NULL, NULL); | |
1148 obj = OBJPTR(item); | |
1149 obj->o_pos = mp->t_pos; | |
1150 attach(mp->t_pack, item); | |
1151 } | |
1152 if (on(*mp, CARRYQUILL)) { | |
1153 register int i, howmany; | |
1154 | |
1155 item = spec_item(RELIC, QUILL_NAGROM, NULL, NULL); | |
1156 obj = OBJPTR(item); | |
1157 obj->o_pos = mp->t_pos; | |
1158 obj->o_charges = rnd(QUILLCHARGES); | |
1159 attach(mp->t_pack, item); | |
1160 howmany = roll(4,3); | |
1161 for (i=0; i<howmany; i++) { | |
1162 /* | |
1163 * the quill writes scrolls so give him a bunch | |
1164 */ | |
1165 item = new_thing(TYP_SCROLL, FALSE); | |
1166 obj = OBJPTR(item); | |
1167 obj->o_pos = mp->t_pos; | |
1168 attach(mp->t_pack, item); | |
1169 } | |
1170 } | |
1171 if (on(*mp, CARRYMSTAR)) { | |
1172 item = spec_item(RELIC, HRUGGEK_MSTAR, NULL, NULL); | |
1173 obj = OBJPTR(item); | |
1174 obj->o_pos = mp->t_pos; | |
1175 attach(mp->t_pack, item); | |
1176 } | |
1177 if (on(*mp, CARRYFLAIL)) { | |
1178 item = spec_item(RELIC, YEENOGHU_FLAIL, NULL, NULL); | |
1179 obj = OBJPTR(item); | |
1180 obj->o_pos = mp->t_pos; | |
1181 attach(mp->t_pack, item); | |
1182 } | |
1183 if (on(*mp, CARRYHORN)) { | |
1184 item = spec_item(RELIC, GERYON_HORN, NULL, NULL); | |
1185 obj = OBJPTR(item); | |
1186 obj->o_pos = mp->t_pos; | |
1187 attach(mp->t_pack, item); | |
1188 } | |
1189 if (on(*mp, CARRYSURTURRING)) { | |
1190 item = spec_item(RELIC, SURTUR_RING, NULL, NULL); | |
1191 obj = OBJPTR(item); | |
1192 obj->o_pos = mp->t_pos; | |
1193 attach(mp->t_pack, item); | |
1194 } | |
1195 if (on(*mp, CARRYCARD)) { | |
1196 item = spec_item(RELIC, ALTERAN_CARD, NULL, NULL); | |
1197 obj = OBJPTR(item); | |
1198 obj->o_pos = mp->t_pos; | |
1199 attach(mp->t_pack, item); | |
1200 } | |
1201 } | |
1202 /* | |
1203 * If it carries gold, give it some | |
1204 */ | |
1205 if (on(*mp, CARRYGOLD) && rnd(100) < chance) { | |
1206 item = spec_item(GOLD, NULL, NULL, NULL); | |
1207 obj = OBJPTR(item); | |
1208 obj->o_count = GOLDCALC + GOLDCALC; | |
1209 obj->o_pos = mp->t_pos; | |
1210 attach(mp->t_pack, item); | |
1211 } | |
1212 | |
1213 /* | |
1214 * If it carries food, give it some | |
1215 */ | |
1216 if (on(*mp, CARRYFOOD) && rnd(100) < chance) { | |
1217 int type; | |
1218 switch (rnd(41)) { | |
1219 case 3: type = E_APPLE; | |
1220 when 6: type = E_HAGBERRY; | |
1221 when 9: type = E_SOURSOP; | |
1222 when 12: type = E_RAMBUTAN; | |
1223 when 15: type = E_DEWBERRY; | |
1224 when 18: type = E_CANDLEBERRY; | |
1225 when 21: type = E_BANANA; | |
1226 when 24: type = E_CAPRIFIG; | |
1227 when 27: type = E_STRAWBERRY; | |
1228 when 30: type = E_GOOSEBERRY; | |
1229 when 33: type = E_ELDERBERRY; | |
1230 when 36: type = E_BLUEBERRY; | |
1231 when 40: type = E_SLIMEMOLD; /* monster food */ | |
1232 otherwise: type = E_RATION; | |
1233 } | |
1234 item = spec_item(FOOD, type, NULL, NULL); | |
1235 obj = OBJPTR(item); | |
1236 obj->o_weight = things[TYP_FOOD].mi_wght; | |
1237 obj->o_pos = mp->t_pos; | |
1238 attach(mp->t_pack, item); | |
1239 } | |
1240 | |
1241 /* | |
1242 * If it carries a weapon, give it one | |
1243 */ | |
1244 if (on(*mp, CARRYWEAPON) && rnd(100) < chance) { | |
1245 int type, hit, dam; | |
1246 | |
1247 /* Get the "bonuses" */ | |
1248 hit = rnd(5 + (vlevel / 5)) - 2; | |
1249 dam = rnd(5 + (vlevel / 5)) - 2; | |
1250 | |
1251 /* Only choose an appropriate type of weapon */ | |
1252 switch (rnd(12)) { | |
1253 case 0: type = DAGGER; | |
1254 when 1: type = BATTLEAXE; | |
1255 when 2: type = MACE; | |
1256 when 3: type = SWORD; | |
1257 when 4: type = PIKE; | |
1258 when 5: type = HALBERD; | |
1259 when 6: type = SPETUM; | |
1260 when 7: type = BARDICHE; | |
1261 when 8: type = TRIDENT; | |
1262 when 9: type = BASWORD; | |
1263 when 10:type = DART; | |
1264 otherwise: type = TWOSWORD; | |
1265 } | |
1266 | |
1267 /* Create the item */ | |
1268 item = spec_item(WEAPON, type, hit, dam); | |
1269 obj = OBJPTR(item); | |
1270 obj->o_pos = mp->t_pos; | |
1271 attach(mp->t_pack, item); | |
1272 } | |
1273 | |
1274 /* | |
1275 * If it carries a dagger, give it one | |
1276 */ | |
1277 if (on(*mp, CARRYDAGGER) && rnd(100) < chance) { | |
1278 int hit, dam; | |
1279 | |
1280 /* Get the "bonuses" */ | |
1281 hit = rnd(3 + (vlevel / 5)) - 1; | |
1282 dam = rnd(3 + (vlevel / 5)) - 1; | |
1283 | |
1284 /* Create the item */ | |
1285 item = spec_item(WEAPON, DAGGER, hit, dam); | |
1286 obj = OBJPTR(item); | |
1287 obj->o_pos = mp->t_pos; | |
1288 attach(mp->t_pack, item); | |
1289 } | |
1290 | |
1291 /* | |
1292 * If it carries a scroll, give it one | |
1293 */ | |
1294 if (on(*mp, CARRYSCROLL) && rnd(100) < chance) { | |
1295 item = new_thing(TYP_SCROLL, TRUE); | |
1296 obj = OBJPTR(item); | |
1297 obj->o_pos = mp->t_pos; | |
1298 | |
1299 /* Can the monster carry this scroll? */ | |
1300 if (obj->o_which == S_SCARE && mp->t_stats.s_intel < 16) | |
1301 fall(item, FALSE); /* This would scare us! */ | |
1302 else attach(mp->t_pack, item); | |
1303 } | |
1304 | |
1305 /* | |
1306 * If it carries a potion, give it one | |
1307 */ | |
1308 if (on(*mp, CARRYPOTION) && rnd(100) < chance) { | |
1309 item = new_thing(TYP_POTION, TRUE); | |
1310 obj = OBJPTR(item); | |
1311 obj->o_pos = mp->t_pos; | |
1312 attach(mp->t_pack, item); | |
1313 } | |
1314 | |
1315 /* | |
1316 * If it carries a ring, give it one | |
1317 */ | |
1318 if (on(*mp, CARRYRING) && rnd(100) < chance) { | |
1319 item = new_thing(TYP_RING, TRUE); | |
1320 obj = OBJPTR(item); | |
1321 obj->o_pos = mp->t_pos; | |
1322 attach(mp->t_pack, item); | |
1323 } | |
1324 | |
1325 /* | |
1326 * If it carries a wand or staff, give it one | |
1327 */ | |
1328 if (on(*mp, CARRYSTICK) && rnd(100) < chance) { | |
1329 item = new_thing(TYP_STICK, TRUE); | |
1330 obj = OBJPTR(item); | |
1331 obj->o_pos = mp->t_pos; | |
1332 attach(mp->t_pack, item); | |
1333 } | |
1334 | |
1335 /* | |
1336 * If it carries any miscellaneous magic, give it one | |
1337 */ | |
1338 if (on(*mp, CARRYMISC) && rnd(100) < chance) { | |
1339 item = new_thing(TYP_MM, TRUE); | |
1340 obj = OBJPTR(item); | |
1341 obj->o_pos = mp->t_pos; | |
1342 attach(mp->t_pack, item); | |
1343 } | |
1344 | |
1345 /* Update the monster's encumberance */ | |
1346 updpack(TRUE, mp); | |
1347 } | |
1348 | |
1349 | |
1350 /* | |
1351 * grab(): | |
1352 * See what is on the spot where the player is standing. If | |
1353 * nothing is there, do nothing. If there is one thing, pick it | |
1354 * up. If there are multiple things, prompt the player for what | |
1355 * he wants (* means everything). | |
1356 */ | |
1357 | |
1358 grab(y, x) | |
1359 register int y, x; | |
1360 { | |
1361 register struct linked_list *next_item, *item; | |
1362 register struct object *obj; | |
1363 register int cnt, pagecnt; | |
1364 int num_there = 0, ch, och; | |
1365 | |
1366 /* | |
1367 * Count how many objects there are and move them to the front | |
1368 * of the level list. | |
1369 */ | |
1370 for (item = lvl_obj; item != NULL; item = next_item) { | |
1371 obj = OBJPTR(item); | |
1372 next_item = next(item); | |
1373 if (obj->o_pos.y == y && obj->o_pos.x == x) { | |
1374 num_there++; | |
1375 detach(lvl_obj, item); /* Remove it from the list */ | |
1376 attach(lvl_obj, item); /* Place it at the front of the list */ | |
1377 } | |
1378 } | |
1379 | |
1380 /* Nothing there. */ | |
1381 if (num_there < 1) msg("Nothing %s", terse ? "there." : "to pick up."); | |
1382 | |
1383 /* Something or things there */ | |
1384 else { | |
1385 char linebuf[2*LINELEN+1]; | |
1386 int curlen, maxlen = 0; | |
1387 | |
1388 wclear(hw); | |
1389 cnt = 0; | |
1390 pagecnt = 0; | |
1391 for (item = lvl_obj, ch = 'a'; item != NULL && cnt < num_there; | |
1392 item = next(item), ch++, cnt++) { | |
1393 obj = OBJPTR(item); | |
1394 /* Construct how the line will look */ | |
1395 sprintf(linebuf, "%c) %s\n\r", ch, inv_name(obj,FALSE)); | |
1396 | |
1397 /* See how long it is */ | |
1398 curlen = strlen(linebuf) - 2; /* Don't count \n or \r */ | |
1399 if (maxlen < curlen) maxlen = curlen; | |
1400 | |
1401 /* Draw it in the window */ | |
1402 waddstr(hw, linebuf); | |
1403 | |
1404 if (++pagecnt >= lines - 2 && next(item) != NULL) { | |
1405 pagecnt = 0; | |
1406 maxlen = 0; | |
1407 dbotline(hw, spacemsg); | |
1408 wclear(hw); | |
1409 } | |
1410 if (ch == 'z') ch = 'A' - 1; | |
1411 } | |
1412 | |
1413 strcpy(linebuf, "Pick up what? (* for all): "); | |
1414 | |
1415 /* See how long it is */ | |
1416 curlen = strlen(linebuf); /* Don't count \n or \r */ | |
1417 if (maxlen < curlen) maxlen = curlen; | |
1418 | |
1419 /* Draw it in the window */ | |
1420 waddstr(hw, linebuf); | |
1421 | |
1422 /* | |
1423 * If we have fewer than half a screenful, don't clear the screen. | |
1424 * Leave 3 blank lines at the bottom and 3 blank columns to he right. | |
1425 */ | |
1426 if (menu_overlay && num_there < lines - 3) { | |
1427 over_win(cw, hw, num_there + 2, maxlen + 3, num_there, curlen, NULL); | |
1428 pagecnt = -1; /* Indicate we used over_win */ | |
1429 } | |
1430 else draw(hw); /* write screen */ | |
1431 | |
1432 for (;;) { | |
1433 do { | |
1434 ch = wgetch(cw); | |
1435 } until (isalpha(ch) || ch == '*' || ch == ESC); | |
1436 | |
1437 /* Redraw original screen */ | |
1438 if (pagecnt < 0) { | |
1439 clearok(cw, FALSE); /* Setup to redraw current screen */ | |
1440 touchwin(cw); /* clearing first */ | |
1441 draw(cw); | |
1442 } | |
1443 else restscr(cw); | |
1444 | |
1445 if (ch == ESC) { | |
1446 after = FALSE; | |
1447 msg(""); /* clear top line */ | |
1448 break; | |
1449 } | |
1450 if (ch == '*') { | |
1451 player.t_action = A_PICKUP; | |
1452 return(1); /* set action to PICKUP and delay for first one */ | |
1453 } | |
1454 /* ch has item to get from list */ | |
1455 | |
1456 cnt = 0; | |
1457 for (item = lvl_obj, och = 'a'; item != NULL && cnt < num_there; | |
1458 item = next(item), och++, cnt++) { | |
1459 if (ch == och) | |
1460 break; | |
1461 if (och == 'z') och = 'A' - 1; | |
1462 } | |
1463 if (item == NULL || cnt >= num_there) { | |
1464 wmove(hw, pagecnt < 0 ? num_there : pagecnt, 25); | |
1465 wprintw(hw, " [between 'a' and '%c']: ", | |
1466 och == 'A' ? 'z' : och-1); | |
1467 if (maxlen < 49) maxlen = 49; | |
1468 | |
1469 /* | |
1470 * If we have fewer than half a screenful, don't clear the | |
1471 * screen. Leave an extra blank line at the bottom and | |
1472 * 3 blank columns to the right. | |
1473 */ | |
1474 if (menu_overlay && num_there < lines - 3) { | |
1475 over_win(cw, hw, num_there + 2, maxlen + 3, | |
1476 num_there, 49, NULL); | |
1477 cnt = -1; /* Indicate we used over_win */ | |
1478 } | |
1479 else draw(hw); /* write screen */ | |
1480 continue; | |
1481 } | |
1482 else { | |
1483 detach(lvl_obj, item); | |
1484 if (add_pack(item, FALSE)) { | |
1485 /* | |
1486 * We make sure here that the dungeon floor gets | |
1487 * updated with what's left on the vacated spot. | |
1488 */ | |
1489 if ((item = find_obj(y, x)) == NULL) { | |
1490 coord roomcoord; /* Needed to pass to roomin() */ | |
1491 | |
1492 roomcoord.y = y; | |
1493 roomcoord.x = x; | |
1494 mvaddch(y, x, | |
1495 (roomin(&roomcoord) == NULL ? PASSAGE : FLOOR)); | |
1496 } | |
1497 else mvaddch(y, x, (OBJPTR(item))->o_type); | |
1498 return(1); | |
1499 } | |
1500 else attach(lvl_obj, item); /* Couldn't pick it up! */ | |
1501 break; | |
1502 } | |
1503 } | |
1504 } | |
1505 | |
1506 return(0); | |
1507 } | |
1508 | |
1509 /* | |
1510 * make_sell_pack: | |
1511 * | |
1512 * Create a pack for sellers (a la quartermaster) | |
1513 */ | |
1514 | |
1515 make_sell_pack(tp) | |
1516 struct thing *tp; | |
1517 { | |
1518 reg struct linked_list *item; | |
1519 reg struct object *obj; | |
1520 reg int sell_type = 0, nitems, i; | |
1521 | |
1522 /* Select the items */ | |
1523 nitems = rnd(5) + 7; | |
1524 | |
1525 switch (rnd(14)) { | |
1526 /* Armor */ | |
1527 case 0: | |
1528 case 1: | |
1529 turn_on(*tp, CARRYARMOR); | |
1530 sell_type = TYP_ARMOR; | |
1531 break; | |
1532 | |
1533 /* Weapon */ | |
1534 when 2: | |
1535 case 3: | |
1536 turn_on(*tp, CARRYWEAPON); | |
1537 sell_type = TYP_WEAPON; | |
1538 break; | |
1539 | |
1540 /* Staff or wand */ | |
1541 when 4: | |
1542 case 5: | |
1543 turn_on(*tp, CARRYSTICK); | |
1544 sell_type = TYP_STICK; | |
1545 break; | |
1546 | |
1547 /* Ring */ | |
1548 when 6: | |
1549 case 7: | |
1550 turn_on(*tp, CARRYRING); | |
1551 sell_type = TYP_RING; | |
1552 break; | |
1553 | |
1554 /* scroll */ | |
1555 when 8: | |
1556 case 9: | |
1557 turn_on(*tp, CARRYSCROLL); | |
1558 sell_type = TYP_SCROLL; | |
1559 break; | |
1560 | |
1561 /* potions */ | |
1562 when 10: | |
1563 case 11: | |
1564 turn_on(*tp, CARRYPOTION); | |
1565 sell_type = TYP_POTION; | |
1566 break; | |
1567 | |
1568 /* Miscellaneous magic */ | |
1569 when 12: | |
1570 case 13: | |
1571 turn_on(*tp, CARRYMISC); | |
1572 sell_type = TYP_MM; | |
1573 break; | |
1574 } | |
1575 for (i=0; i<nitems; i++) { | |
1576 item = new_thing(sell_type, FALSE); | |
1577 obj = OBJPTR(item); | |
1578 obj->o_pos = tp->t_pos; | |
1579 attach(tp->t_pack, item); | |
1580 } | |
1581 } | |
1582 |