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