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 }