Annotation of early-roguelike/srogue/pack.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * Routines to deal with the pack
3: *
4: * @(#)pack.c 9.0 (rdk) 7/17/84
5: *
6: * Super-Rogue
7: * Copyright (C) 1984 Robert D. Kindelberger
8: * All rights reserved.
9: *
10: * Based on "Rogue: Exploring the Dungeons of Doom"
11: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
12: * All rights reserved.
13: *
14: * See the file LICENSE.TXT for full copyright and licensing information.
15: */
16:
17: #include <ctype.h>
18: #include "rogue.h"
19: #include "rogue.ext"
20:
21: /*
22: * add_pack:
23: * Pick up an object and add it to the pack. If the argument
24: * is non-null use it as the linked_list pointer instead of
25: * getting it off the ground.
26: */
27: bool
28: add_pack(struct linked_list *item, bool silent)
29: {
30: reg struct linked_list *ip, *lp;
31: reg struct object *obj, *op = NULL;
32: bool from_floor;
33: char delchar;
34:
35: if (player.t_room == NULL)
36: delchar = PASSAGE;
37: else
38: delchar = FLOOR;
39: if (item == NULL) {
40: from_floor = TRUE;
41: if ((item = find_obj(hero.y, hero.x)) == NULL) {
42: mpos = 0;
43: msg("That object must have been an illusion.");
44: mvaddch(hero.y, hero.x, delchar);
45: return FALSE;
46: }
47: /*
48: * Check for scare monster scrolls
49: */
50: obj = OBJPTR(item);
51: if (obj->o_type == SCROLL && obj->o_which == S_SCARE) {
52: if (o_on(obj,ISFOUND)) {
53: msg("The scroll turns to dust as you pick it up.");
54: detach(lvl_obj, item);
55: discard(item);
56: mvaddch(hero.y, hero.x, delchar);
57: return FALSE;
58: }
59: }
60: }
61: else
62: from_floor = FALSE;
63: obj = OBJPTR(item);
64: /*
65: * See if this guy can carry any more weight
66: */
67: if (itemweight(obj) + him->s_pack > him->s_carry) {
68: msg("You can't carry that %s.", obj->o_typname);
69: return FALSE;
70: }
71: /*
72: * Check if there is room
73: */
74: if (packvol + obj->o_vol > V_PACK) {
75: msg("That %s won't fit in your pack.", obj->o_typname);
76: return FALSE;
77: }
78: if (from_floor) {
79: detach(lvl_obj, item);
80: mvaddch(hero.y, hero.x, delchar);
81: }
82: item->l_prev = NULL;
83: item->l_next = NULL;
84: setoflg(obj, ISFOUND);
85: /*
86: * start looking thru pack to find the start of items
87: * with the same type.
88: */
89: lp = pack;
90: for (ip = pack; ip != NULL; ip = next(ip)) {
91: op = OBJPTR(ip);
92: /*
93: * If we find a matching type then quit.
94: */
95: if (op->o_type == obj->o_type)
96: break;
97: if (next(ip) != NULL)
98: lp = next(lp); /* update "previous" entry */
99: }
100: /*
101: * If the pack was empty, just stick the item in it.
102: */
103: if (pack == NULL) {
104: pack = item;
105: item->l_prev = NULL;
106: }
107: /*
108: * If we looked thru the pack, but could not find an
109: * item of the same type, then stick it at the end,
110: * unless it was food, then put it in front.
111: */
112: else if (ip == NULL) {
113: if (obj->o_type == FOOD) { /* insert food at front */
114: item->l_next = pack;
115: pack->l_prev = item;
116: pack = item;
117: item->l_prev = NULL;
118: }
119: else { /* insert other stuff at back */
120: lp->l_next = item;
121: item->l_prev = lp;
122: }
123: }
124: /*
125: * Here, we found at least one item of the same type.
126: * Look thru these items to see if there is one of the
127: * same group. If so, increment the count and throw the
128: * new item away. If not, stick it at the end of the
129: * items with the same type. Also keep all similar
130: * objects near each other, like all identify scrolls, etc.
131: */
132: else {
133: struct linked_list **save;
134:
135: while (ip != NULL && op->o_type == obj->o_type) {
136: if (op->o_group == obj->o_group) {
137: if (op->o_flags == obj->o_flags) {
138: op->o_count++;
139: discard(item);
140: item = ip;
141: goto picked_up;
142: }
143: else {
144: goto around;
145: }
146: }
147: if (op->o_which == obj->o_which) {
148: if (obj->o_type == FOOD)
149: ip = next(ip);
150: break;
151: }
152: around:
153: ip = next(ip);
154: if (ip != NULL) {
155: op = OBJPTR(ip);
156: lp = next(lp);
157: }
158: }
159: /*
160: * If inserting into last of group at end of pack,
161: * just tack on the end.
162: */
163: if (ip == NULL) {
164: lp->l_next = item;
165: item->l_prev = lp;
166: }
167: /*
168: * Insert into the last of a group of objects
169: * not at the end of the pack.
170: */
171: else {
172: save = &((ip->l_prev)->l_next);
173: item->l_next = ip;
174: item->l_prev = ip->l_prev;
175: ip->l_prev = item;
176: *save = item;
177: }
178: }
179: picked_up:
180: obj = OBJPTR(item);
181: if (!silent)
182: msg("%s (%c)",inv_name(obj,FALSE),pack_char(obj));
183: if (obj->o_type == AMULET)
184: amulet = TRUE;
185: updpack(); /* new pack weight & volume */
186: return TRUE;
187: }
188:
189: /*
190: * inventory:
191: * Show what items are in a specific list
192: */
193: bool
194: inventory(struct linked_list *list, int type)
195: {
196: reg struct linked_list *pc;
197: reg struct object *obj;
198: reg char ch;
199: reg int cnt;
200:
201: if (list == NULL) { /* empty list */
202: msg(type == 0 ? "Empty handed." : "Nothing appropriate.");
203: return FALSE;
204: }
205: else if (next(list) == NULL) { /* only 1 item in list */
206: obj = OBJPTR(list);
207: msg("a) %s", inv_name(obj, FALSE));
208: return TRUE;
209: }
210: cnt = 0;
211: wclear(hw);
212: for (ch = 'a', pc = list; pc != NULL; pc = next(pc), ch = npch(ch)) {
213: obj = OBJPTR(pc);
214: wprintw(hw,"%c) %s\n\r",ch,inv_name(obj, FALSE));
215: if (++cnt > LINES - 2 && next(pc) != NULL) {
216: dbotline(hw, morestr);
217: cnt = 0;
218: wclear(hw);
219: }
220: }
221: dbotline(hw,spacemsg);
222: restscr(cw);
223: return TRUE;
224: }
225:
226: /*
227: * pick_up:
228: * Add something to characters pack.
229: */
230: void
231: pick_up(char ch)
232: {
233: nochange = FALSE;
234: switch(ch) {
235: case GOLD:
236: money();
237: when ARMOR:
238: case POTION:
239: case FOOD:
240: case WEAPON:
241: case SCROLL:
242: case AMULET:
243: case RING:
244: case STICK:
245: add_pack(NULL, FALSE);
246: otherwise:
247: msg("That item is ethereal !!!");
248: }
249: }
250:
251: /*
252: * picky_inven:
253: * Allow player to inventory a single item
254: */
255: void
256: picky_inven(void)
257: {
258: reg struct linked_list *item;
259: reg char ch, mch;
260:
261: if (pack == NULL)
262: msg("You aren't carrying anything.");
263: else if (next(pack) == NULL)
264: msg("a) %s", inv_name(OBJPTR(pack), FALSE));
265: else {
266: msg("Item: ");
267: mpos = 0;
268: if ((mch = readchar()) == ESCAPE) {
269: msg("");
270: return;
271: }
272: for (ch='a',item=pack; item != NULL; item=next(item),ch=npch(ch))
273: if (ch == mch) {
274: msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE));
275: return;
276: }
277: if (ch == 'A')
278: ch = 'z';
279: else
280: ch -= 1;
281: msg("Range is 'a' to '%c'", ch);
282: }
283: }
284:
285: /*
286: * get_item:
287: * pick something out of a pack for a purpose
288: */
289: struct linked_list *
290: get_item(char *purpose, int type)
291: {
292: reg struct linked_list *obj, *pit, *savepit = NULL;
293: struct object *pob;
294: int ch, och, anr, cnt;
295:
296: if (pack == NULL) {
297: msg("You aren't carrying anything.");
298: return NULL;
299: }
300: if (type != WEAPON && (type != 0 || next(pack) == NULL)) {
301: /*
302: * see if we have any of the type requested
303: */
304: pit = pack;
305: anr = 0;
306: for (ch = 'a'; pit != NULL; pit = next(pit), ch = npch(ch)) {
307: pob = OBJPTR(pit);
308: if (type == pob->o_type || type == 0) {
309: ++anr;
310: savepit = pit; /* save in case of only 1 */
311: }
312: }
313: if (anr == 0) {
314: msg("Nothing to %s",purpose);
315: after = FALSE;
316: return NULL;
317: }
318: else if (anr == 1) { /* only found one of 'em */
319: do {
320: struct object *opb;
321:
322: opb = OBJPTR(savepit);
323: msg("%s what (* for the item)?",purpose);
324: och = readchar();
325: if (och == '*') {
326: mpos = 0;
327: msg("%c) %s",pack_char(opb),inv_name(opb,FALSE));
328: continue;
329: }
330: if (och == ESCAPE) {
331: msg("");
332: after = FALSE;
333: return NULL;
334: }
335: if (isalpha(och) && och != pack_char(opb)) {
336: mpos = 0;
337: msg("You can't %s that !!", purpose);
338: after = FALSE;
339: return NULL;
340: }
341: } while(!isalpha(och));
342: mpos = 0;
343: return savepit; /* return this item */
344: }
345: }
346: for (;;) {
347: msg("%s what? (* for list): ",purpose);
348: ch = readchar();
349: mpos = 0;
350: if (ch == ESCAPE) { /* abort if escape hit */
351: after = FALSE;
352: msg(""); /* clear display */
353: return NULL;
354: }
355: if (ch == '*') {
356: wclear(hw);
357: pit = pack; /* point to pack */
358: cnt = 0;
359: for (ch='a'; pit != NULL; pit=next(pit), ch=npch(ch)) {
360: pob = OBJPTR(pit);
361: if (type == 0 || type == pob->o_type) {
362: wprintw(hw,"%c) %s\n\r",ch,inv_name(pob,FALSE));
363: if (++cnt > LINES - 2 && next(pit) != NULL) {
364: cnt = 0;
365: dbotline(hw, morestr);
366: wclear(hw);
367: }
368: }
369: }
370: wmove(hw, LINES - 1,0);
371: wprintw(hw,"%s what? ",purpose);
372: draw(hw); /* write screen */
373: anr = FALSE;
374: do {
375: ch = readchar();
376: if (isalpha(ch) || ch == ESCAPE)
377: anr = TRUE;
378: } while(!anr); /* do till we got it right */
379: restscr(cw); /* redraw orig screen */
380: if (ch == ESCAPE) {
381: after = FALSE;
382: msg(""); /* clear top line */
383: return NULL; /* all done if abort */
384: }
385: /* ch has item to get from pack */
386: }
387: for (obj=pack,och='a';obj!=NULL;obj=next(obj),och=npch(och))
388: if (ch == och)
389: break;
390: if (obj == NULL) {
391: if (och == 'A')
392: och = 'z';
393: else
394: och -= 1;
395: msg("Please specify a letter between 'a' and '%c'",och);
396: continue;
397: }
398: else
399: return obj;
400: }
401: }
402:
403: /*
404: * pack_char:
405: * Get the character of a particular item in the pack
406: */
407: char
408: pack_char(struct object *obj)
409: {
410: reg struct linked_list *item;
411: reg char c;
412:
413: c = 'a';
414: for (item = pack; item != NULL; item = next(item))
415: if (OBJPTR(item) == obj)
416: return c;
417: else
418: c = npch(c);
419: return '%';
420: }
421:
422: /*
423: * idenpack:
424: * Identify all the items in the pack
425: */
426: void
427: idenpack(void)
428: {
429: reg struct linked_list *pc;
430:
431: for (pc = pack ; pc != NULL ; pc = next(pc))
432: whatis(pc);
433: }
434:
435:
436: /*
437: * del_pack:
438: * Take something out of the hero's pack
439: */
440: void
441: del_pack(struct linked_list *what)
442: {
443: reg struct object *op;
444:
445: op = OBJPTR(what);
446: cur_null(op); /* check for current stuff */
447: if (op->o_count > 1) {
448: op->o_count--;
449: }
450: else {
451: detach(pack,what);
452: discard(what);
453: }
454: updpack();
455: }
456:
457: /*
458: * cur_null:
459: * This updates cur_weapon etc for dropping things
460: */
461: void
462: cur_null(struct object *op)
463: {
464: if (op == cur_weapon)
465: cur_weapon = NULL;
466: else if (op == cur_armor)
467: cur_armor = NULL;
468: else if (op == cur_ring[LEFT])
469: cur_ring[LEFT] = NULL;
470: else if (op == cur_ring[RIGHT])
471: cur_ring[RIGHT] = NULL;
472: }
CVSweb