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