Mercurial > hg > early-roguelike
comparison srogue/pack.c @ 36:2128c7dc8a40
Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 25 Nov 2010 12:21:41 +0000 |
parents | |
children | 7f5f5f1ba09c |
comparison
equal
deleted
inserted
replaced
35:05018c63a721 | 36:2128c7dc8a40 |
---|---|
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 add_pack(item, silent) | |
28 struct linked_list *item; | |
29 bool silent; | |
30 { | |
31 reg struct linked_list *ip, *lp; | |
32 reg struct object *obj, *op; | |
33 bool from_floor; | |
34 char delchar; | |
35 | |
36 if (player.t_room == NULL) | |
37 delchar = PASSAGE; | |
38 else | |
39 delchar = FLOOR; | |
40 if (item == NULL) { | |
41 from_floor = TRUE; | |
42 if ((item = find_obj(hero.y, hero.x)) == NULL) { | |
43 mpos = 0; | |
44 msg("That object must have been an illusion."); | |
45 mvaddch(hero.y, hero.x, delchar); | |
46 return FALSE; | |
47 } | |
48 /* | |
49 * Check for scare monster scrolls | |
50 */ | |
51 obj = OBJPTR(item); | |
52 if (obj->o_type == SCROLL && obj->o_which == S_SCARE) { | |
53 if (o_on(obj,ISFOUND)) { | |
54 msg("The scroll turns to dust as you pick it up."); | |
55 detach(lvl_obj, item); | |
56 discard(item); | |
57 mvaddch(hero.y, hero.x, delchar); | |
58 return FALSE; | |
59 } | |
60 } | |
61 } | |
62 else | |
63 from_floor = FALSE; | |
64 obj = OBJPTR(item); | |
65 /* | |
66 * See if this guy can carry any more weight | |
67 */ | |
68 if (itemweight(obj) + him->s_pack > him->s_carry) { | |
69 msg("You can't carry that %s.", obj->o_typname); | |
70 return FALSE; | |
71 } | |
72 /* | |
73 * Check if there is room | |
74 */ | |
75 if (packvol + obj->o_vol > V_PACK) { | |
76 msg("That %s won't fit in your pack.", obj->o_typname); | |
77 return FALSE; | |
78 } | |
79 if (from_floor) { | |
80 detach(lvl_obj, item); | |
81 mvaddch(hero.y, hero.x, delchar); | |
82 } | |
83 item->l_prev = NULL; | |
84 item->l_next = NULL; | |
85 setoflg(obj, ISFOUND); | |
86 /* | |
87 * start looking thru pack to find the start of items | |
88 * with the same type. | |
89 */ | |
90 lp = pack; | |
91 for (ip = pack; ip != NULL; ip = next(ip)) { | |
92 op = OBJPTR(ip); | |
93 /* | |
94 * If we find a matching type then quit. | |
95 */ | |
96 if (op->o_type == obj->o_type) | |
97 break; | |
98 if (next(ip) != NULL) | |
99 lp = next(lp); /* update "previous" entry */ | |
100 } | |
101 /* | |
102 * If the pack was empty, just stick the item in it. | |
103 */ | |
104 if (pack == NULL) { | |
105 pack = item; | |
106 item->l_prev = NULL; | |
107 } | |
108 /* | |
109 * If we looked thru the pack, but could not find an | |
110 * item of the same type, then stick it at the end, | |
111 * unless it was food, then put it in front. | |
112 */ | |
113 else if (ip == NULL) { | |
114 if (obj->o_type == FOOD) { /* insert food at front */ | |
115 item->l_next = pack; | |
116 pack->l_prev = item; | |
117 pack = item; | |
118 item->l_prev = NULL; | |
119 } | |
120 else { /* insert other stuff at back */ | |
121 lp->l_next = item; | |
122 item->l_prev = lp; | |
123 } | |
124 } | |
125 /* | |
126 * Here, we found at least one item of the same type. | |
127 * Look thru these items to see if there is one of the | |
128 * same group. If so, increment the count and throw the | |
129 * new item away. If not, stick it at the end of the | |
130 * items with the same type. Also keep all similar | |
131 * objects near each other, like all identify scrolls, etc. | |
132 */ | |
133 else { | |
134 struct linked_list **save; | |
135 | |
136 while (ip != NULL && op->o_type == obj->o_type) { | |
137 if (op->o_group == obj->o_group) { | |
138 if (op->o_flags == obj->o_flags) { | |
139 op->o_count++; | |
140 discard(item); | |
141 item = ip; | |
142 goto picked_up; | |
143 } | |
144 else { | |
145 goto around; | |
146 } | |
147 } | |
148 if (op->o_which == obj->o_which) { | |
149 if (obj->o_type == FOOD) | |
150 ip = next(ip); | |
151 break; | |
152 } | |
153 around: | |
154 ip = next(ip); | |
155 if (ip != NULL) { | |
156 op = OBJPTR(ip); | |
157 lp = next(lp); | |
158 } | |
159 } | |
160 /* | |
161 * If inserting into last of group at end of pack, | |
162 * just tack on the end. | |
163 */ | |
164 if (ip == NULL) { | |
165 lp->l_next = item; | |
166 item->l_prev = lp; | |
167 } | |
168 /* | |
169 * Insert into the last of a group of objects | |
170 * not at the end of the pack. | |
171 */ | |
172 else { | |
173 save = &((ip->l_prev)->l_next); | |
174 item->l_next = ip; | |
175 item->l_prev = ip->l_prev; | |
176 ip->l_prev = item; | |
177 *save = item; | |
178 } | |
179 } | |
180 picked_up: | |
181 obj = OBJPTR(item); | |
182 if (!silent) | |
183 msg("%s (%c)",inv_name(obj,FALSE),pack_char(obj)); | |
184 if (obj->o_type == AMULET) | |
185 amulet = TRUE; | |
186 updpack(); /* new pack weight & volume */ | |
187 return TRUE; | |
188 } | |
189 | |
190 /* | |
191 * inventory: | |
192 * Show what items are in a specific list | |
193 */ | |
194 inventory(list, type) | |
195 struct linked_list *list; | |
196 int type; | |
197 { | |
198 reg struct linked_list *pc; | |
199 reg struct object *obj; | |
200 reg char ch; | |
201 reg int cnt; | |
202 | |
203 if (list == NULL) { /* empty list */ | |
204 msg(type == 0 ? "Empty handed." : "Nothing appropriate."); | |
205 return FALSE; | |
206 } | |
207 else if (next(list) == NULL) { /* only 1 item in list */ | |
208 obj = OBJPTR(list); | |
209 msg("a) %s", inv_name(obj, FALSE)); | |
210 return TRUE; | |
211 } | |
212 cnt = 0; | |
213 wclear(hw); | |
214 for (ch = 'a', pc = list; pc != NULL; pc = next(pc), ch = npch(ch)) { | |
215 obj = OBJPTR(pc); | |
216 wprintw(hw,"%c) %s\n\r",ch,inv_name(obj, FALSE)); | |
217 if (++cnt > LINES - 2 && next(pc) != NULL) { | |
218 dbotline(hw, morestr); | |
219 cnt = 0; | |
220 wclear(hw); | |
221 } | |
222 } | |
223 dbotline(hw,spacemsg); | |
224 restscr(cw); | |
225 return TRUE; | |
226 } | |
227 | |
228 /* | |
229 * pick_up: | |
230 * Add something to characters pack. | |
231 */ | |
232 pick_up(ch) | |
233 char ch; | |
234 { | |
235 nochange = FALSE; | |
236 switch(ch) { | |
237 case GOLD: | |
238 money(); | |
239 when ARMOR: | |
240 case POTION: | |
241 case FOOD: | |
242 case WEAPON: | |
243 case SCROLL: | |
244 case AMULET: | |
245 case RING: | |
246 case STICK: | |
247 add_pack(NULL, FALSE); | |
248 otherwise: | |
249 msg("That item is ethereal !!!"); | |
250 } | |
251 } | |
252 | |
253 /* | |
254 * picky_inven: | |
255 * Allow player to inventory a single item | |
256 */ | |
257 picky_inven() | |
258 { | |
259 reg struct linked_list *item; | |
260 reg char ch, mch; | |
261 | |
262 if (pack == NULL) | |
263 msg("You aren't carrying anything."); | |
264 else if (next(pack) == NULL) | |
265 msg("a) %s", inv_name(OBJPTR(pack), FALSE)); | |
266 else { | |
267 msg("Item: "); | |
268 mpos = 0; | |
269 if ((mch = readchar()) == ESCAPE) { | |
270 msg(""); | |
271 return; | |
272 } | |
273 for (ch='a',item=pack; item != NULL; item=next(item),ch=npch(ch)) | |
274 if (ch == mch) { | |
275 msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE)); | |
276 return; | |
277 } | |
278 if (ch == 'A') | |
279 ch = 'z'; | |
280 else | |
281 ch -= 1; | |
282 msg("Range is 'a' to '%c'", ch); | |
283 } | |
284 } | |
285 | |
286 /* | |
287 * get_item: | |
288 * pick something out of a pack for a purpose | |
289 */ | |
290 struct linked_list * | |
291 get_item(purpose, type) | |
292 char *purpose; | |
293 int type; | |
294 { | |
295 reg struct linked_list *obj, *pit, *savepit; | |
296 struct object *pob; | |
297 int ch, och, anr, cnt; | |
298 | |
299 if (pack == NULL) { | |
300 msg("You aren't carrying anything."); | |
301 return NULL; | |
302 } | |
303 if (type != WEAPON && (type != 0 || next(pack) == NULL)) { | |
304 /* | |
305 * see if we have any of the type requested | |
306 */ | |
307 pit = pack; | |
308 anr = 0; | |
309 for (ch = 'a'; pit != NULL; pit = next(pit), ch = npch(ch)) { | |
310 pob = OBJPTR(pit); | |
311 if (type == pob->o_type || type == 0) { | |
312 ++anr; | |
313 savepit = pit; /* save in case of only 1 */ | |
314 } | |
315 } | |
316 if (anr == 0) { | |
317 msg("Nothing to %s",purpose); | |
318 after = FALSE; | |
319 return NULL; | |
320 } | |
321 else if (anr == 1) { /* only found one of 'em */ | |
322 do { | |
323 struct object *opb; | |
324 | |
325 opb = OBJPTR(savepit); | |
326 msg("%s what (* for the item)?",purpose); | |
327 och = readchar(); | |
328 if (och == '*') { | |
329 mpos = 0; | |
330 msg("%c) %s",pack_char(opb),inv_name(opb,FALSE)); | |
331 continue; | |
332 } | |
333 if (och == ESCAPE) { | |
334 msg(""); | |
335 after = FALSE; | |
336 return NULL; | |
337 } | |
338 if (isalpha(och) && och != pack_char(opb)) { | |
339 mpos = 0; | |
340 msg("You can't %s that !!", purpose); | |
341 after = FALSE; | |
342 return NULL; | |
343 } | |
344 } while(!isalpha(och)); | |
345 mpos = 0; | |
346 return savepit; /* return this item */ | |
347 } | |
348 } | |
349 for (;;) { | |
350 msg("%s what? (* for list): ",purpose); | |
351 ch = readchar(); | |
352 mpos = 0; | |
353 if (ch == ESCAPE) { /* abort if escape hit */ | |
354 after = FALSE; | |
355 msg(""); /* clear display */ | |
356 return NULL; | |
357 } | |
358 if (ch == '*') { | |
359 wclear(hw); | |
360 pit = pack; /* point to pack */ | |
361 cnt = 0; | |
362 for (ch='a'; pit != NULL; pit=next(pit), ch=npch(ch)) { | |
363 pob = OBJPTR(pit); | |
364 if (type == 0 || type == pob->o_type) { | |
365 wprintw(hw,"%c) %s\n\r",ch,inv_name(pob,FALSE)); | |
366 if (++cnt > LINES - 2 && next(pit) != NULL) { | |
367 cnt = 0; | |
368 dbotline(hw, morestr); | |
369 wclear(hw); | |
370 } | |
371 } | |
372 } | |
373 wmove(hw, LINES - 1,0); | |
374 wprintw(hw,"%s what? ",purpose); | |
375 draw(hw); /* write screen */ | |
376 anr = FALSE; | |
377 do { | |
378 ch = readchar(); | |
379 if (isalpha(ch) || ch == ESCAPE) | |
380 anr = TRUE; | |
381 } while(!anr); /* do till we got it right */ | |
382 restscr(cw); /* redraw orig screen */ | |
383 if (ch == ESCAPE) { | |