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) {
384 after = FALSE;
385 msg(""); /* clear top line */
386 return NULL; /* all done if abort */
387 }
388 /* ch has item to get from pack */
389 }
390 for (obj=pack,och='a';obj!=NULL;obj=next(obj),och=npch(och))
391 if (ch == och)
392 break;
393 if (obj == NULL) {
394 if (och == 'A')
395 och = 'z';
396 else
397 och -= 1;
398 msg("Please specify a letter between 'a' and '%c'",och);
399 continue;
400 }
401 else
402 return obj;
403 }
404 }
405
406 /*
407 * pack_char:
408 * Get the character of a particular item in the pack
409 */
410 char
411 pack_char(obj)
412 struct object *obj;
413 {
414 reg struct linked_list *item;
415 reg char c;
416
417 c = 'a';
418 for (item = pack; item != NULL; item = next(item))
419 if (OBJPTR(item) == obj)
420 return c;
421 else
422 c = npch(c);
423 return '%';
424 }
425
426 /*
427 * idenpack:
428 * Identify all the items in the pack
429 */
430 idenpack()
431 {
432 reg struct linked_list *pc;
433
434 for (pc = pack ; pc != NULL ; pc = next(pc))
435 whatis(pc);
436 }
437
438
439 /*
440 * del_pack:
441 * Take something out of the hero's pack
442 */
443 del_pack(what)
444 struct linked_list *what;
445 {
446 reg struct object *op;
447
448 op = OBJPTR(what);
449 cur_null(op); /* check for current stuff */
450 if (op->o_count > 1) {
451 op->o_count--;
452 }
453 else {
454 detach(pack,what);
455 discard(what);
456 }
457 updpack();
458 }
459
460 /*
461 * cur_null:
462 * This updates cur_weapon etc for dropping things
463 */
464 cur_null(op)
465 struct object *op;
466 {
467 if (op == cur_weapon)
468 cur_weapon = NULL;
469 else if (op == cur_armor)
470 cur_armor = NULL;
471 else if (op == cur_ring[LEFT])
472 cur_ring[LEFT] = NULL;
473 else if (op == cur_ring[RIGHT])
474 cur_ring[RIGHT] = NULL;
475 }