|
|
1.1 root 1: /*
2: * Copyright (c) 1988 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Timothy C. Stoehr.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)pack.c 5.3 (Berkeley) 6/1/90";
25: #endif /* not lint */
26:
27: /*
28: * pack.c
29: *
30: * This source herein may be modified and/or distributed by anybody who
31: * so desires, with the following restrictions:
32: * 1.) No portion of this notice shall be removed.
33: * 2.) Credit shall not be taken for the creation of this source.
34: * 3.) This code is not to be traded, sold, or used for personal
35: * gain or profit.
36: *
37: */
38:
39: #include "rogue.h"
40:
41: char *curse_message = "you can't, it appears to be cursed";
42:
43: extern short levitate;
44:
45: object *
46: add_to_pack(obj, pack, condense)
47: object *obj, *pack;
48: {
49: object *op;
50:
51: if (condense) {
52: if (op = check_duplicate(obj, pack)) {
53: free_object(obj);
54: return(op);
55: } else {
56: obj->ichar = next_avail_ichar();
57: }
58: }
59: if (pack->next_object == 0) {
60: pack->next_object = obj;
61: } else {
62: op = pack->next_object;
63:
64: while (op->next_object) {
65: op = op->next_object;
66: }
67: op->next_object = obj;
68: }
69: obj->next_object = 0;
70: return(obj);
71: }
72:
73: take_from_pack(obj, pack)
74: object *obj, *pack;
75: {
76: while (pack->next_object != obj) {
77: pack = pack->next_object;
78: }
79: pack->next_object = pack->next_object->next_object;
80: }
81:
82: /* Note: *status is set to 0 if the rogue attempts to pick up a scroll
83: * of scare-monster and it turns to dust. *status is otherwise set to 1.
84: */
85:
86: object *
87: pick_up(row, col, status)
88: short *status;
89: {
90: object *obj;
91:
92: *status = 1;
93:
94: if (levitate) {
95: message("you're floating in the air!", 0);
96: return((object *) 0);
97: }
98: obj = object_at(&level_objects, row, col);
99: if (!obj) {
100: message("pick_up(): inconsistent", 1);
101: return(obj);
102: }
103: if ( (obj->what_is == SCROL) &&
104: (obj->which_kind == SCARE_MONSTER) &&
105: obj->picked_up) {
106: message("the scroll turns to dust as you pick it up", 0);
107: dungeon[row][col] &= (~OBJECT);
108: vanish(obj, 0, &level_objects);
109: *status = 0;
110: if (id_scrolls[SCARE_MONSTER].id_status == UNIDENTIFIED) {
111: id_scrolls[SCARE_MONSTER].id_status = IDENTIFIED;
112: }
113: return((object *) 0);
114: }
115: if (obj->what_is == GOLD) {
116: rogue.gold += obj->quantity;
117: dungeon[row][col] &= ~(OBJECT);
118: take_from_pack(obj, &level_objects);
119: print_stats(STAT_GOLD);
120: return(obj); /* obj will be free_object()ed in caller */
121: }
122: if (pack_count(obj) >= MAX_PACK_COUNT) {
123: message("pack too full", 1);
124: return((object *) 0);
125: }
126: dungeon[row][col] &= ~(OBJECT);
127: take_from_pack(obj, &level_objects);
128: obj = add_to_pack(obj, &rogue.pack, 1);
129: obj->picked_up = 1;
130: return(obj);
131: }
132:
133: drop()
134: {
135: object *obj, *new;
136: short ch;
137: char desc[DCOLS];
138:
139: if (dungeon[rogue.row][rogue.col] & (OBJECT | STAIRS | TRAP)) {
140: message("there's already something there", 0);
141: return;
142: }
143: if (!rogue.pack.next_object) {
144: message("you have nothing to drop", 0);
145: return;
146: }
147: if ((ch = pack_letter("drop what?", ALL_OBJECTS)) == CANCEL) {
148: return;
149: }
150: if (!(obj = get_letter_object(ch))) {
151: message("no such item.", 0);
152: return;
153: }
154: if (obj->in_use_flags & BEING_WIELDED) {
155: if (obj->is_cursed) {
156: message(curse_message, 0);
157: return;
158: }
159: unwield(rogue.weapon);
160: } else if (obj->in_use_flags & BEING_WORN) {
161: if (obj->is_cursed) {
162: message(curse_message, 0);
163: return;
164: }
165: mv_aquatars();
166: unwear(rogue.armor);
167: print_stats(STAT_ARMOR);
168: } else if (obj->in_use_flags & ON_EITHER_HAND) {
169: if (obj->is_cursed) {
170: message(curse_message, 0);
171: return;
172: }
173: un_put_on(obj);
174: }
175: obj->row = rogue.row;
176: obj->col = rogue.col;
177:
178: if ((obj->quantity > 1) && (obj->what_is != WEAPON)) {
179: obj->quantity--;
180: new = alloc_object();
181: *new = *obj;
182: new->quantity = 1;
183: obj = new;
184: } else {
185: obj->ichar = 'L';
186: take_from_pack(obj, &rogue.pack);
187: }
188: place_at(obj, rogue.row, rogue.col);
189: (void) strcpy(desc, "dropped ");
190: get_desc(obj, desc+8);
191: message(desc, 0);
192: (void) reg_move();
193: }
194:
195: object *
196: check_duplicate(obj, pack)
197: object *obj, *pack;
198: {
199: object *op;
200:
201: if (!(obj->what_is & (WEAPON | FOOD | SCROL | POTION))) {
202: return(0);
203: }
204: if ((obj->what_is == FOOD) && (obj->which_kind == FRUIT)) {
205: return(0);
206: }
207: op = pack->next_object;
208:
209: while (op) {
210: if ((op->what_is == obj->what_is) &&
211: (op->which_kind == obj->which_kind)) {
212:
213: if ((obj->what_is != WEAPON) ||
214: ((obj->what_is == WEAPON) &&
215: ((obj->which_kind == ARROW) ||
216: (obj->which_kind == DAGGER) ||
217: (obj->which_kind == DART) ||
218: (obj->which_kind == SHURIKEN)) &&
219: (obj->quiver == op->quiver))) {
220: op->quantity += obj->quantity;
221: return(op);
222: }
223: }
224: op = op->next_object;
225: }
226: return(0);
227: }
228:
229: next_avail_ichar()
230: {
231: register object *obj;
232: register i;
233: boolean ichars[26];
234:
235: for (i = 0; i < 26; i++) {
236: ichars[i] = 0;
237: }
238: obj = rogue.pack.next_object;
239: while (obj) {
240: ichars[(obj->ichar - 'a')] = 1;
241: obj = obj->next_object;
242: }
243: for (i = 0; i < 26; i++) {
244: if (!ichars[i]) {
245: return(i + 'a');
246: }
247: }
248: return('?');
249: }
250:
251: wait_for_ack()
252: {
253: while (rgetchar() != ' ') ;
254: }
255:
256: pack_letter(prompt, mask)
257: char *prompt;
258: unsigned short mask;
259: {
260: short ch;
261: unsigned short tmask = mask;
262:
263: if (!mask_pack(&rogue.pack, mask)) {
264: message("nothing appropriate", 0);
265: return(CANCEL);
266: }
267: for (;;) {
268:
269: message(prompt, 0);
270:
271: for (;;) {
272: ch = rgetchar();
273: if (!is_pack_letter(&ch, &mask)) {
274: sound_bell();
275: } else {
276: break;
277: }
278: }
279:
280: if (ch == LIST) {
281: check_message();
282: inventory(&rogue.pack, mask);
283: } else {
284: break;
285: }
286: mask = tmask;
287: }
288: check_message();
289: return(ch);
290: }
291:
292: take_off()
293: {
294: char desc[DCOLS];
295: object *obj;
296:
297: if (rogue.armor) {
298: if (rogue.armor->is_cursed) {
299: message(curse_message, 0);
300: } else {
301: mv_aquatars();
302: obj = rogue.armor;
303: unwear(rogue.armor);
304: (void) strcpy(desc, "was wearing ");
305: get_desc(obj, desc+12);
306: message(desc, 0);
307: print_stats(STAT_ARMOR);
308: (void) reg_move();
309: }
310: } else {
311: message("not wearing any", 0);
312: }
313: }
314:
315: wear()
316: {
317: short ch;
318: register object *obj;
319: char desc[DCOLS];
320:
321: if (rogue.armor) {
322: message("your already wearing some", 0);
323: return;
324: }
325: ch = pack_letter("wear what?", ARMOR);
326:
327: if (ch == CANCEL) {
328: return;
329: }
330: if (!(obj = get_letter_object(ch))) {
331: message("no such item.", 0);
332: return;
333: }
334: if (obj->what_is != ARMOR) {
335: message("you can't wear that", 0);
336: return;
337: }
338: obj->identified = 1;
339: (void) strcpy(desc, "wearing ");
340: get_desc(obj, desc + 8);
341: message(desc, 0);
342: do_wear(obj);
343: print_stats(STAT_ARMOR);
344: (void) reg_move();
345: }
346:
347: unwear(obj)
348: object *obj;
349: {
350: if (obj) {
351: obj->in_use_flags &= (~BEING_WORN);
352: }
353: rogue.armor = (object *) 0;
354: }
355:
356: do_wear(obj)
357: object *obj;
358: {
359: rogue.armor = obj;
360: obj->in_use_flags |= BEING_WORN;
361: obj->identified = 1;
362: }
363:
364: wield()
365: {
366: short ch;
367: register object *obj;
368: char desc[DCOLS];
369:
370: if (rogue.weapon && rogue.weapon->is_cursed) {
371: message(curse_message, 0);
372: return;
373: }
374: ch = pack_letter("wield what?", WEAPON);
375:
376: if (ch == CANCEL) {
377: return;
378: }
379: if (!(obj = get_letter_object(ch))) {
380: message("No such item.", 0);
381: return;
382: }
383: if (obj->what_is & (ARMOR | RING)) {
384: sprintf(desc, "you can't wield %s",
385: ((obj->what_is == ARMOR) ? "armor" : "rings"));
386: message(desc, 0);
387: return;
388: }
389: if (obj->in_use_flags & BEING_WIELDED) {
390: message("in use", 0);
391: } else {
392: unwield(rogue.weapon);
393: (void) strcpy(desc, "wielding ");
394: get_desc(obj, desc + 9);
395: message(desc, 0);
396: do_wield(obj);
397: (void) reg_move();
398: }
399: }
400:
401: do_wield(obj)
402: object *obj;
403: {
404: rogue.weapon = obj;
405: obj->in_use_flags |= BEING_WIELDED;
406: }
407:
408: unwield(obj)
409: object *obj;
410: {
411: if (obj) {
412: obj->in_use_flags &= (~BEING_WIELDED);
413: }
414: rogue.weapon = (object *) 0;
415: }
416:
417: call_it()
418: {
419: short ch;
420: register object *obj;
421: struct id *id_table;
422: char buf[MAX_TITLE_LENGTH+2];
423:
424: ch = pack_letter("call what?", (SCROL | POTION | WAND | RING));
425:
426: if (ch == CANCEL) {
427: return;
428: }
429: if (!(obj = get_letter_object(ch))) {
430: message("no such item.", 0);
431: return;
432: }
433: if (!(obj->what_is & (SCROL | POTION | WAND | RING))) {
434: message("surely you already know what that's called", 0);
435: return;
436: }
437: id_table = get_id_table(obj);
438:
439: if (get_input_line("call it:","",buf,id_table[obj->which_kind].title,1,1)) {
440: id_table[obj->which_kind].id_status = CALLED;
441: (void) strcpy(id_table[obj->which_kind].title, buf);
442: }
443: }
444:
445: pack_count(new_obj)
446: object *new_obj;
447: {
448: object *obj;
449: short count = 0;
450:
451: obj = rogue.pack.next_object;
452:
453: while (obj) {
454: if (obj->what_is != WEAPON) {
455: count += obj->quantity;
456: } else if (!new_obj) {
457: count++;
458: } else if ((new_obj->what_is != WEAPON) ||
459: ((obj->which_kind != ARROW) &&
460: (obj->which_kind != DAGGER) &&
461: (obj->which_kind != DART) &&
462: (obj->which_kind != SHURIKEN)) ||
463: (new_obj->which_kind != obj->which_kind) ||
464: (obj->quiver != new_obj->quiver)) {
465: count++;
466: }
467: obj = obj->next_object;
468: }
469: return(count);
470: }
471:
472: boolean
473: mask_pack(pack, mask)
474: object *pack;
475: unsigned short mask;
476: {
477: while (pack->next_object) {
478: pack = pack->next_object;
479: if (pack->what_is & mask) {
480: return(1);
481: }
482: }
483: return(0);
484: }
485:
486: is_pack_letter(c, mask)
487: short *c;
488: unsigned short *mask;
489: {
490: if (((*c == '?') || (*c == '!') || (*c == ':') || (*c == '=') ||
491: (*c == ')') || (*c == ']') || (*c == '/') || (*c == ','))) {
492: switch(*c) {
493: case '?':
494: *mask = SCROL;
495: break;
496: case '!':
497: *mask = POTION;
498: break;
499: case ':':
500: *mask = FOOD;
501: break;
502: case ')':
503: *mask = WEAPON;
504: break;
505: case ']':
506: *mask = ARMOR;
507: break;
508: case '/':
509: *mask = WAND;
510: break;
511: case '=':
512: *mask = RING;
513: break;
514: case ',':
515: *mask = AMULET;
516: break;
517: }
518: *c = LIST;
519: return(1);
520: }
521: return(((*c >= 'a') && (*c <= 'z')) || (*c == CANCEL) || (*c == LIST));
522: }
523:
524: has_amulet()
525: {
526: return(mask_pack(&rogue.pack, AMULET));
527: }
528:
529: kick_into_pack()
530: {
531: object *obj;
532: char desc[DCOLS];
533: short n, stat;
534:
535: if (!(dungeon[rogue.row][rogue.col] & OBJECT)) {
536: message("nothing here", 0);
537: } else {
538: if (obj = pick_up(rogue.row, rogue.col, &stat)) {
539: get_desc(obj, desc);
540: if (obj->what_is == GOLD) {
541: message(desc, 0);
542: free_object(obj);
543: } else {
544: n = strlen(desc);
545: desc[n] = '(';
546: desc[n+1] = obj->ichar;
547: desc[n+2] = ')';
548: desc[n+3] = 0;
549: message(desc, 0);
550: }
551: }
552: if (obj || (!stat)) {
553: (void) reg_move();
554: }
555: }
556: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.