Annotation of early-roguelike/rogue4/pack.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * Routines to deal with the pack
3: *
4: * @(#)pack.c 4.15 (Berkeley) 4/6/82
5: *
6: * Rogue: Exploring the Dungeons of Doom
7: * Copyright (C) 1980, 1981, 1982 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: void money(int value);
18:
19: /*
20: * update_mdest:
21: * Called after picking up an object, before discarding it.
22: * If this was the object of something's desire, that monster will
23: * get mad and run at the hero
24: */
25: void
26: update_mdest(THING *obj)
27: {
28: register THING *mp;
29:
30: for (mp = mlist; mp != NULL; mp = next(mp))
31: if (mp->t_dest == &obj->o_pos)
32: mp->t_dest = &hero;
33: }
34:
35: /*
36: * add_pack:
37: * Pick up an object and add it to the pack. If the argument is
38: * non-null use it as the linked_list pointer instead of gettting
39: * it off the ground.
40: */
41: void
42: add_pack(THING *obj, bool silent)
43: {
44: register THING *op, *lp = NULL;
45: register bool exact, from_floor;
46: register char floor;
47: int discarded = 0;
48:
49: if (obj == NULL)
50: {
51: from_floor = TRUE;
52: if ((obj = find_obj(hero.y, hero.x)) == NULL)
53: return;
54: }
55: else
56: from_floor = FALSE;
57: /*
58: * Link it into the pack. Search the pack for a object of similar type
59: * if there isn't one, stuff it at the beginning, if there is, look for one
60: * that is exactly the same and just increment the count if there is.
61: * it that. Food is always put at the beginning for ease of access, but
62: * is not ordered so that you can't tell good food from bad. First check
63: * to see if there is something in thr same group and if there is then
64: * increment the count.
65: */
66: /* floor = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR; */
67: if (proom) floor = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
68: else floor = FLOOR;
69: if (obj->o_group)
70: {
71: for (op = pack; op != NULL; op = next(op))
72: {
73: if (op->o_group == obj->o_group)
74: {
75: /*
76: * Put it in the pack and notify the user
77: */
78: op->o_count++;
79: if (from_floor)
80: {
81: detach(lvl_obj, obj);
82: mvaddch(hero.y, hero.x, floor);
83: chat(hero.y, hero.x) = floor;
84: }
85: update_mdest(obj);
86: discard(obj);
87: obj = op;
88: discarded = 1;
89: goto picked_up;
90: }
91: }
92: }
93: /*
94: * Check if there is room
95: */
96: if (inpack == MAXPACK-1)
97: {
98: msg("you can't carry anything else");
99: return;
100: }
101: /*
102: * Check for and deal with scare monster scrolls
103: */
104: if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
105: if (obj->o_flags & ISFOUND)
106: {
107: detach(lvl_obj, obj);
108: mvaddch(hero.y, hero.x, floor);
109: chat(hero.y, hero.x) = floor;
110: msg("the scroll turns to dust as you pick it up");
111: return;
112: }
113: else
114: obj->o_flags |= ISFOUND;
115:
116: inpack++;
117: if (from_floor)
118: {
119: detach(lvl_obj, obj);
120: mvaddch(hero.y, hero.x, floor);
121: chat(hero.y, hero.x) = floor;
122: }
123: /*
124: * Search for an object of the same type
125: */
126: exact = FALSE;
127: for (op = pack; op != NULL; op = next(op))
128: if (obj->o_type == op->o_type)
129: break;
130: if (op == NULL)
131: {
132: /*
133: * Put it at the end of the pack since it is a new type
134: */
135: for (op = pack; op != NULL; op = next(op))
136: {
137: if (op->o_type != FOOD)
138: break;
139: lp = op;
140: }
141: }
142: else
143: {
144: /*
145: * Search for an object which is exactly the same
146: */
147: while (op->o_type == obj->o_type)
148: {
149: if (op->o_which == obj->o_which)
150: {
151: exact = TRUE;
152: break;
153: }
154: lp = op;
155: if ((op = next(op)) == NULL)
156: break;
157: }
158: }
159: if (op == NULL)
160: {
161: /*
162: * Didn't find an exact match, just stick it here
163: */
164: if (pack == NULL)
165: pack = obj;
166: else
167: {
168: lp->l_next = obj;
169: obj->l_prev = lp;
170: obj->l_next = NULL;
171: }
172: }
173: else
174: {
175: /*
176: * If we found an exact match. If it is a potion, food, or a
177: * scroll, increase the count, otherwise put it with its clones.
178: */
179: if (exact && ISMULT(obj->o_type))
180: {
181: op->o_count++;
182: update_mdest(obj);
183: discard(obj);
184: obj = op;
185: discarded = 1;
186: goto picked_up;
187: }
188: if ((obj->l_prev = prev(op)) != NULL)
189: obj->l_prev->l_next = obj;
190: else
191: pack = obj;
192: obj->l_next = op;
193: op->l_prev = obj;
194: }
195: picked_up:
196: /*
197: * If this was the object of something's desire, that monster will
198: * get mad and run at the hero
199: */
200: if (!discarded)
201: update_mdest(obj);
202:
203: if (obj->o_type == AMULET)
204: amulet = TRUE;
205: /*
206: * Notify the user
207: */
208: if (!silent)
209: {
210: if (!terse)
211: addmsg("you now have ");
212: msg("%s (%c)", inv_name(obj, !terse), pack_char(obj));
213: }
214: }
215:
216: /*
217: * inventory:
218: * List what is in the pack
219: */
220: bool
221: inventory(THING *list, int type)
222: {
223: register char ch;
224: register int n_objs;
225: char inv_temp[MAXSTR];
226:
227: n_objs = 0;
228: for (ch = 'a'; list != NULL; ch++, list = next(list))
229: {
230: if (type && type != list->o_type && !(type == CALLABLE &&
231: (list->o_type == SCROLL || list->o_type == POTION ||
232: list->o_type == RING || list->o_type == STICK)))
233: continue;
234: n_objs++;
235: sprintf(inv_temp, "%c) %%s", ch);
236: add_line(inv_temp, inv_name(list, FALSE));
237: }
238: if (n_objs == 0)
239: {
240: if (terse)
241: msg(type == 0 ? "empty handed" :
242: "nothing appropriate");
243: else
244: msg(type == 0 ? "you are empty handed" :
245: "you don't have anything appropriate");
246: return FALSE;
247: }
248: end_line();
249: return TRUE;
250: }
251:
252: /*
253: * pick_up:
254: * Add something to characters pack.
255: */
256: void
257: pick_up(char ch)
258: {
259: register THING *obj, *mp;
260:
261: switch (ch)
262: {
263: case GOLD:
264: if ((obj = find_obj(hero.y, hero.x)) == NULL)
265: return;
266: money(obj->o_goldval);
267: detach(lvl_obj, obj);
268: update_mdest(obj);
269: discard(obj);
270: proom->r_goldval = 0;
271: break;
272: default:
273: #ifdef WIZARD
274: debug("Where did you pick a '%s' up???", unctrol(ch));
275: #endif
276: case ARMOR:
277: case POTION:
278: case FOOD:
279: case WEAPON:
280: case SCROLL:
281: case AMULET:
282: case RING:
283: case STICK:
284: add_pack(NULL, FALSE);
285: break;
286: }
287: }
288:
289: /*
290: * picky_inven:
291: * Allow player to inventory a single item
292: */
293: void
294: picky_inven(void)
295: {
296: register THING *obj;
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(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', obj = pack; obj != NULL; obj = next(obj), ch++)
313: if (ch == mch)
314: {
315: msg("%c) %s",ch,inv_name(obj, FALSE));
316: return;
317: }
318: if (!terse)
319: msg("'%s' not in pack", unctrol(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: THING *
329: get_item(char *purpose, int type)
330: {
331: register THING *obj;
332: register char ch, och;
333:
334: if (pack == NULL)
335: msg("you aren't carrying anything");
336: else
337: {
338: for (;;)
339: {
340: if (!terse)
341: addmsg("which object do you want to ");
342: addmsg(purpose);
343: if (terse)
344: addmsg(" what");
345: msg("? (* for list): ");
346: ch = readchar();
347: mpos = 0;
348: /*
349: * Give the poor player a chance to abort the command
350: */
351: if (ch == ESCAPE || ch == CTRL('G'))
352: {
353: after = FALSE;
354: msg("");
355: return NULL;
356: }
357: if (ch == '*')
358: {
359: mpos = 0;
360: if (inventory(pack, type) == 0)
361: {
362: after = FALSE;
363: return NULL;
364: }
365: continue;
366: }
367: for (obj = pack, och = 'a'; obj != NULL; obj = next(obj), och++)
368: if (ch == och)
369: break;
370: if (obj == NULL)
371: {
372: msg("please specify a letter between 'a' and '%c'", och-1);
373: continue;
374: }
375: else
376: return obj;
377: }
378: }
379: return NULL;
380: }
381:
382: /*
383: * pack_char:
384: * Return which character would address a pack object
385: */
386: char
387: pack_char(THING *obj)
388: {
389: register THING *item;
390: register char c;
391:
392: c = 'a';
393: for (item = pack; item != NULL; item = next(item))
394: if (item == obj)
395: return c;
396: else
397: c++;
398: return '?';
399: }
400:
401: /*
402: * money:
403: * Add or subtract gold from the pack
404: */
405: void
406: money(int value)
407: {
408: register char floor;
409:
410: floor = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
411: purse += value;
412: mvaddch(hero.y, hero.x, floor);
413: chat(hero.y, hero.x) = floor;
414: if (value > 0)
415: {
416: if (!terse)
417: addmsg("you found ");
418: msg("%d gold pieces", value);
419: }
420: }
CVSweb