comparison rogue3/pack.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children d9e44e18eeec
comparison
equal deleted inserted replaced
-1:000000000000 0:527e2150eaf0
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;
26 struct object *obj, *op;
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)