Annotation of early-roguelike/rogue3/pack.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * Routines to deal with the pack
3: *
4: * @(#)pack.c 3.6 (Berkeley) 6/15/81
5: *
6: * Rogue: Exploring the Dungeons of Doom
7: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
8: * All rights reserved.
9: *
10: * See the file LICENSE.TXT for full copyright and licensing information.
11: */
12:
13: #include "curses.h"
14: #include <ctype.h>
15: #include "rogue.h"
16:
17: /*
18: * add_pack:
19: * Pick up an object and add it to the pack. If the argument is non-null
20: * use it as the linked_list pointer instead of gettting it off the ground.
21: */
22: void
23: add_pack(struct linked_list *item, int silent)
24: {
25: struct linked_list *ip, *lp = NULL;
26: struct object *obj, *op = NULL;
27: int exact, from_floor;
28:
29: if (item == NULL)
30: {
31: from_floor = TRUE;
32: if ((item = find_obj(hero.y, hero.x)) == NULL)
33: return;
34: }
35: else
36: from_floor = FALSE;
37: obj = (struct object *) ldata(item);
38: /*
39: * Link it into the pack. Search the pack for a object of similar type
40: * if there isn't one, stuff it at the beginning, if there is, look for one
41: * that is exactly the same and just increment the count if there is.
42: * it that. Food is always put at the beginning for ease of access, but
43: * is not ordered so that you can't tell good food from bad. First check
44: * to see if there is something in thr same group and if there is then
45: * increment the count.
46: */
47: if (obj->o_group)
48: {
49: for (ip = pack; ip != NULL; ip = next(ip))
50: {
51: op = (struct object *) ldata(ip);
52: if (op->o_group == obj->o_group)
53: {
54: /*
55: * Put it in the pack and notify the user
56: */
57: op->o_count++;
58: if (from_floor)
59: {
60: detach(lvl_obj, item);
61: mvaddch(hero.y, hero.x,
62: (roomin(&hero) == NULL ? PASSAGE : FLOOR));
63: }
64: discard(item);
65: item = ip;
66: goto picked_up;
67: }
68: }
69: }
70: /*
71: * Check if there is room
72: */
73: if (inpack == MAXPACK-1)
74: {
75: msg("You can't carry anything else.");
76: return;
77: }
78: /*
79: * Check for and deal with scare monster scrolls
80: */
81: if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
82: if (obj->o_flags & ISFOUND)
83: {
84: msg("The scroll turns to dust as you pick it up.");
85: detach(lvl_obj, item);
86: mvaddch(hero.y, hero.x, FLOOR);
87: return;
88: }
89: else
90: obj->o_flags |= ISFOUND;
91:
92: inpack++;
93: if (from_floor)
94: {
95: detach(lvl_obj, item);
96: mvaddch(hero.y, hero.x, (roomin(&hero) == NULL ? PASSAGE : FLOOR));
97: }
98: /*
99: * Search for an object of the same type
100: */
101: exact = FALSE;
102: for (ip = pack; ip != NULL; ip = next(ip))
103: {
104: op = (struct object *) ldata(ip);
105: if (obj->o_type == op->o_type)
106: break;
107: }
108: if (ip == NULL)
109: {
110: /*
111: * Put it at the end of the pack since it is a new type
112: */
113: for (ip = pack; ip != NULL; ip = next(ip))
114: {
115: op = (struct object *) ldata(ip);
116: if (op->o_type != FOOD)
117: break;
118: lp = ip;
119: }
120: }
121: else
122: {
123: /*
124: * Search for an object which is exactly the same
125: */
126: while (ip != NULL && op->o_type == obj->o_type)
127: {
128: if (op->o_which == obj->o_which)
129: {
130: exact = TRUE;
131: break;
132: }
133: lp = ip;
134: if ((ip = next(ip)) == NULL)
135: break;
136: op = (struct object *) ldata(ip);
137: }
138: }
139: if (ip == NULL)
140: {
141: /*
142: * Didn't find an exact match, just stick it here
143: */
144: if (pack == NULL)
145: pack = item;
146: else
147: {
148: lp->l_next = item;
149: item->l_prev = lp;
150: item->l_next = NULL;
151: }
152: }
153: else
154: {
155: /*
156: * If we found an exact match. If it is a potion, food, or a
157: * scroll, increase the count, otherwise put it with its clones.
158: */
159: if (exact && ISMULT(obj->o_type))
160: {
161: op->o_count++;
162: discard(item);
163: item = ip;
164: goto picked_up;
165: }
166: if ((item->l_prev = prev(ip)) != NULL)
167: item->l_prev->l_next = item;
168: else
169: pack = item;
170: item->l_next = ip;
171: ip->l_prev = item;
172: }
173: picked_up:
174: /*
175: * Notify the user
176: */
177: obj = (struct object *) ldata(item);
178: if (notify && !silent)
179: {
180: if (!terse)
181: addmsg("You now have ");
182: msg("%s (%c)", inv_name(obj, !terse), pack_char(obj));
183: }
184: if (obj->o_type == AMULET)
185: amulet = TRUE;
186: }
187:
188: /*
189: * inventory:
190: * list what is in the pack
191: */
192: int
193: inventory(struct linked_list *list, int type)
194: {
195: struct object *obj;
196: int ch;
197: int n_objs;
198: char inv_temp[80];
199:
200: n_objs = 0;
201: for (ch = 'a'; list != NULL; ch++, list = next(list))
202: {
203: obj = (struct object *) ldata(list);
204: if (type && type != obj->o_type && !(type == CALLABLE &&
205: (obj->o_type == SCROLL || obj->o_type == POTION ||
206: obj->o_type == RING || obj->o_type == STICK)))
207: continue;
208: switch (n_objs++)
209: {
210: /*
211: * For the first thing in the inventory, just save the string
212: * in case there is only one.
213: */
214: case 0:
215: sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
216: break;
217: /*
218: * If there is more than one, clear the screen, print the
219: * saved message and fall through to ...
220: */
221: case 1:
222: if (slow_invent)
223: msg(inv_temp);
224: else
225: {
226: wclear(hw);
227: waddstr(hw, inv_temp);
228: waddch(hw, '\n');
229: }
230: /*
231: * Print the line for this object
232: */
233: default:
234: if (slow_invent)
235: msg("%c) %s", ch, inv_name(obj, FALSE));
236: else
237: wprintw(hw, "%c) %s\n", ch, inv_name(obj, FALSE));
238: }
239: }
240: if (n_objs == 0)
241: {
242: if (terse)
243: msg(type == 0 ? "Empty handed." :
244: "Nothing appropriate");
245: else
246: msg(type == 0 ? "You are empty handed." :
247: "You don't have anything appropriate");
248: return FALSE;
249: }
250: if (n_objs == 1)
251: {
252: msg(inv_temp);
253: return TRUE;
254: }
255: if (!slow_invent)
256: {
257: mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
258: draw(hw);
259: wait_for(hw,' ');
260: clearok(cw, TRUE);
261: touchwin(cw);
262: }
263: return TRUE;
264: }
265:
266: /*
267: * pick_up:
268: * Add something to characters pack.
269: */
270: void
271: pick_up(int ch)
272: {
273: switch(ch)
274: {
275: case GOLD:
276: money();
277: break;
278: default:
279: debug("Where did you pick that up???");
280: case ARMOR:
281: case POTION:
282: case FOOD:
283: case WEAPON:
284: case SCROLL:
285: case AMULET:
286: case RING:
287: case STICK:
288: add_pack(NULL, FALSE);
289: break;
290: }
291: }
292:
293: /*
294: * picky_inven:
295: * Allow player to inventory a single item
296: */
297: void
298: picky_inven()
299: {
300: struct linked_list *item;
301: int ch, mch;
302:
303: if (pack == NULL)
304: msg("You aren't carrying anything");
305: else if (next(pack) == NULL)
306: msg("a) %s", inv_name((struct object *) ldata(pack), FALSE));
307: else
308: {
309: msg(terse ? "Item: " : "Which item do you wish to inventory: ");
310: mpos = 0;
311: if ((mch = readchar(cw)) == ESCAPE)
312: {
313: msg("");
314: return;
315: }
316: for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
317: if (ch == mch)
318: {
319: msg("%c) %s",ch,inv_name((struct object *) ldata(item), FALSE));
320: return;
321: }
322: if (!terse)
323: msg("'%s' not in pack", unctrl(mch));
324: msg("Range is 'a' to '%c'", --ch);
325: }
326: }
327:
328: /*
329: * get_item:
330: * pick something out of a pack for a purpose
331: */
332: struct linked_list *
333: get_item(char *purpose, int type)
334: {
335: struct linked_list *obj;
336: int ch, och;
337:
338: if (pack == NULL)
339: msg("You aren't carrying anything.");
340: else
341: {
342: for (;;)
343: {
344: if (!terse)
345: addmsg("Which object do you want to ");
346: addmsg(purpose);
347: if (terse)
348: addmsg(" what");
349: msg("? (* for list): ");
350: ch = readchar(cw);
351: mpos = 0;
352: /*
353: * Give the poor player a chance to abort the command
354: */
355: if (ch == ESCAPE || ch == CTRL('G'))
356: {
357: after = FALSE;
358: msg("");
359: return NULL;
360: }
361: if (ch == '*')
362: {
363: mpos = 0;
364: if (inventory(pack, type) == 0)
365: {
366: after = FALSE;
367: return NULL;
368: }
369: continue;
370: }
371: for (obj = pack, och = 'a'; obj != NULL; obj = next(obj), och++)
372: if (ch == och)
373: break;
374: if (obj == NULL)
375: {
376: msg("Please specify a letter between 'a' and '%c'", och-1);
377: continue;
378: }
379: else
380: return obj;
381: }
382: }
383: return NULL;
384: }
385:
386: int
387: pack_char(struct object *obj)
388: {
389: struct linked_list *item;
390: int c;
391:
392: c = 'a';
393: for (item = pack; item != NULL; item = next(item))
394: if ((struct object *) ldata(item) == obj)
395: return c;
396: else
397: c++;
398: return 'z';
399: }
CVSweb