Mercurial > hg > early-roguelike
comparison rogue5/pack.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Mon, 24 May 2010 20:10:59 +0000 |
parents | |
children | e5a15b09ce1d |
comparison
equal
deleted
inserted
replaced
32:2dcd75e6a736 | 33:f502bf60e6e4 |
---|---|
1 /* | |
2 * Routines to deal with the pack | |
3 * | |
4 * @(#)pack.c 4.40 (Berkeley) 02/05/99 | |
5 * | |
6 * Rogue: Exploring the Dungeons of Doom | |
7 * Copyright (C) 1980-1983, 1985, 1999 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 <string.h> | |
14 #include <curses.h> | |
15 #include <ctype.h> | |
16 #include "rogue.h" | |
17 | |
18 /* | |
19 * update_mdest: | |
20 * Called after picking up an object, before discarding it. | |
21 * If this was the object of something's desire, that monster will | |
22 * get mad and run at the hero | |
23 */ | |
24 update_mdest(obj) | |
25 register THING *obj; | |
26 { | |
27 register THING *mp; | |
28 | |
29 for (mp = mlist; mp != NULL; mp = next(mp)) | |
30 if (mp->t_dest == &obj->o_pos) | |
31 mp->t_dest = &hero; | |
32 } | |
33 | |
34 /* | |
35 * add_pack: | |
36 * Pick up an object and add it to the pack. If the argument is | |
37 * non-null use it as the linked_list pointer instead of gettting | |
38 * it off the ground. | |
39 */ | |
40 | |
41 void | |
42 add_pack(THING *obj, int silent) | |
43 { | |
44 THING *op, *lp; | |
45 int from_floor; | |
46 int discarded = 0; | |
47 | |
48 from_floor = FALSE; | |
49 if (obj == NULL) | |
50 { | |
51 if ((obj = find_obj(hero.y, hero.x)) == NULL) | |
52 return; | |
53 from_floor = TRUE; | |
54 } | |
55 | |
56 /* | |
57 * Check for and deal with scare monster scrolls | |
58 */ | |
59 if (obj->o_type == SCROLL && obj->o_which == S_SCARE) | |
60 if (obj->o_flags & ISFOUND) | |
61 { | |
62 detach(lvl_obj, obj); | |
63 mvaddch(hero.y, hero.x, floor_ch()); | |
64 chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR; | |
65 update_mdest(obj); | |
66 discarded = 1; | |
67 discard(obj); | |
68 msg("the scroll turns to dust as you pick it up"); | |
69 return; | |
70 } | |
71 | |
72 if (pack == NULL) | |
73 { | |
74 pack = obj; | |
75 obj->o_packch = pack_char(); | |
76 inpack++; | |
77 } | |
78 else | |
79 { | |
80 lp = NULL; | |
81 for (op = pack; op != NULL; op = next(op)) | |
82 { | |
83 if (op->o_type != obj->o_type) | |
84 lp = op; | |
85 else | |
86 { | |
87 while (op->o_type == obj->o_type && op->o_which != obj->o_which) | |
88 { | |
89 lp = op; | |
90 if (next(op) == NULL) | |
91 break; | |
92 else | |
93 op = next(op); | |
94 } | |
95 if (op->o_type == obj->o_type && op->o_which == obj->o_which) | |
96 { | |
97 if (ISMULT(op->o_type)) | |
98 { | |
99 if (!pack_room(from_floor, obj)) | |
100 return; | |
101 op->o_count++; | |
102 dump_it: | |
103 update_mdest(obj); | |
104 discard(obj); | |
105 obj = op; | |
106 discarded = 1; | |
107 lp = NULL; | |
108 goto out; | |
109 } | |
110 else if (obj->o_group) | |
111 { | |
112 lp = op; | |
113 while (op->o_type == obj->o_type | |
114 && op->o_which == obj->o_which | |
115 && op->o_group != obj->o_group) | |
116 { | |
117 lp = op; | |
118 if (next(op) == NULL) | |
119 break; | |
120 else | |
121 op = next(op); | |
122 } | |
123 if (op->o_type == obj->o_type | |
124 && op->o_which == obj->o_which | |
125 && op->o_group == obj->o_group) | |
126 { | |
127 op->o_count += obj->o_count; | |
128 inpack--; | |
129 if (!pack_room(from_floor, obj)) | |
130 return; | |
131 goto dump_it; | |
132 } | |
133 } | |
134 else | |
135 lp = op; | |
136 } | |
137 out: | |
138 break; | |
139 } | |
140 } | |
141 | |
142 if (lp != NULL) | |
143 { | |
144 if (!pack_room(from_floor, obj)) | |
145 return; | |
146 else | |
147 { | |
148 obj->o_packch = pack_char(); | |
149 next(obj) = next(lp); | |
150 prev(obj) = lp; | |
151 if (next(lp) != NULL) | |
152 prev(next(lp)) = obj; | |
153 next(lp) = obj; | |
154 } | |
155 } | |
156 } | |
157 | |
158 obj->o_flags |= ISFOUND; | |
159 | |
160 /* | |
161 * If this was the object of something's desire, that monster will | |
162 * get mad and run at the hero. | |
163 */ | |
164 if (!discarded) | |
165 update_mdest(obj); | |
166 | |
167 if (obj->o_type == AMULET) | |
168 amulet = TRUE; | |
169 /* | |
170 * Notify the user | |
171 */ | |
172 if (!silent) | |
173 { | |
174 if (!terse) | |
175 addmsg("you now have "); | |
176 msg("%s (%c)", inv_name(obj, !terse), obj->o_packch); | |
177 } | |
178 } | |
179 | |
180 /* | |
181 * pack_room: | |
182 * See if there's room in the pack. If not, print out an | |
183 * appropriate message | |
184 */ | |
185 int | |
186 pack_room(int from_floor, THING *obj) | |
187 { | |
188 if (++inpack > MAXPACK) | |
189 { | |
190 if (!terse) | |
191 addmsg("there's "); | |
192 addmsg("no room"); | |
193 if (!terse) | |
194 addmsg(" in your pack"); | |
195 endmsg(); | |
196 if (from_floor) | |
197 move_msg(obj); | |
198 inpack = MAXPACK; | |
199 return FALSE; | |
200 } | |
201 | |
202 if (from_floor) | |
203 { | |
204 detach(lvl_obj, obj); | |
205 mvaddch(hero.y, hero.x, floor_ch()); | |
206 chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR; | |
207 } | |
208 | |
209 return TRUE; | |
210 } | |
211 | |
212 /* | |
213 * leave_pack: | |
214 * take an item out of the pack | |
215 */ | |
216 THING * | |
217 leave_pack(THING *obj, int newobj, int all) | |
218 { | |
219 THING *nobj; | |
220 | |
221 inpack--; | |
222 nobj = obj; | |
223 if (obj->o_count > 1 && !all) | |
224 { | |
225 last_pick = obj; | |
226 obj->o_count--; | |
227 if (obj->o_group) | |
228 inpack++; | |
229 if (newobj) | |
230 { | |
231 nobj = new_item(); | |
232 *nobj = *obj; | |
233 next(nobj) = NULL; | |
234 prev(nobj) = NULL; | |
235 nobj->o_count = 1; | |
236 } | |
237 } | |
238 else | |
239 { | |
240 last_pick = NULL; | |
241 pack_used[obj->o_packch - 'a'] = FALSE; | |
242 detach(pack, obj); | |
243 } | |
244 return nobj; | |
245 } | |
246 | |
247 /* | |
248 * pack_char: | |
249 * Return the next unused pack character. | |
250 */ | |
251 int | |
252 pack_char(void) | |
253 { | |
254 int *bp; | |
255 | |
256 for (bp = pack_used; *bp; bp++) | |
257 continue; | |
258 *bp = TRUE; | |
259 return ((int)(bp - pack_used) + 'a'); | |
260 } | |
261 | |
262 /* | |
263 * inventory: | |
264 * List what is in the pack. Return TRUE if there is something of | |
265 * the given type. | |
266 */ | |
267 int | |
268 inventory(const THING *list, int type) | |
269 { | |
270 static char inv_temp[MAXSTR]; | |
271 | |
272 n_objs = 0; | |
273 for (; list != NULL; list = next(list)) | |
274 { | |
275 if (type && type != list->o_type && !(type == CALLABLE && | |
276 list->o_type != FOOD && list->o_type != AMULET) && | |
277 !(type == R_OR_S && (list->o_type == RING || list->o_type == STICK))) | |
278 continue; | |
279 n_objs++; | |
280 #ifdef MASTER | |
281 if (!list->o_packch) | |
282 strcpy(inv_temp, "%s"); | |
283 else | |
284 #endif | |
285 sprintf(inv_temp, "%c) %%s", list->o_packch); | |
286 msg_esc = TRUE; | |
287 if (add_line(inv_temp, inv_name(list, FALSE)) == ESCAPE) | |
288 { | |
289 msg_esc = FALSE; | |
290 msg(""); | |
291 return TRUE; | |
292 } | |
293 msg_esc = FALSE; | |
294 } | |
295 if (n_objs == 0) | |
296 { | |
297 if (terse) | |
298 msg(type == 0 ? "empty handed" : | |
299 "nothing appropriate"); | |
300 else | |
301 msg(type == 0 ? "you are empty handed" : | |
302 "you don't have anything appropriate"); | |
303 return FALSE; | |
304 } | |
305 end_line(); | |
306 return TRUE; | |
307 } | |
308 | |
309 /* | |
310 * pick_up: | |
311 * Add something to characters pack. | |
312 */ | |
313 | |
314 void | |
315 pick_up(int ch) | |
316 { | |
317 THING *obj; | |
318 | |
319 if (on(player, ISLEVIT)) | |
320 return; | |
321 | |
322 obj = find_obj(hero.y, hero.x); | |
323 if (move_on) | |
324 move_msg(obj); | |
325 else | |
326 switch (ch) | |
327 { | |
328 case GOLD: | |
329 if (obj == NULL) | |
330 return; | |
331 money(obj->o_goldval); | |
332 detach(lvl_obj, obj); | |
333 update_mdest(obj); | |
334 discard(obj); | |
335 proom->r_goldval = 0; | |
336 break; | |
337 default: | |
338 #ifdef MASTER | |
339 debug("Where did you pick a '%s' up???", unctrl(ch)); | |
340 #endif | |
341 case ARMOR: | |
342 case POTION: | |
343 case FOOD: | |
344 case WEAPON: | |
345 case SCROLL: | |
346 case AMULET: | |
347 case RING: | |
348 case STICK: | |
349 add_pack(NULL, FALSE); | |
350 break; | |
351 } | |
352 } | |
353 | |
354 /* | |
355 * move_msg: | |
356 * Print out the message if you are just moving onto an object | |
357 */ | |
358 | |
359 void | |
360 move_msg(const THING *obj) | |
361 { | |
362 if (!terse) | |
363 addmsg("you "); | |
364 msg("moved onto %s", inv_name(obj, TRUE)); | |
365 } | |
366 | |
367 /* | |
368 * picky_inven: | |
369 * Allow player to inventory a single item | |
370 */ | |
371 | |
372 void | |
373 picky_inven(void) | |
374 { | |
375 THING *obj; | |
376 int mch; | |
377 | |
378 if (pack == NULL) | |
379 msg("you aren't carrying anything"); | |
380 else if (next(pack) == NULL) | |
381 msg("a) %s", inv_name(pack, FALSE)); | |
382 else | |
383 { | |
384 msg(terse ? "item: " : "which item do you wish to inventory: "); | |
385 mpos = 0; | |
386 if ((mch = readchar()) == ESCAPE) | |
387 { | |
388 msg(""); | |
389 return; | |
390 } | |
391 for (obj = pack; obj != NULL; obj = next(obj)) | |