comparison arogue7/pack.c @ 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents
children b786053d2f37
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
1 /*
2 * pack.c - Routines to deal with the pack.
3 *
4 * Advanced Rogue
5 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
6 * All rights reserved.
7 *
8 * Based on "Rogue: Exploring the Dungeons of Doom"
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
10 * All rights reserved.
11 *
12 * See the file LICENSE.TXT for full copyright and licensing information.
13 */
14
15 #include "curses.h"
16 #include <ctype.h>
17 #include "rogue.h"
18 #ifdef PC7300
19 #include "menu.h"
20 #endif
21
22 /*
23 * Routines to deal with the pack
24 */
25
26 /*
27 * add_pack:
28 * Pick up an object and add it to the pack. If the argument is non-null
29 * use it as the linked_list pointer instead of gettting it off the ground.
30 */
31 bool
32 add_pack(item, silent, packret)
33 register struct linked_list *item, **packret;
34 bool silent;
35 {
36 register struct linked_list *ip, *lp, *ap;
37 register struct object *obj, *op;
38 register bool exact, from_floor;
39
40 if (packret != NULL)
41 *packret = NULL;
42
43 if (item == NULL)
44 {
45 from_floor = TRUE;
46 if ((item = find_obj(hero.y, hero.x)) == NULL)
47 return(FALSE);
48 }
49 else
50 from_floor = FALSE;
51 obj = OBJPTR(item);
52 /*
53 * If it is gold, just add its value to rogue's purse and get rid
54 * of it.
55 */
56 if (obj->o_type == GOLD) {
57 register struct linked_list *mitem;
58 register struct thing *tp;
59
60 if (!silent) {
61 if (!terse) addmsg("You found ");
62 msg("%d gold pieces.", obj->o_count);
63 }
64
65 /* First make sure no greedy monster is after this gold.
66 * If so, make the monster run after the rogue instead.
67 */
68 for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
69 tp = THINGPTR(mitem);
70 if (tp->t_dest == &obj->o_pos) tp->t_dest = &hero;
71 }
72
73 purse += obj->o_count;
74 if (from_floor) {
75 detach(lvl_obj, item);
76 if ((ap = find_obj(hero.y, hero.x)) == NULL)
77 mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
78 else
79 mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
80 }
81 o_discard(item);
82 return(TRUE);
83 }
84
85 /*
86 * see if he can carry any more weight
87 */
88 if (itemweight(obj) + pstats.s_pack > pstats.s_carry) {
89 msg("Too much for you to carry.");
90 return FALSE;
91 }
92 /*
93 * Link it into the pack. Search the pack for a object of similar type
94 * if there isn't one, stuff it at the beginning, if there is, look for one
95 * that is exactly the same and just increment the count if there is.
96 * it that. Food is always put at the beginning for ease of access, but
97 * is not ordered so that you can't tell good food from bad. First check
98 * to see if there is something in thr same group and if there is then
99 * increment the count.
100 */
101 if (obj->o_group)
102 {
103 for (ip = pack; ip != NULL; ip = next(ip))
104 {
105 op = OBJPTR(ip);
106 if (op->o_group == obj->o_group)
107 {
108 /*
109 * Put it in the pack and notify the user
110 */
111 op->o_count += obj->o_count;
112 if (from_floor)
113 {
114 detach(lvl_obj, item);
115 if ((ap = find_obj(hero.y, hero.x)) == NULL)
116 mvaddch(hero.y,hero.x,
117 (roomin(&hero)==NULL ? PASSAGE : FLOOR));
118 else
119 mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
120 }
121 o_discard(item);
122 item = ip;
123 goto picked_up;
124 }
125 }
126 }
127
128 /*
129 * Check for and deal with scare monster scrolls
130 */
131 if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
132 if (obj->o_flags & ISCURSED)
133 {
134 msg("The scroll turns to dust as you pick it up.");
135 detach(lvl_obj, item);
136 if ((ap = find_obj(hero.y, hero.x)) == NULL)
137 mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
138 else
139 mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
140 return(TRUE);
141 }
142
143 /*
144 * Search for an object of the same type
145 */
146 exact = FALSE;
147 for (ip = pack; ip != NULL; ip = next(ip))
148 {
149 op = OBJPTR(ip);
150 if (obj->o_type == op->o_type)
151 break;
152 }
153 if (ip == NULL)
154 {
155 /*
156 * Put it at the end of the pack since it is a new type
157 */
158 for (ip = pack; ip != NULL; ip = next(ip))
159 {
160 op = OBJPTR(ip);
161 if (op->o_type != FOOD)
162 break;
163 lp = ip;
164 }
165 }
166 else
167 {
168 /*
169 * Search for an object which is exactly the same
170 */
171 while (ip != NULL && op->o_type == obj->o_type)
172 {
173 if (op->o_which == obj->o_which)
174 {
175 exact = TRUE;
176 break;
177 }
178 lp = ip;
179 if ((ip = next(ip)) == NULL)
180 break;
181 op = OBJPTR(ip);
182 }
183 }
184 /*
185 * Check if there is room
186 */
187 if (ip == NULL || !exact || !ISMULT(obj->o_type)) {
188 if (inpack == MAXPACK-1) {
189 msg(terse ? "No room." : "You can't carry anything else.");
190 return(FALSE);
191 }
192 }
193 inpack++;
194 if (from_floor)
195 {
196 detach(lvl_obj, item);
197 if ((ap = find_obj(hero.y, hero.x)) == NULL)
198 mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
199 else
200 mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
201 }
202 if (ip == NULL)
203 {
204 /*
205 * Didn't find an exact match, just stick it here
206 */
207 if (pack == NULL)
208 pack = item;
209 else
210 {
211 lp->l_next = item;
212 item->l_prev = lp;
213 item->l_next = NULL;
214 }
215 }
216 else
217 {
218 /*
219 * If we found an exact match. If it is food,
220 * increase the count, otherwise put it with its clones.
221 */
222 if (exact && ISMULT(obj->o_type))
223 {
224 op->o_count += obj->o_count;
225 inpack--; /* adjust for previous addition */
226 o_discard(item);
227 item = ip;
228 goto picked_up;
229 }
230 if ((item->l_prev = prev(ip)) != NULL)
231 item->l_prev->l_next = item;
232 else
233 pack = item;
234 item->l_next = ip;
235 ip->l_prev = item;
236 }
237 picked_up:
238 /*
239 * Notify the user
240 */
241 obj = OBJPTR(item);
242 if (!silent)
243 {
244 if (!terse)
245 addmsg("You now have ");
246 msg("%s (%c)", inv_name(obj, !terse), pack_char(pack, obj));
247 }
248
249 /* Relics can do strange things when you pick them up */
250 if (obj->o_type == RELIC) {
251 switch (obj->o_which) {
252 /* the ankh of Heil gives you prayers */
253 case HEIL_ANKH:
254 msg("The ankh welds itself into your hand.");
255 if (player.t_ctype != C_CLERIC && player.t_ctype != C_PALADIN)
256 fuse(prayer_recovery, 0, SPELLTIME, AFTER);
257
258 /* A cloak must be worn. */
259 when EMORI_CLOAK:
260 if (cur_armor != NULL || cur_misc[WEAR_CLOAK]) {
261 msg("The cloak insists you remove your current garments.");
262 if (!dropcheck(cur_armor != NULL ? cur_armor
263 : cur_misc[WEAR_CLOAK])) {
264 pstats.s_hpt = -1;
265 msg("The cloak constricts around you.");
266 msg("It draws your life force from you!!! -- More --");
267 wait_for(' ');
268 death(D_RELIC);
269 }
270 }
271 if (obj->o_charges < 0) /* should never happen, but.... */
272 obj->o_charges = 0;
273 if (obj->o_charges == 0)
274 fuse(cloak_charge, obj, CLOAK_TIME, AFTER);
275
276 /* The amulet must be worn. */
277 when STONEBONES_AMULET:
278 case YENDOR_AMULET:
279 if (cur_misc[WEAR_JEWEL] ||
280 cur_relic[STONEBONES_AMULET] ||
281 cur_relic[YENDOR_AMULET]) {
282 msg("You have an urge to remove your current amulet.");
283 }
284 if((cur_misc[WEAR_JEWEL] && !dropcheck(cur_misc[WEAR_JEWEL])) ||
285 cur_relic[STONEBONES_AMULET] ||
286 cur_relic[YENDOR_AMULET]) {
287 pstats.s_hpt = -1;
288 msg("The %s begins pulsing.", inv_name(obj, TRUE));
289 msg("It fades away.... -- More --");
290 wait_for(' ');
291 death(D_RELIC);
292 }
293 msg("The %s welds itself into your chest.",inv_name(obj,TRUE));
294
295 /* The eye must be inserted in eye socket */
296 when EYE_VECNA:
297 msg("The eye forces you to jam it into your eye socket!");
298 pstats.s_hpt -= 75;
299 if (pstats.s_hpt < 0) {
300 msg ("The pain is too much for you! -- More --");
301 wait_for(' ');
302 death(D_RELIC);
303 }
304 waste_time();
305 msg("The excrutiating pain slowly turns into a dull throb.");
306
307 when QUILL_NAGROM:
308 fuse(quill_charge,0,player.t_ctype==C_MAGICIAN ? 4 : 8,AFTER);
309
310 /* Weapons will insist on being wielded. */
311 when MUSTY_DAGGER:
312 case HRUGGEK_MSTAR:
313 case YEENOGHU_FLAIL:
314 case AXE_AKLAD:
315 /* For the daggers start a fuse to change player to a thief. */
316 /* and set a daemon to eat gold. */
317 if (obj->o_which == MUSTY_DAGGER) {
318 fuse(changeclass, C_THIEF, roll(20, 20), AFTER);
319 if (purse > 0)
320 msg("Your purse feels lighter");
321 else
322 purse = 1; /* fudge to get right msg from eat_gold() */
323 eat_gold(obj);
324 daemon(eat_gold, obj, AFTER);
325 }
326 /* For the axe start a fuse to change player to a fighter. */
327 if (obj->o_which == AXE_AKLAD)
328 fuse(changeclass, C_FIGHTER, roll(20, 20), AFTER);
329 if (cur_weapon != NULL) {
330 msg("The artifact insists you release your current weapon.");
331 if (!dropcheck(cur_weapon)) {
332 pstats.s_hpt = -1;
333 msg("The artifact forces your weapon into your heart.");
334 msg("It hums with satisfaction. -- More --");
335 wait_for(' ');
336 death(D_RELIC);
337 }
338 }
339 cur_weapon = obj;
340
341 when SURTUR_RING:
342 msg("The ring forces itself through your nose!");
343 pstats.s_hpt -= 22;
344 if (pstats.s_hpt < 0) {
345 msg ("The pain is too much for you! -- More --");
346 wait_for(' ');
347 death(D_RELIC);
348 }
349 waste_time();
350 turn_on(player, NOFIRE);
351 msg("The pain slowly subsides.");
352 otherwise:
353 break;
354 }
355 cur_relic[obj->o_which]++; /* Note that we have it */
356 }
357
358 updpack(FALSE, &player);
359 if (packret != NULL)
360 *packret = item;
361 return(TRUE);
362 }
363
364 #ifdef PC7300
365 static menu_t Display; /* The menu structure */
366 static mitem_t Dispitems[MAXPACK+1]; /* Info for each line */
367 static char Displines[MAXPACK+1][LINELEN+1]; /* The lines themselves */
368 #endif
369
370 /*
371 * inventory:
372 * list what is in the pack
373 */
374 inventory(list, type)