Branch data Line data Source code
1 : : /* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
2 : : /* inv.c */
3 : : /* functions having to do with player item inventory */
4 : :
5 : : #ifdef MSDOS_SUPPORTED_ANTIQUE
6 : : # include "curses.h"
7 : : #else
8 : : # ifdef AMIGA
9 : : # include <curses210.h>
10 : : # elif defined(USE_OPCURSES)
11 : : # include "../opcurses/curses.h"
12 : : # else
13 : : # include <curses.h>
14 : : # endif
15 : : #endif
16 : :
17 : : #include "glob.h"
18 : :
19 : : static void inv_display_munge(void);
20 : : static void inv_display_refresh(void);
21 : :
22 : :
23 : : /* drops money, heh heh */
24 : 0 : void drop_money(void)
25 : : {
26 : : pob money;
27 : :
28 : 0 : money = detach_money(0);
29 [ # # ]: 0 : if (money != NULL) {
30 [ # # ]: 0 : if (Current_Environment == E_CITY) {
31 : 0 : print1("As soon as the money leaves your hand,");
32 : 0 : print2("a horde of scrofulous beggars snatch it up and are gone!");
33 : 0 : free( money );
34 : : }
35 : 0 : else drop_at(Player.x,Player.y,money);
36 : : }
37 : 0 : else setgamestatus(SKIP_MONSTERS);
38 : 0 : }
39 : :
40 : :
41 : : /* returns some money from player back into "money" item.
42 : : for giving and dropping money */
43 : 0 : pob detach_money(long howmuch)
44 : : /* if howmuch == 0, ask the player. otherwise, just get howmuch. */
45 : : {
46 : : long c;
47 : 0 : pob cash=NULL;
48 [ # # ]: 0 : if ( howmuch == 0 )
49 : 0 : c = get_money(Player.cash);
50 : : else
51 : 0 : c = howmuch;
52 [ # # ]: 0 : if (c != ABORT) {
53 : 0 : Player.cash -= c;
54 : 0 : cash = ((pob) checkmalloc(sizeof(objtype)));
55 : 0 : make_cash(cash,difficulty());
56 : 0 : cash->basevalue = c;
57 : : }
58 : 0 : return(cash);
59 : : }
60 : :
61 : :
62 : : /* gets a legal amount of money or ABORT */
63 : 0 : long get_money(long limit)
64 : : {
65 : : long c;
66 : 0 : c = parsenum("How much money? ");
67 [ # # ]: 0 : if (c > limit) {
68 : 0 : print3("Forget it, buddy.");
69 : 0 : return(ABORT);
70 : : }
71 : 0 : else return(c);
72 : : }
73 : :
74 : :
75 : :
76 : : /* pick up from some location x,y */
77 : : /* Lift entire itemlist off ground, pass it to inventory control, which
78 : : may drop things back onto the now null ground */
79 : 0 : void pickup_at (int x, int y)
80 : : {
81 : 0 : char response = 0;
82 : :
83 : : pol ol;
84 : : pol temp;
85 : :
86 : 0 : resetgamestatus(FAST_MOVE);
87 : :
88 : 0 : ol = Level->site[x][y].things;
89 : 0 : Level->site[x][y].things = 0;
90 : :
91 [ # # ]: 0 : while (ol != 0)
92 : : {
93 [ # # ]: 0 : if(response != 'q') {
94 : 0 : clearmsg1();
95 : 0 : response = cinema_ynq(strjoin("Pick up: ", itemid(ol->thing)));
96 : : }
97 : :
98 [ # # ]: 0 : if (response == 'y')
99 : 0 : gain_item(ol->thing);
100 : : else
101 : 0 : drop_at(x,y,ol->thing);
102 : :
103 : 0 : temp = ol;
104 : 0 : ol = ol->next;
105 : 0 : temp->next = 0;
106 : 0 : temp->thing = 0;
107 : 0 : free(temp);
108 : : }
109 : 0 : }
110 : :
111 : : /* WDT -- convert from a char (keypress) to an item index in
112 : : * player inventory */
113 : : /* Item identifiers, in this case the letters of the alphabet minus
114 : : * any letters already used for commands. Yes, there are more here
115 : : * than could be needed, but I don't want to short myself for later.
116 : : */
117 : : signed char inventory_keymap[] = "-abcfghimnoqruvwyz";
118 : 12 : int key_to_index(signed char key)
119 : : {
120 : : int i;
121 : : assert( MAXITEMS>0 ); /* must have room for an item, or this loop will
122 : : * die! */
123 : :
124 [ + - ]: 58 : for (i=0; i<MAXITEMS; i++) {
125 [ + + ]: 58 : if (key == inventory_keymap[i])
126 : 12 : return (signed char)i;
127 : : }
128 : 0 : return O_UP_IN_AIR;
129 : : }
130 : :
131 : 218 : signed char index_to_key(signed int index)
132 : : {
133 [ + - ]: 218 : if ( index < MAXITEMS )
134 : 218 : return inventory_keymap[index];
135 : 0 : else return '-';
136 : : }
137 : :
138 : :
139 : : /* criteria for being able to put some item in some slot */
140 : : /* WDT -- why on earth does the 'slottable' function print stuff???? */
141 : 0 : int aux_slottable(pob o, int slot)
142 : : {
143 : 0 : int ok = TRUE;
144 [ # # ]: 0 : if (o == NULL) ok = FALSE;
145 [ # # ]: 0 : else if (slot == O_ARMOR) {
146 [ # # ]: 0 : if (o->objchar != ARMOR) {
147 : 0 : ok = FALSE;
148 : : }
149 : : }
150 [ # # ]: 0 : else if (slot == O_SHIELD) {
151 [ # # ]: 0 : if (o->objchar != SHIELD) {
152 : 0 : ok = FALSE;
153 : : }
154 : : }
155 [ # # ]: 0 : else if (slot == O_BOOTS) {
156 [ # # ]: 0 : if (o->objchar != BOOTS) {
157 : 0 : ok = FALSE;
158 : : }
159 : : }
160 [ # # ]: 0 : else if (slot == O_CLOAK) {
161 [ # # ]: 0 : if (o->objchar != CLOAK) {
162 : 0 : ok = FALSE;
163 : : }
164 : : }
165 [ # # ]: 0 : else if (slot >= O_RING1) {
166 [ # # ]: 0 : if (o->objchar != RING) {
167 : 0 : ok = FALSE;
168 : : }
169 : : }
170 : 0 : return(ok);
171 : : }
172 : :
173 : : /* put all of o on objlist at x,y on Level->depth */
174 : : /* Not necessarily dropped by character; just dropped... */
175 : 1 : void drop_at(int x, int y, pob o)
176 : : {
177 : : pol tmp;
178 : : pob cpy;
179 : :
180 [ + - ]: 1 : if (Current_Environment != E_COUNTRYSIDE) {
181 [ + - ][ + - ]: 1 : if ((Level->site[x][y].locchar != VOID_CHAR) &&
182 : 1 : (Level->site[x][y].locchar != ABYSS)) {
183 : 1 : cpy = copy_obj( o );
184 : 1 : tmp = ((pol) checkmalloc(sizeof(oltype)));
185 : 1 : cpy->used = FALSE;
186 : 1 : tmp->thing = cpy;
187 : 1 : tmp->next = Level->site[x][y].things;
188 : 1 : Level->site[x][y].things = tmp;
189 : : }
190 [ # # ]: 0 : else if (Level->site[x][y].p_locf == L_VOID_STATION)
191 : 0 : setgamestatus(PREPARED_VOID);
192 : : }
193 : 1 : }
194 : :
195 : : /* put n of o on objlist at x,y on Level->depth */
196 : 0 : void p_drop_at(int x, int y, int n, pob o)
197 : : {
198 : : pol tmp;
199 [ # # ]: 0 : if (Current_Environment != E_COUNTRYSIDE) {
200 [ # # ][ # # ]: 0 : if ((Level->site[x][y].locchar != VOID_CHAR) &&
201 : 0 : (Level->site[x][y].locchar != ABYSS)) {
202 : 0 : tmp = ((pol) checkmalloc(sizeof(oltype)));
203 : 0 : tmp->thing = copy_obj( o );
204 : 0 : tmp->thing->used = FALSE;
205 : 0 : tmp->thing->number = n;
206 : 0 : print2("Dropped ");
207 : 0 : nprint2(itemid(tmp->thing));
208 : 0 : morewait();
209 : 0 : tmp->next = Level->site[x][y].things;
210 : 0 : Level->site[x][y].things = tmp;
211 : : }
212 [ # # ]: 0 : else if (Level->site[x][y].p_locf == L_VOID_STATION)
213 : 0 : setgamestatus(PREPARED_VOID);
214 : : }
215 : 0 : }
216 : :
217 : :
218 : : /* returns a string for identified items */
219 : 156 : char *itemid(pob obj)
220 : : {
221 : : char tstr[80];
222 [ - + ]: 156 : if (obj->objchar==CASH){
223 : 0 : strcpy(Str4,obj->truename);
224 : 0 : return(Str4);
225 : : }
226 : : else {
227 [ - + ]: 156 : if (Objects[obj->id].known > obj->known)
228 : 0 : obj->known = Objects[obj->id].known;
229 : :
230 : 156 : setnumstr(obj,tstr);
231 : 156 : strcpy(Str4,tstr);
232 [ + + ]: 156 : if (obj->known == 0)
233 : 54 : strcat(Str4,obj->objstr);
234 [ + + ]: 102 : else if (obj->known == 1) {
235 [ + - ][ + - ]: 13 : if (obj->id == OB_YENDOR || obj->id == OB_KARNAK ||
[ - + ]
236 : 13 : obj->id == OB_STARGEM )
237 : 0 : strcat(Str4, "the ");
238 : 13 : strcat(Str4,obj->truename);
239 : : }
240 : : else {
241 [ + - ][ + - ]: 89 : if (obj->id == OB_YENDOR || obj->id == OB_KARNAK ||
[ - + ]
242 : 89 : obj->id == OB_STARGEM )
243 : 0 : strcat(Str4, "the ");
244 [ - + ][ # # ]: 89 : if (obj->usef == I_NOTHING && Objects[obj->id].usef != I_NOTHING)
245 : 0 : strcat(Str4, "disenchanted ");
246 [ + + ]: 89 : if (obj->blessing < 0) {
247 : 7 : strcat(Str4, "cursed ");
248 : 7 : strcat(Str4, obj->cursestr);
249 : : }
250 [ + + ]: 82 : else if (obj->blessing > 0) {
251 : 6 : strcat(Str4, "blessed ");
252 : 6 : strcat(Str4, obj->truename);
253 : : }
254 : 76 : else strcat(Str4,obj->truename);
255 [ - + ]: 89 : if (obj->number > 1) strcat(Str4,"s");
256 [ + + + ]: 89 : switch (obj->objchar) {
257 : : case STICK:
258 : 3 : setchargestr(obj,tstr);
259 : 3 : strcat(Str4,tstr);
260 : 3 : break;
261 : : case MISSILEWEAPON:
262 : : case ARMOR:
263 : : case RING:
264 : : case SHIELD:
265 : : case WEAPON:
266 : 51 : setplustr(obj,tstr);
267 : 51 : strcat(Str4, tstr);
268 : 51 : break;
269 : 35 : default: strcat(Str4,""); break;
270 : : }
271 : : }
272 : 156 : return(Str4);
273 : : }
274 : : }
275 : :
276 : 42 : char *cashstr(void)
277 : : {
278 [ + - ]: 42 : if (difficulty() < 3) return("copper pieces");
279 [ # # ]: 0 : else if (difficulty() < 5) return("silver pieces");
280 [ # # ]: 0 : else if (difficulty() < 7) return("gold pieces");
281 [ # # ]: 0 : else if (difficulty() < 8) return("semiprecious gems");
282 [ # # ]: 0 : else if (difficulty() < 9) return("mithril pieces");
283 [ # # ]: 0 : else if (difficulty() < 10) return("precious gems");
284 : 0 : else return("orichalc pieces");
285 : : }
286 : :
287 : : /* return an object's plus as a string */
288 : 51 : void setplustr(pob obj, char *pstr)
289 : : {
290 : 51 : pstr[0] = ' ';
291 [ + + ]: 51 : pstr[1] = (obj->plus < 0 ? '-' : '+' );
292 [ + - ][ + - ]: 51 : if (abs(obj->plus) < 10) {
293 : 51 : pstr[2] = '0' + abs(obj->plus);
294 : 51 : pstr[3] = 0;
295 : : }
296 : : else {
297 [ # # ]: 0 : pstr[2] = '0' + abs(obj->plus / 10);
298 : 0 : pstr[3] = '0' + abs(obj->plus % 10);
299 : 0 : pstr[4] = 0;
300 : : }
301 : 51 : }
302 : :
303 : : /* return an object's number as a string */
304 : 156 : void setnumstr(pob obj, char *nstr)
305 : : {
306 [ + + ]: 156 : if (obj->number < 2)
307 : 137 : nstr[0] = 0;
308 [ + - ]: 19 : else if (obj->number < 10) {
309 : 19 : nstr[0] = '0' + obj->number;
310 : 19 : nstr[1] = 'x';
311 : 19 : nstr[2] = ' ';
312 : 19 : nstr[3] = 0;
313 : : }
314 [ # # ]: 0 : else if (obj->number < 41) {
315 : 0 : nstr[0] = '0' + ((int)(obj->number / 10));
316 : 0 : nstr[1] = '0' + (obj->number % 10);
317 : 0 : nstr[2] = 'x';
318 : 0 : nstr[3] = ' ';
319 : 0 : nstr[4] = 0;
320 : : }
321 : 0 : else strcpy(nstr,"lots of ");
322 : 156 : }
323 : :
324 : :
325 : : /* return object with charges */
326 : 3 : void setchargestr(pob obj, char *cstr)
327 : : {
328 : 3 : cstr[0] = ' ';
329 : 3 : cstr[1] = '[';
330 [ - + ]: 3 : if (obj->charge < 0) {
331 : 0 : cstr[2]='d';
332 : 0 : cstr[3]='e';
333 : 0 : cstr[4]='a';
334 : 0 : cstr[5]='d';
335 : 0 : cstr[6]=']';
336 : 0 : cstr[7]=0;
337 : : }
338 [ - + ]: 3 : else if (obj->charge < 10) {
339 : 0 : cstr[2] = '0' + obj->charge;
340 : 0 : cstr[3] = ']';
341 : 0 : cstr[4] = 0;
342 : : }
343 : : else {
344 : 3 : cstr[2] = '0' + ((int)(obj->charge / 10));
345 : 3 : cstr[3] = '0' + (obj->charge % 10);
346 : 3 : cstr[4] = ']';
347 : 3 : cstr[5] = 0;
348 : : }
349 : 3 : }
350 : :
351 : :
352 : 0 : void give_money(struct monster *m)
353 : : {
354 : : pob cash;
355 : :
356 : 0 : cash = detach_money(0);
357 [ # # ]: 0 : if (cash == NULL)
358 : 0 : setgamestatus(SKIP_MONSTERS);
359 : 0 : else givemonster(m,cash);
360 : 0 : }
361 : :
362 : :
363 : 0 : void lawbringer_gets_gem(pmt m, pob o)
364 : : {
365 : 0 : clearmsg();
366 : 0 : print1("The LawBringer accepts the gem reverently.");
367 : 0 : print2("He raises it above his head, where it bursts into lambent flame!");
368 : 0 : morewait();
369 : 0 : print1("You are bathed in a shimmering golden light.");
370 : 0 : print2("You feel embedded in an infinite matrix of ordered energy.");
371 : 0 : morewait();
372 [ # # ]: 0 : if (Imprisonment > 0)
373 : 0 : Imprisonment = 0;
374 [ # # ]: 0 : if (Player.rank[ORDER] == -1) {
375 : 0 : print2("You have been forgiven. You feel like a Paladin....");
376 : 0 : Player.rank[ORDER] = 1;
377 : : }
378 : 0 : Player.alignment += 200;
379 : 0 : Player.pow = Player.maxpow = Player.pow * 2;
380 : 0 : gain_experience(2000);
381 : 0 : setgamestatus(GAVE_STARGEM);
382 : : /* WDT HACK!!! Where else would this ever get freed?? */
383 : 0 : free_obj(o, TRUE);
384 : 0 : }
385 : :
386 : 0 : void givemonster(pmt m, pob o)
387 : : {
388 : : /* special case -- give gem to LawBringer */
389 [ # # ][ # # ]: 0 : if ((m->id == LAWBRINGER) && (o->id == OB_STARGEM))
390 : 0 : lawbringer_gets_gem(m,o);
391 : : else {
392 [ # # ]: 0 : if (m->uniqueness == COMMON) {
393 : 0 : strcpy(Str3,"The ");
394 : 0 : strcat(Str3,m->monstring);
395 : : }
396 : 0 : else strcpy(Str3,m->monstring);
397 : :
398 [ # # ][ # # ]: 0 : if (m_statusp(m,GREEDY) || m_statusp(m,NEEDY)) {
399 : 0 : m_pickup(m,o);
400 : 0 : strcat(Str3," takes your gift");
401 : 0 : print1(Str3);
402 : 0 : Player.alignment++;
403 [ # # ][ # # ]: 0 : if (m_statusp(m,GREEDY) && (true_item_value(o) < (long) m->level*100))
404 : 0 : nprint1("...but does not appear satisfied.");
405 [ # # # # ]: 0 : else if (m_statusp(m,NEEDY) &&
406 : 0 : (true_item_value(o) < (long) Level->depth*Level->depth))
407 : 0 : nprint1("...and looks chasteningly at you.");
408 : : else {
409 : 0 : nprint1("...and seems happy with it.");
410 : 0 : m_status_reset(m,HOSTILE);
411 : 0 : m_status_reset(m,GREEDY);
412 : 0 : m_status_reset(m,NEEDY);
413 : : }
414 : : }
415 [ # # ]: 0 : else if (m_statusp(m,HUNGRY)) {
416 : :
417 [ # # ][ # # ]: 0 : if (((m->id == HORSE) && (o->id == OB_GRAIN)) || /* grain */
[ # # ]
418 [ # # ]: 0 : ((m->id != HORSE) &&
419 [ # # ]: 0 : ((o->usef == I_FOOD) || (o->usef == I_POISON_FOOD)))) {
420 : 0 : strcat(Str3," wolfs down your food ... ");
421 : 0 : print1(Str3);
422 : 0 : m_status_reset(m,HUNGRY);
423 : 0 : m_status_reset(m,HOSTILE);
424 [ # # ]: 0 : if (o->usef == I_POISON_FOOD) {
425 : 0 : Player.alignment -= 2;
426 : 0 : nprint1("...and chokes on the poisoned ration!");
427 : 0 : morewait();
428 : 0 : m_status_set(m,HOSTILE);
429 : 0 : m_damage(m,100,POISON);
430 : : }
431 : 0 : else nprint1("...and now seems satiated.");
432 : 0 : morewait();
433 : 0 : free_obj(o, TRUE);
434 : : }
435 : : else {
436 : 0 : strcat(Str3," spurns your offering and leaves it on the ground.");
437 : 0 : print1(Str3);
438 : 0 : drop_at(m->x,m->y,o);
439 : : }
440 : : }
441 : : else {
442 : 0 : strcat(Str3," doesn't care for your offering and drops it.");
443 : 0 : print1(Str3);
444 : 0 : drop_at(m->x,m->y,o);
445 : : }
446 : : }
447 : 0 : }
448 : :
449 : :
450 : :
451 : : /* will clear all, not just one of an object. */
452 : 0 : void conform_lost_object(pob obj)
453 : : {
454 [ # # ]: 0 : if (obj != NULL) conform_lost_objects(obj->number,obj);
455 : 0 : }
456 : :
457 : :
458 : :
459 : : /* removes n of object from inventory; frees object if appropriate. */
460 : :
461 : 2 : void dispose_lost_objects(int n, pob obj)
462 : : {
463 : 2 : int i,conformed=FALSE,subtracted=FALSE;
464 : :
465 [ - + ]: 2 : if (obj == NULL)
466 : 0 : return;
467 [ + + ]: 34 : for(i=0;i<MAXITEMS;i++)
468 [ + + ]: 32 : if (Player.possessions[i] == obj) {
469 [ + - ]: 2 : if (! subtracted) {
470 : 2 : obj->number -= n;
471 : 2 : subtracted = TRUE;
472 : : }
473 [ + - ]: 2 : if (obj->number < 1) {
474 [ + - ]: 2 : if (!conformed) {
475 : 2 : conform_unused_object(obj);
476 : 2 : conformed = TRUE;
477 : : }
478 : 2 : Player.possessions[i] = NULL;
479 : : }
480 : : }
481 [ + - ]: 2 : if (obj->number < 1)
482 : 2 : free_obj( obj, TRUE );
483 : : }
484 : :
485 : :
486 : : /* removes n of object from inventory without freeing object.
487 : : Removes all instances of pointer (might be 2 handed weapon, etc) */
488 : 2 : void conform_lost_objects(int n, pob obj)
489 : : {
490 : 2 : int i,conformed=FALSE,subtracted=FALSE;
491 [ + - ][ + + ]: 34 : if (obj != NULL) for(i=0;i<MAXITEMS;i++)
492 [ + + ]: 32 : if (Player.possessions[i] == obj) {
493 [ + - ]: 2 : if (! subtracted) {
494 : 2 : obj->number -= n;
495 : 2 : subtracted = TRUE;
496 : : }
497 [ + - ]: 2 : if (obj->number < 1) {
498 [ + - ]: 2 : if (!conformed) {
499 : 2 : conform_unused_object(obj);
500 : 2 : conformed = TRUE;
501 : : }
502 : 2 : Player.possessions[i] = NULL;
503 : : }
504 : : }
505 : 2 : }
506 : :
507 : :
508 : : /* clears unused possession */
509 : 4 : void conform_unused_object(pob obj)
510 : : {
511 [ + + ]: 4 : if (obj->used) {
512 : 2 : obj->used = FALSE;
513 : 2 : item_use(obj);
514 : 2 : inv_display_munge();
515 : : }
516 : 4 : calc_melee();
517 : 4 : }
518 : :
519 : :
520 : : /* select an item from inventory */
521 : : /* if itype is NULL_ITEM, any kind of item is acceptable.
522 : : if itype is CASH, any kind of item or '$' (cash) is acceptable.
523 : : if itype is FOOD, CORPSE or FOOD is acceptable, but only FOOD is
524 : : listed in the possibilities.
525 : : if itype is any other object type (eg SCROLL, POTION, etc.), only
526 : : that type of item is acceptable or is listed */
527 : :
528 : 60 : int item_is_selectable (Symbol itype, struct object * item)
529 : : {
530 [ + + ]: 60 : if (!item) return FALSE;
531 : :
532 [ - + ]: 26 : if (CASH == itype) return TRUE;
533 [ + - ]: 26 : if (NULL_ITEM == itype) return TRUE;
534 [ # # ]: 0 : if (item->objchar == itype) return TRUE;
535 [ # # ][ # # ]: 0 : if (FOOD == itype && CORPSE == item->objchar) return TRUE;
536 : :
537 : 0 : return FALSE;
538 : : }
539 : :
540 : 0 : int getitem (Symbol itype)
541 : : {
542 : 0 : return getitem_prompt(0, itype);
543 : : }
544 : :
545 : 2 : int getitem_prompt (char * prompt, Symbol itype)
546 : : {
547 : : int key;
548 : : char *line3;
549 : : char invstr[64];
550 : : char selectstr[80];
551 : : int i, k;
552 : : int again;
553 : 2 : int found = FALSE;
554 : 2 : int drewmenu = FALSE;
555 : :
556 [ - + ][ # # ]: 2 : found = ((itype == NULL_ITEM) || ((itype == CASH) && (Player.cash > 0)));
[ # # ]
557 : :
558 : : /* build invstr, which lists all valid selections that the user can make */
559 : 2 : invstr[0] = 0;
560 : :
561 : 2 : k = 0;
562 [ + + ]: 32 : for(i = 1; i < MAXITEMS; ++i)
563 : : {
564 [ + + ]: 30 : if (item_is_selectable(itype, Player.possessions[i]))
565 : : {
566 : 13 : found = TRUE;
567 : 13 : invstr[k++] = index_to_key(i);
568 : 13 : invstr[k] = 0;
569 : : }
570 : : }
571 : :
572 [ - + ]: 2 : if (!found)
573 : : {
574 : 0 : print3("Nothing appropriate.");
575 : 0 : return ABORT;
576 : : }
577 : :
578 [ - + ]: 2 : if (itype == CASH)
579 : : {
580 : 0 : invstr[k++] = CASH & 0xff;
581 : 0 : invstr[k] = 0;
582 : : }
583 : :
584 : : /* gotta let the user see what everything means... */
585 : 2 : invstr[k++] = '?';
586 : 2 : invstr[k] = 0;
587 : :
588 : 2 : line3 = NULL;
589 : :
590 : : /* build prompt... */
591 : 2 : selectstr[0] = 0;
592 [ + - ]: 2 : if (prompt) strcpy(selectstr, prompt);
593 : 2 : strcat(selectstr, "Select an item. (");
594 : :
595 : 2 : i = 0;
596 : 2 : k = strlen(selectstr);
597 : : while (TRUE)
598 : : {
599 [ + + ]: 15 : if ('?' == invstr[i]) break;
600 : 13 : selectstr[k++] = invstr[i++];
601 : 13 : selectstr[k++] = ',';
602 [ - + ]: 13 : if (k > 75) break;
603 : 13 : }
604 : :
605 : 2 : selectstr[k-1] = ')';
606 : 2 : selectstr[k] = 0;
607 : :
608 : : /* get input from the user */
609 : : do
610 : : {
611 : 4 : again = FALSE;
612 : :
613 : 4 : key = cinema_interact(invstr, selectstr, " ? to display items", line3);
614 : 4 : line3 = NULL;
615 : :
616 [ + + ]: 4 : if ('?' == key)
617 : : {
618 : 2 : again = TRUE;
619 : 2 : drewmenu = TRUE;
620 [ + + ]: 32 : for (i = 1; i < MAXITEMS; ++i)
621 : : {
622 [ + + ]: 30 : if (item_is_selectable(itype, Player.possessions[i]))
623 : 13 : display_inventory_slot(i, FALSE);
624 : : }
625 : : }
626 [ - + ][ # # ]: 2 : else if ((CASH & 0xff) == key && (CASH != itype))
627 : : {
628 : 0 : again = TRUE;
629 : 0 : line3 = "You cannot select cash now.";
630 : : }
631 : : }
632 [ + + ]: 4 : while (again);
633 : :
634 [ + - ]: 2 : if (drewmenu) xredraw();
635 [ - + ]: 2 : if (-1 == key) return ABORT; /* cinema_interact() returns -1 for ESC */
636 [ - + ]: 2 : if ((CASH & 0xff) == key) return CASHVALUE;
637 : :
638 : 2 : return key_to_index(key);
639 : : }
640 : :
641 : :
642 : : /* true if the numerical index based on 'a' == 1 turns out to be either
643 : : out of the range of the possessions array or a null item */
644 : 0 : int badobject(char slotchar)
645 : : {
646 : 0 : int slot = slotchar + 1 - 'a';
647 [ # # ][ # # ]: 0 : if ((slot<1) || (slot >= MAXITEMS)) return(TRUE);
648 : 0 : else return(Player.possessions[slot] == NULL);
649 : : }
650 : :
651 : :
652 : : #ifndef MSDOS_SUPPORTED_ANTIQUE
653 : : /* this takes the numerical index directly for the same effect as badobject*/
654 : 0 : int baditem(int slotnum)
655 : : {
656 [ # # ][ # # ]: 0 : if ((slotnum<1) || (slotnum >= MAXITEMS)) return(TRUE);
657 : 0 : else return(Player.possessions[slotnum] == NULL);
658 : : }
659 : : #endif
660 : :
661 : :
662 : :
663 : : /* formerly add_item_to_pack */
664 : 3 : void gain_item(pob o)
665 : : {
666 [ - + ]: 3 : if (o->uniqueness == UNIQUE_MADE)
667 : 0 : Objects[o->id].uniqueness = UNIQUE_TAKEN;
668 [ - + ]: 3 : if (o->objchar == CASH) {
669 : 0 : print2("You gained some cash.");
670 : 0 : Player.cash += o->basevalue;
671 : 0 : free_obj(o,TRUE);
672 : 0 : dataprint();
673 : : }
674 [ - + ]: 3 : else if (optionp(PACKADD)) {
675 [ # # ]: 0 : if (! get_to_pack(o)) {
676 : 0 : Player.possessions[O_UP_IN_AIR] = o;
677 : 0 : do_inventory_control();
678 : : }
679 : : }
680 : : else {
681 : 3 : Player.possessions[O_UP_IN_AIR] = o;
682 : 3 : do_inventory_control();
683 : : }
684 : 3 : }
685 : :
686 : : /* tosses the item into the pack, making it the first reachable item */
687 : 0 : void push_pack(pob o)
688 : : {
689 : : int i;
690 [ # # ]: 0 : for (i = Player.packptr; i > 0; i--)
691 : 0 : Player.pack[i] = Player.pack[i-1];
692 : 0 : Player.pack[0] = o;
693 : 0 : Player.packptr++;
694 : 0 : }
695 : :
696 : : /* Adds item to pack list */
697 : 0 : void add_to_pack(pob o)
698 : : {
699 [ # # ]: 0 : if (Player.packptr >= MAXPACK) {
700 : 0 : print3("Your pack is full. The item drops to the ground.");
701 : 0 : drop_at(Player.x,Player.y,o);
702 : : }
703 : : else {
704 : 0 : push_pack(o);
705 : 0 : print3("Putting item in pack.");
706 : : }
707 : 0 : }
708 : :
709 : : /* Adds item to pack list, maybe going into inventory mode if pack is full */
710 : 0 : int get_to_pack(pob o)
711 : : {
712 [ # # ]: 0 : if (Player.packptr >= MAXPACK) {
713 : 0 : print3("Your pack is full.");
714 : 0 : morewait();
715 : 0 : return(FALSE);
716 : : }
717 : : else {
718 : 0 : push_pack(o);
719 : 0 : print3("Putting item in pack.");
720 : 0 : return(TRUE);
721 : : }
722 : : }
723 : :
724 : 0 : int pack_item_cost(int index)
725 : : {
726 : : int cost;
727 [ # # ]: 0 : if (index > 20) {
728 : 0 : cost = 17;
729 : : }
730 [ # # ]: 0 : else if (index > 15) {
731 : 0 : cost = 7;
732 : : }
733 : 0 : else cost = 2;
734 : 0 : return cost;
735 : : }
736 : :
737 : : /* WDT -- 'response' must be an index into the pack. */
738 : 0 : void use_pack_item(int response, int slot)
739 : : {
740 : : pob item; int i;
741 : 0 : i = pack_item_cost(response);
742 [ # # ]: 0 : if (i > 10) {
743 : 0 : cinema_scene("You begin to rummage through your pack.",NULL,NULL);
744 : : }
745 [ # # ]: 0 : if (i > 5) {
746 : 0 : cinema_scene("You search your pack for the item.",NULL,NULL);
747 : : }
748 : 0 : print3("You take the item from your pack.");
749 : 0 : morewait();
750 : 0 : Command_Duration += i;
751 : 0 : item = Player.possessions[slot] = Player.pack[response];
752 [ # # ]: 0 : for(i=response;i<Player.packptr-1;i++)
753 : 0 : Player.pack[i] = Player.pack[i+1];
754 : 0 : Player.pack[--Player.packptr] = NULL;
755 : :
756 [ # # ]: 0 : if ((slot == O_READY_HAND || slot == O_WEAPON_HAND) &&
[ # # # # ]
757 : 0 : twohandedp(item->id))
758 : : {
759 [ # # ]: 0 : if (Player.possessions[O_READY_HAND] == NULL)
760 : 0 : Player.possessions[O_READY_HAND] = item;
761 [ # # ]: 0 : if (Player.possessions[O_WEAPON_HAND] == NULL)
762 : 0 : Player.possessions[O_WEAPON_HAND] = item;
763 : : }
764 [ # # ]: 0 : if (item_useable(item,slot)) {
765 : 0 : item->used = TRUE;
766 : 0 : item_use(item);
767 : 0 : inv_display_munge();
768 : 0 : morewait();
769 [ # # ]: 0 : if (item->number > 1) pack_extra_items(item);
770 : : }
771 : 0 : }
772 : :
773 : : /* WDT HACK! This ought to be in scr.c, along with its companion. However,
774 : : * right now it's only used in the function directly below. */
775 : 0 : int aux_display_pack(int start_item, int slot)
776 : : {
777 : 0 : int i=start_item, items;
778 : : char *depth_string;
779 : :
780 : 0 : menuclear();
781 : : #if 0
782 : : /* WDT: I decided to remove these lines, since the purpose of this routine
783 : : * is to generate a pack menu, not update the message line. This is
784 : : * especially important now that I'm making the inventory system use the
785 : : * new 'Cinema' message box (which will stop the message corruption
786 : : * problems that were epidemic). */
787 : : if (Player.packptr < 1) print3("Pack is empty.");
788 : : else if (Player.packptr <= start_item) print3("You see the leather at the bottom of the pack.");
789 : : #else
790 : : /* These cases are not terribly important, but they can happen. */
791 [ # # ][ # # ]: 0 : if (Player.packptr < 1 || Player.packptr <= start_item)
792 : 0 : return start_item;
793 : : #endif
794 : : else
795 : : {
796 : 0 : items = 0;
797 [ # # ][ # # ]: 0 : for(i=start_item;i<Player.packptr && items<ScreenLength-5;i++) {
798 [ # # ]: 0 : if ( aux_slottable(Player.pack[i],slot) ) {
799 [ # # ]: 0 : if (pack_item_cost(i) > 10)
800 : 0 : depth_string = "**";
801 [ # # ]: 0 : else if (pack_item_cost(i) > 5)
802 : 0 : depth_string = "* ";
803 : 0 : else depth_string = " ";
804 : 0 : sprintf(Str1, " %c: %s %s\n", i + 'a', depth_string,
805 : 0 : itemid(Player.pack[i]));
806 [ # # ]: 0 : if (items == 0)
807 : 0 : menuprint("Items in Pack:\n");
808 : 0 : menuprint(Str1);
809 : 0 : items++;
810 : : }
811 : : }
812 [ # # ]: 0 : if (items == 0)
813 : 0 : menuprint("You see nothing useful for that slot in the pack.");
814 : : else {
815 : 0 : menuprint("\n*: Takes some time to reach; **: buried very deeply.");
816 : : }
817 : 0 : showmenu();
818 : : }
819 : 0 : return i;
820 : : }
821 : :
822 : : /* takes something from pack, puts to slot,
823 : : * or to 'up-in-air', one of which at least must be empty */
824 : 0 : int aux_take_from_pack(int slot)
825 : : {
826 : : char response,pack_item, last_item;
827 : 0 : int quit = FALSE,ok=TRUE;
828 [ # # ]: 0 : if (Player.possessions[slot] != NULL)
829 : 0 : slot = O_UP_IN_AIR;
830 [ # # ]: 0 : if (Player.possessions[slot] != NULL)
831 : 0 : print3("slot is not empty!");
832 [ # # ]: 0 : else if (Player.packptr < 1)
833 : 0 : print3("Pack is empty!");
834 : : else {
835 : 0 : pack_item = 0;
836 : : do {
837 : 0 : ok = TRUE;
838 : 0 : last_item = aux_display_pack(pack_item,slot);
839 [ # # ][ # # ]: 0 : if (last_item == Player.packptr && pack_item == 0 )
840 : 0 : print1("Enter pack slot letter or ESCAPE to quit.");
841 [ # # ]: 0 : else if (last_item == Player.packptr)
842 : 0 : print1("Enter pack slot letter, - to go back, or ESCAPE to quit.");
843 [ # # ]: 0 : else if (pack_item == 0)
844 : 0 : print1("Enter pack slot letter, + to see more, or ESCAPE to quit.");
845 : : else
846 : 0 : print1("Enter pack slot letter, + or - to see more, or ESCAPE to quit.");
847 : 0 : response = mcigetc();
848 [ # # ]: 0 : if (response == '?') {
849 : : /* WDT HACK -- display some help instead. */
850 : 0 : print1("Help not implemented (sorry).");
851 : 0 : morewait();
852 : 0 : ok = FALSE;
853 : : }
854 [ # # ]: 0 : else if (response == ESCAPE) quit = TRUE;
855 [ # # ]: 0 : else if (response == '+') {
856 [ # # ]: 0 : if (last_item < Player.packptr)
857 : 0 : pack_item = last_item;
858 : 0 : ok = FALSE;
859 : : }
860 [ # # ]: 0 : else if (response == '-') {
861 : : /* WDT HACK: this _should_ make us page up. Sadly,
862 : : * I have no way of calculating how much I'll be paging up.
863 : : * This is fixable, but I have no idea how much work... As
864 : : * a hack, I'm just returning to the first page of the listing.
865 : : */
866 : 0 : pack_item = 0;
867 : 0 : ok = FALSE;
868 : : }
869 : : else{
870 [ # # ][ # # ]: 0 : ok = ((response >= 'a') && (response < 'a'+Player.packptr));
871 [ # # ]: 0 : if (ok) ok = slottable(Player.pack[response-'a'],slot);
872 : : }
873 [ # # ]: 0 : } while (! ok);
874 [ # # ]: 0 : if (! quit) {
875 : 0 : use_pack_item(response - 'a',slot);
876 : : }
877 : : }
878 : :
879 : 0 : inv_display_munge();
880 : :
881 : 0 : return slot;
882 : : }
883 : :
884 : : /* takes something from pack, puts to slot,
885 : : or to 'up-in-air', one of which at least must be empty */
886 : 0 : int aux_top_take_from_pack(int slot, int display)
887 : : {
888 : : char response;
889 : 0 : int quit = FALSE,ok=TRUE;
890 : :
891 [ # # ]: 0 : if (Player.possessions[slot] != NULL)
892 : 0 : slot = O_UP_IN_AIR;
893 [ # # ]: 0 : if (Player.possessions[slot] != NULL)
894 : 0 : print3("slot is not empty!");
895 [ # # ]: 0 : else if (Player.packptr == 0)
896 : 0 : print3("Pack is empty!");
897 : : else {
898 : : do {
899 : 0 : ok = TRUE;
900 : 0 : print1("Enter pack slot letter, or ? to show pack, or ESCAPE to quit.");
901 : 0 : response = mcigetc();
902 [ # # ]: 0 : if (response == '?') {
903 : 0 : display_pack();
904 : 0 : inv_display_munge();
905 : 0 : ok = FALSE;
906 : : }
907 [ # # ]: 0 : else if (response == ESCAPE) quit = TRUE;
908 : : else{
909 [ # # ][ # # ]: 0 : ok = ((response >= 'a') && (response < 'a'+Player.packptr));
910 [ # # ]: 0 : if (ok) ok = slottable(Player.pack[response-'a'],slot);
911 : : }
912 [ # # ]: 0 : } while (! ok);
913 [ # # ]: 0 : if (! quit) use_pack_item(response - 'a',slot);
914 : : }
915 : 0 : return slot;
916 : : }
917 : :
918 : 0 : int take_from_pack(int slot, int display)
919 : : {
920 [ # # ]: 0 : if (optionp(TOPINV)) return aux_top_take_from_pack(slot,display);
921 : 0 : else return aux_take_from_pack(slot);
922 : : }
923 : :
924 : :
925 : : #ifndef MSDOS_SUPPORTED_ANTIQUE
926 : : /* General interface to inventory */
927 : 0 : void item_inventory(int topline)
928 : : {
929 [ # # ]: 0 : if (topline) {
930 : 0 : display_possessions();
931 : 0 : inventory_control();
932 : : }
933 : 0 : else top_inventory_control();
934 : 0 : }
935 : : #endif
936 : :
937 : :
938 : 4 : void do_inventory_control(void)
939 : : {
940 [ - + ]: 4 : if (optionp(TOPINV)) top_inventory_control();
941 : : else {
942 : 4 : menuclear();
943 : 4 : display_possessions();
944 : 4 : inventory_control();
945 : : }
946 : 4 : }
947 : :
948 : : /* inventory_control assumes a few setup things have been done,
949 : : * like loading the O_UP_IN_AIR item, etc.
950 : : * Each action uses up a little time. If only inspection actions
951 : : * are taken, no time is used up. */
952 : 4 : void inventory_control(void)
953 : : {
954 : 4 : int slot = O_UP_IN_AIR,done=FALSE;
955 : : int response;
956 : : char letter;
957 : : #ifdef MSDOS_SUPPORTED_ANTIQUE
958 : : int simple = 0;
959 : : #endif
960 : : /* Start out assuming that we'll need to redraw. */
961 : 4 : inv_display_munge();
962 : 4 : clearmsg3();
963 : :
964 : : do {
965 : 9 : checkclear();
966 : 9 : print1("Action [d,e,l,p,s,t,x,>,<,?,ESCAPE]:");
967 : 9 : inv_display_refresh();
968 : :
969 : 9 : show_inventory_slot(slot,FALSE);
970 : 9 : display_inventory_slot(O_UP_IN_AIR,FALSE);
971 : 9 : move_slot(slot,slot,MAXITEMS);
972 : 9 : response = mcigetc();
973 : :
974 [ - - - - : 9 : switch(response) {
- - - + -
- - - - +
+ ]
975 : : case 12:
976 : : case 18: /* ^l, ^r */
977 : 0 : display_possessions();
978 : 0 : break;
979 : : case 'd':
980 [ # # ]: 0 : if (Player.possessions[O_UP_IN_AIR] != NULL)
981 : : {
982 : 0 : drop_from_slot(O_UP_IN_AIR);
983 : 0 : display_inventory_slot(O_UP_IN_AIR, FALSE);
984 : : }
985 [ # # ]: 0 : else if (Player.possessions[slot] != NULL)
986 : : {
987 : 0 : drop_from_slot(slot);
988 : 0 : show_inventory_slot(slot, FALSE);
989 : : }
990 : 0 : else print3("Nothing in selected slot!");
991 : 0 : Command_Duration++;
992 : 0 : break;
993 : : case 'l':
994 : 0 : Str1[0] = '\0';
995 [ # # ]: 0 : if (Player.possessions[slot] != NULL) {
996 [ # # ]: 0 : if (!strcmp(itemid(Player.possessions[slot]),
997 : 0 : Player.possessions[slot]->objstr))
998 : 0 : print3("You notice nothing new about it.");
999 : : else {
1000 [ # # ]: 0 : if (Player.possessions[slot]->uniqueness == COMMON)
1001 : 0 : strcat(Str1, "Your ");
1002 : 0 : strcat(Str1, itemid(Player.possessions[slot]));
1003 [ # # ]: 0 : if (Player.possessions[slot]->objchar == BOOTS)
1004 : 0 : strcat(Str1, " look like ");
1005 : : else {
1006 : 0 : strcat(Str1, " looks like a");
1007 : 0 : letter = Player.possessions[slot]->objstr[0];
1008 [ # # ][ # # ]: 0 : if (letter == 'a' || letter == 'A' || letter == 'e' ||
[ # # ][ # # ]
1009 [ # # ][ # # ]: 0 : letter == 'E' || letter == 'i' || letter == 'I' ||
[ # # ]
1010 [ # # ][ # # ]: 0 : letter == 'o' || letter == 'O' || letter == 'u' || letter == 'U')
[ # # ]
1011 : 0 : strcat(Str1, "n ");
1012 : : else
1013 : 0 : strcat(Str1, " ");
1014 : : }
1015 : 0 : strcat(Str1, Player.possessions[slot]->objstr);
1016 : 0 : print3(Str1);
1017 : : }
1018 : : }
1019 : 0 : else print3("Nothing in selected slot!");
1020 : 0 : break;
1021 : : case 'p':
1022 [ # # ]: 0 : if (Player.possessions[slot] != NULL)
1023 : : {
1024 : 0 : put_to_pack(slot);
1025 : 0 : show_inventory_slot(slot, FALSE);
1026 : : }
1027 : 0 : Command_Duration+=5;
1028 : 0 : break;
1029 : : case 's':
1030 : 0 : display_pack();
1031 : 0 : morewait();
1032 : 0 : inv_display_munge();
1033 : 0 : Command_Duration+=5;
1034 : 0 : break;
1035 : : case 't':
1036 : 0 : show_inventory_slot(take_from_pack(slot,TRUE), FALSE);
1037 : 0 : Command_Duration+=5;
1038 : 0 : break;
1039 : : case 'e':
1040 : 0 : switch_to_slot(slot);
1041 : 0 : show_inventory_slot(O_UP_IN_AIR,FALSE);
1042 : 0 : show_inventory_slot(slot,FALSE);
1043 : 0 : Command_Duration+=2;
1044 : 0 : break;
1045 : : case '\n':
1046 : : case 'x':
1047 : 2 : switch_to_slot(slot);
1048 : 2 : show_inventory_slot(O_UP_IN_AIR,FALSE);
1049 : 2 : show_inventory_slot(slot,FALSE);
1050 : 2 : Command_Duration+=2;
1051 : 2 : done = (Player.possessions[O_UP_IN_AIR] == NULL);
1052 : 2 : break;
1053 : : case 'j':
1054 : : case '>':
1055 : : case '2':
1056 : : #if defined(KEY_DOWN)
1057 : : case KEY_DOWN:
1058 : : #endif
1059 : 0 : slot = move_slot(slot,slot+1,MAXITEMS);
1060 : 0 : break;
1061 : : case 'k':
1062 : : case '<':
1063 : : case '8':
1064 : : #if defined(KEY_UP)
1065 : : case KEY_UP:
1066 : : #endif
1067 : 0 : slot = move_slot(slot,slot-1,MAXITEMS);
1068 : 0 : break;
1069 : : #ifdef KEY_HOME
1070 : : case KEY_HOME:
1071 : : #endif
1072 : : case '-':
1073 : 0 : slot = move_slot(slot,0,MAXITEMS);
1074 : 0 : break;
1075 : : #ifdef KEY_LL
1076 : : case KEY_LL:
1077 : : #endif
1078 : : case '+':
1079 : 0 : slot = move_slot(slot,MAXITEMS-1,MAXITEMS);
1080 : 0 : break;
1081 : : case '?':
1082 : 0 : menuclear();
1083 : 0 : menuprint("d:\tDrop up-in-air or current item\n");
1084 : 0 : menuprint("e:\tExchange current slot with up-in-air slot\n");
1085 : 0 : menuprint("l:\tLook at current item\n");
1086 : 0 : menuprint("p:\tPut up-in-air or current item in pack\n");
1087 : 0 : menuprint("s:\tShow contents of pack\n");
1088 : 0 : menuprint("t:\tTake something from pack into the\n\tcurrent or up-in-air slot\n");
1089 : 0 : menuprint("x:\tAs 'e', but exit if up-in-air slot finishes empty\n");
1090 : 0 : menuprint(">:\tMove down one slot/item\n");
1091 : 0 : menuprint("<:\tMove up one slot/item\n");
1092 : 0 : menuprint("?:\tDisplay help (this message + help file)\n");
1093 : 0 : menuprint("ESCAPE:\texit\n");
1094 : 0 : showmenu();
1095 : 0 : clearmsg();
1096 : 0 : print1("Display full help? (y/n)");
1097 [ # # ]: 0 : if (ynq1() == 'y')
1098 : 0 : inv_help();
1099 : 0 : inv_display_munge();
1100 : 0 : break;
1101 : : case ESCAPE:
1102 [ - + ]: 2 : if (Player.possessions[O_UP_IN_AIR] != NULL) {
1103 : 0 : drop_at(Player.x,Player.y,Player.possessions[O_UP_IN_AIR]);
1104 : 0 : Player.possessions[O_UP_IN_AIR] = NULL;
1105 : 0 : print3("Object 'up in air' dropped.");
1106 : : }
1107 : 2 : done = TRUE;
1108 : 2 : break;
1109 : : default:
1110 [ + - ]: 5 : if (key_to_index(response) > 0) {
1111 : 5 : slot = move_slot(slot,key_to_index(response),MAXITEMS);
1112 [ + + ]: 5 : if (Player.possessions[slot] == NULL
1113 [ - + ]: 2 : &&
1114 : 2 : Player.possessions[O_UP_IN_AIR] == NULL) {
1115 : 0 : show_inventory_slot(take_from_pack(slot,TRUE), FALSE);
1116 : 0 : Command_Duration+=5;
1117 : : }
1118 : : else {
1119 : 5 : switch_to_slot(slot);
1120 : 5 : show_inventory_slot(slot,FALSE);
1121 : 5 : slot = O_UP_IN_AIR;
1122 : 5 : show_inventory_slot(slot,FALSE);
1123 : 5 : Command_Duration+=2;
1124 : : }
1125 : : }
1126 : : }
1127 : 9 : calc_melee();
1128 [ + + ]: 9 : } while (! done);
1129 : 4 : xredraw();
1130 : 4 : }
1131 : :
1132 : :
1133 : : /* Make it clear that the inventory window mmust be redrawn. */
1134 : : static int inv_must_redraw;
1135 : 8 : static void inv_display_munge(void)
1136 : : {
1137 : 8 : inv_must_redraw = TRUE;
1138 : 8 : }
1139 : :
1140 : 9 : static void inv_display_refresh(void)
1141 : : {
1142 [ + + ]: 9 : if ( inv_must_redraw )
1143 : 6 : display_possessions();
1144 : 9 : inv_must_redraw = FALSE;
1145 : 9 : }
1146 : :
1147 : :
1148 : : /* same as inventory_control, but only uses msg window for i/o*/
1149 : :
1150 : :
1151 : 0 : void top_inventory_control(void)
1152 : : {
1153 : 0 : int slot = 0,done=FALSE,usedmenu=FALSE;
1154 : : char response, letter;
1155 : 0 : clearmsg3();
1156 : : do {
1157 : 0 : clearmsg1();
1158 : 0 : print1("Action [d,e,l,p,s,t,x,~,?,ESCAPE]:");
1159 : 0 : print2("'Up in air': ");
1160 [ # # ]: 0 : if (Player.possessions[O_UP_IN_AIR] == NULL) nprint2("NOTHING");
1161 : 0 : else nprint2(itemid(Player.possessions[O_UP_IN_AIR]));
1162 : 0 : response = (char) mcigetc();
1163 : :
1164 [ # # # # : 0 : switch(response) {
# # # # #
# # ]
1165 : : case 'd':
1166 [ # # ]: 0 : if (Player.possessions[O_UP_IN_AIR] != NULL)
1167 : 0 : drop_from_slot(O_UP_IN_AIR);
1168 : : else {
1169 : 0 : slot = get_inventory_slot();
1170 [ # # ]: 0 : if (Player.possessions[slot] != NULL)
1171 : 0 : drop_from_slot(slot);
1172 : 0 : else print3("Nothing in selected slot!");
1173 : : }
1174 : 0 : Command_Duration++;
1175 : 0 : break;
1176 : : case 'l':
1177 : 0 : Str1[0] = '\0';
1178 : 0 : slot = get_inventory_slot();
1179 [ # # ]: 0 : if (Player.possessions[slot] != NULL) {
1180 [ # # ]: 0 : if (!strcmp(itemid(Player.possessions[slot]),
1181 : 0 : Player.possessions[slot]->objstr))
1182 : 0 : print3("You notice nothing new about it.");
1183 : : else {
1184 [ # # ]: 0 : if (Player.possessions[slot]->uniqueness == COMMON)
1185 : 0 : strcat(Str1, "Your ");
1186 : 0 : strcat(Str1, itemid(Player.possessions[slot]));
1187 [ # # ]: 0 : if (Player.possessions[slot]->objchar == BOOTS)
1188 : 0 : strcat(Str1, " look like ");
1189 : : else {
1190 : 0 : strcat(Str1, " looks like a");
1191 : 0 : letter = Player.possessions[slot]->objstr[0];
1192 [ # # ][ # # ]: 0 : if (letter == 'a' || letter == 'A' || letter == 'e' ||
[ # # ][ # # ]
1193 [ # # ][ # # ]: 0 : letter == 'E' || letter == 'i' || letter == 'I' ||
[ # # ]
1194 [ # # ][ # # ]: 0 : letter == 'o' || letter == 'O' || letter == 'u' || letter == 'U')
[ # # ]
1195 : 0 : strcat(Str1, "n ");
1196 : : else
1197 : 0 : strcat(Str1, " ");
1198 : : }
1199 : 0 : strcat(Str1, Player.possessions[slot]->objstr);
1200 : 0 : print3(Str1);
1201 : : }
1202 : : }
1203 : 0 : else print3("Nothing in selected slot!");
1204 : 0 : break;
1205 : : case 'p':
1206 [ # # ]: 0 : if (Player.possessions[O_UP_IN_AIR] == NULL)
1207 : 0 : slot = get_inventory_slot();
1208 : 0 : else slot = O_UP_IN_AIR;
1209 : 0 : put_to_pack(slot);
1210 : 0 : Command_Duration+=5;
1211 : 0 : break;
1212 : : case 's':
1213 : 0 : display_pack();
1214 : 0 : usedmenu = TRUE;
1215 : 0 : Command_Duration+=5;
1216 : 0 : break;
1217 : : case 't':
1218 : 0 : slot = get_inventory_slot();
1219 : 0 : (void) take_from_pack(slot,FALSE);
1220 : 0 : Command_Duration+=5;
1221 : 0 : break;
1222 : : case 'e':
1223 : 0 : slot = get_inventory_slot();
1224 [ # # ]: 0 : if ( slot == O_UP_IN_AIR ) break;
1225 : 0 : switch_to_slot(slot);
1226 : 0 : Command_Duration+=2;
1227 : 0 : break;
1228 : : case 'x':
1229 : 0 : slot = get_inventory_slot();
1230 [ # # ]: 0 : if ( slot == O_UP_IN_AIR ) break;
1231 : 0 : switch_to_slot(slot);
1232 : 0 : Command_Duration+=2;
1233 : 0 : done = (Player.possessions[O_UP_IN_AIR] == NULL);
1234 : 0 : break;
1235 : : case '~':
1236 : 0 : display_possessions();
1237 : 0 : inventory_control();
1238 : 0 : usedmenu = TRUE;
1239 : 0 : done = TRUE;
1240 : 0 : break;
1241 : : case '?':
1242 : 0 : menuclear();
1243 : 0 : menuprint("d:\tDrop an item\n");
1244 : 0 : menuprint("e:\tExchange a slot with up-in-air slot\n");
1245 : 0 : menuprint("l:\tLook at an item\n");
1246 : 0 : menuprint("p:\tPut an item in pack\n");
1247 : 0 : menuprint("s:\tShow contents of pack\n");
1248 : 0 : menuprint("t:\tTake something from pack into a slot\n");
1249 : 0 : menuprint("x:\tAs 'e', above, exit if up-in-air slot finishes empty\n");
1250 : 0 : menuprint("~:\tEnter full-screen inventory mode\n");
1251 : 0 : menuprint("?:\tDisplay help (this message + help file)\n");
1252 : 0 : menuprint("ESCAPE:\texit\n");
1253 : 0 : showmenu();
1254 : 0 : clearmsg();
1255 : 0 : print1("Display full help? (y/n)");
1256 [ # # ]: 0 : if (ynq1() == 'y')
1257 : 0 : inv_help();
1258 : 0 : usedmenu=TRUE;
1259 : 0 : break;
1260 : : case ESCAPE:
1261 [ # # ]: 0 : if (Player.possessions[O_UP_IN_AIR] != NULL) {
1262 : 0 : drop_at(Player.x,Player.y,Player.possessions[O_UP_IN_AIR]);
1263 : 0 : Player.possessions[O_UP_IN_AIR] = NULL;
1264 : 0 : print3("Object 'up in air' dropped.");
1265 : : }
1266 : 0 : done = TRUE;
1267 : 0 : break;
1268 : : }
1269 : 0 : calc_melee();
1270 [ # # ]: 0 : } while (! done);
1271 [ # # ]: 0 : if (usedmenu)
1272 : 0 : xredraw();
1273 : 0 : }
1274 : :
1275 : :
1276 : :
1277 : : /* Let the user select a slot. */
1278 : 0 : int get_inventory_slot(void)
1279 : : {
1280 : : signed char response;
1281 : : do {
1282 : 0 : clearmsg1();
1283 : 0 : print1("Which inventory slot ['-'='up-in-air' slot]?");
1284 : 0 : response = (signed char)mcigetc();
1285 [ # # ][ # # ]: 0 : if ( response == ESCAPE || response == '-' )
1286 : 0 : return O_UP_IN_AIR;
1287 : 0 : else response = key_to_index(response);
1288 [ # # ]: 0 : } while (response != O_UP_IN_AIR);
1289 : 0 : return response;
1290 : : }
1291 : :
1292 : :
1293 : : /* returns some number between 0 and o->number */
1294 : 0 : int get_item_number(pob o)
1295 : : {
1296 : 0 : int n=0;
1297 [ # # ]: 0 : if (o->number == 1)
1298 : 0 : return 1;
1299 : : do {
1300 : 0 : clearmsg();
1301 : 0 : print1("How many? -- max ");
1302 : 0 : mnumprint(o->number);
1303 : 0 : nprint1(" :");
1304 : 0 : n = (int) parsenum("");
1305 [ # # ]: 0 : if (n>o->number) print3("Too many!");
1306 [ # # ]: 0 : else if (n<1) n = 0;
1307 [ # # ]: 0 : } while (n > o->number);
1308 [ # # ]: 0 : if (n < 1) n = 0;
1309 : 0 : return(n);
1310 : : }
1311 : :
1312 : 0 : void drop_from_slot(int slot)
1313 : : {
1314 : : int n,waitflag;
1315 [ # # ]: 0 : if (Player.possessions[slot] != NULL) {
1316 [ # # ]: 0 : if(cursed(Player.possessions[slot]) == TRUE + TRUE)
1317 : 0 : print3("It sticks to your fingers!");
1318 : : else {
1319 : 0 : n = get_item_number(Player.possessions[slot]);
1320 [ # # ]: 0 : if (n > 0) {
1321 : 0 : p_drop_at(Player.x,Player.y,n,Player.possessions[slot]);
1322 [ # # ][ # # ]: 0 : waitflag = (Player.possessions[slot]->used &&
1323 : 0 : (Player.possessions[slot]->number == n));
1324 : 0 : conform_lost_objects(n,Player.possessions[slot]);
1325 [ # # ]: 0 : if (waitflag) morewait();
1326 : : }
1327 : 0 : else print3("Didn't drop anything.");
1328 : : }
1329 : : }
1330 : 0 : else print3("Didn't drop anything.");
1331 : 0 : }
1332 : :
1333 : :
1334 : 0 : void put_to_pack(int slot)
1335 : : {
1336 : 0 : int waitflag,num = 1;
1337 : 0 : pob temp,oslot = Player.possessions[slot];
1338 [ # # ]: 0 : if (oslot == NULL)
1339 : 0 : print3("Slot is empty!");
1340 [ # # ]: 0 : else if (cursed(oslot) == TRUE+TRUE)
1341 : 0 : print3("Item is cursed!");
1342 : : else {
1343 : 0 : num = get_item_number(oslot);
1344 [ # # ]: 0 : if (num > 0) {
1345 : 0 : temp = split_item(num,oslot);
1346 [ # # ][ # # ]: 0 : waitflag = (oslot->used && (oslot->number == num));
1347 : 0 : conform_lost_objects(num,oslot);
1348 [ # # ]: 0 : if (waitflag) morewait();
1349 : 0 : add_to_pack(temp);
1350 : : }
1351 : : }
1352 : 0 : }
1353 : :
1354 : :
1355 : : /* splits num off of item to make newitem which is returned */
1356 : : /* something else (conform_lost_objects) has to reduce the actual
1357 : : number value of item and Player.itemweight */
1358 : 0 : pob split_item(int num, pob item)
1359 : : {
1360 : 0 : pob newitem=NULL;
1361 [ # # ]: 0 : if (item != NULL) {
1362 : 0 : newitem = copy_obj( item );
1363 [ # # ]: 0 : if (num <= item->number)
1364 : 0 : newitem->number = num;
1365 : : /* else num > item->number, so return newitem with number = item->number */
1366 : 0 : newitem->used = FALSE; /* whether the original item was used or not */
1367 : : }
1368 : 0 : return(newitem);
1369 : : }
1370 : :
1371 : :
1372 : :
1373 : : /* Trades contents of "up in air" slot with selected slot. One or both
1374 : : may be null. If both slots are 'objequal' merges two groups into one
1375 : : in the selected slot. If one slot is null and the number of the other
1376 : : is greater than one, requests how many to move. */
1377 : :
1378 : 7 : void switch_to_slot(int slot)
1379 : : {
1380 : 7 : pob oslot = Player.possessions[slot];
1381 : 7 : pob oair = Player.possessions[O_UP_IN_AIR];
1382 : 7 : pob otemp = NULL;
1383 : 7 : int slotnull,airnull,num=1,trade=FALSE,put=FALSE,take=FALSE,merge=FALSE;
1384 : 7 : int s2h=FALSE,a2h=FALSE;
1385 : :
1386 : : /* ie, is cursed and in use */
1387 [ + + ]: 7 : if (slot == O_UP_IN_AIR)
1388 : 2 : print3("This action makes no sense!");
1389 [ - + ]: 5 : else if (cursed(oslot)==TRUE+TRUE) /* WDT: this is SICK!!!! TRUE doesn't
1390 : : * add. */
1391 : 0 : print3("The object in that slot is cursed -- you can't get rid of it!");
1392 : : else {
1393 : :
1394 : 5 : slotnull = (oslot == NULL);
1395 : 5 : airnull = (oair == NULL);
1396 : :
1397 [ + + ]: 5 : if (!slotnull)
1398 : 3 : s2h = (Player.possessions[O_READY_HAND] ==
1399 : 3 : Player.possessions[O_WEAPON_HAND]);
1400 : :
1401 [ + - ]: 5 : if (! airnull)
1402 [ - + ][ # # ]: 5 : a2h = (twohandedp(oair->id) &&
1403 [ # # ]: 0 : ((slot == O_READY_HAND) || (slot == O_WEAPON_HAND)));
1404 : :
1405 : :
1406 : : /* figure out which action to take */
1407 : :
1408 : : /* merge if both are same kind of object */
1409 : 5 : merge = objequal(oslot,oair);
1410 : :
1411 [ + + ][ + + ]: 5 : take = ((!merge) && (!slotnull) && airnull);
[ - + ]
1412 : :
1413 [ + + ][ + + ]: 5 : put = ((!merge) && slotnull && (!airnull) && slottable(oair,slot));
[ + - ][ + - ]
1414 : :
1415 [ + + ][ + + ]: 5 : trade = ((!merge) && (!slotnull) && (!airnull) && slottable(oair,slot));
[ + - ][ + - ]
1416 : :
1417 [ + + ]: 5 : if (merge) merge_item(slot);
1418 : :
1419 [ + + ]: 4 : else if (put) {
1420 : :
1421 : : /* deal with a 2-handed weapon */
1422 [ - + ]: 2 : if (a2h) {
1423 [ # # ]: 0 : if (Player.possessions[O_READY_HAND] == NULL)
1424 : 0 : Player.possessions[O_READY_HAND] = oair;
1425 [ # # ]: 0 : if (Player.possessions[O_WEAPON_HAND] == NULL)
1426 : 0 : Player.possessions[O_WEAPON_HAND] = oair;
1427 : : }
1428 : 2 : else Player.possessions[slot] = oair;
1429 : 2 : Player.possessions[O_UP_IN_AIR] = NULL;
1430 [ - + ]: 2 : if (item_useable(oair,slot)) {
1431 : 0 : oair->used = TRUE;
1432 : 0 : item_use(oair);
1433 : 0 : inv_display_munge();
1434 : 0 : morewait();
1435 [ # # ]: 0 : if (oair->number > 1) pack_extra_items(oair);
1436 : : }
1437 : 2 : Player.possessions[O_UP_IN_AIR] = NULL;
1438 : : }
1439 : :
1440 [ - + ]: 2 : else if (take) {
1441 : 0 : num = get_item_number(oslot);
1442 [ # # ]: 0 : if (num > 0) {
1443 : 0 : otemp = split_item(num,oslot);
1444 : 0 : dispose_lost_objects(num,oslot);
1445 : 0 : Player.possessions[O_UP_IN_AIR] = otemp;
1446 : : }
1447 [ # # ]: 0 : if (s2h) {
1448 [ # # ]: 0 : if (Player.possessions[O_READY_HAND] == oslot)
1449 : 0 : Player.possessions[O_READY_HAND] = NULL;
1450 [ # # ]: 0 : if (Player.possessions[O_WEAPON_HAND] == oslot)
1451 : 0 : Player.possessions[O_WEAPON_HAND] = NULL;
1452 : : }
1453 : : }
1454 : :
1455 [ + - ]: 2 : else if (trade) {
1456 : :
1457 : : /* first remove item from slot */
1458 : 2 : num = oslot->number;
1459 : 2 : conform_lost_objects(oslot->number,oslot);
1460 : 2 : oslot->number = num;
1461 : :
1462 : 2 : Player.possessions[O_UP_IN_AIR] = oslot;
1463 : :
1464 : 2 : Player.possessions[slot] = oair;
1465 : :
1466 [ - + ]: 2 : if (s2h) {
1467 [ # # ]: 0 : if (Player.possessions[O_READY_HAND] == oslot)
1468 : 0 : Player.possessions[O_READY_HAND] = NULL;
1469 [ # # ]: 0 : if (Player.possessions[O_WEAPON_HAND] == oslot)
1470 : 0 : Player.possessions[O_WEAPON_HAND] = NULL;
1471 : : }
1472 : :
1473 [ - + ]: 2 : if (a2h) {
1474 [ # # ]: 0 : if (Player.possessions[O_READY_HAND] == NULL)
1475 : 0 : Player.possessions[O_READY_HAND] = oair;
1476 [ # # ]: 0 : if (Player.possessions[O_WEAPON_HAND] == NULL)
1477 : 0 : Player.possessions[O_WEAPON_HAND] = oair;
1478 : : }
1479 : :
1480 [ + - ]: 2 : if (item_useable(oair,slot)) {
1481 : 2 : oair->used = TRUE;
1482 : 2 : item_use(oair);
1483 : 2 : inv_display_munge();
1484 : 2 : morewait();
1485 [ - + ]: 2 : if (oair->number > 1) pack_extra_items(oair);
1486 : : }
1487 : : }
1488 : : }
1489 : 7 : }
1490 : :
1491 : :
1492 : :
1493 : :
1494 : : /* merges the up-in-air items into the selected items */
1495 : :
1496 : 1 : void merge_item(int slot)
1497 : : {
1498 : 2 : Player.possessions[slot]->number +=
1499 : 1 : Player.possessions[O_UP_IN_AIR]->number;
1500 : 1 : Player.possessions[O_UP_IN_AIR] = NULL;
1501 : 1 : }
1502 : :
1503 : :
1504 : : /* are two objects equal except for their number field? */
1505 : : /* returns false if either object is null */
1506 : 5 : int objequal(pob o, pob p)
1507 : : {
1508 [ + + ][ - + ]: 5 : if ((o == NULL) || (p == NULL)) return(FALSE);
1509 : 3 : else return(
1510 [ + - ]: 1 : (o->id == p->id) &&
1511 : : /* DAG won't match corpses because they use charge for monster id, */
1512 : : /* except for hornets which have mid == 0, so will stack. Prevent this. */
1513 [ + - ]: 1 : (o->id != CORPSEID) &&
1514 [ + - ]: 1 : (o->plus == p->plus) &&
1515 [ + - ]: 1 : (o->charge == 0) &&
1516 [ + - ]: 1 : (p->charge == 0) &&
1517 [ + - ]: 1 : (o->dmg == p->dmg) &&
1518 [ + - ]: 1 : (o->hit == p->hit) &&
1519 [ + - ]: 1 : (o->aux == p->aux) &&
1520 [ + - ]: 1 : (o->known == p->known) &&
1521 [ + - ]: 1 : (o->blessing == p->blessing) &&
1522 [ + + ][ + - ]: 4 : (o->usef == p->usef) &&
1523 : 1 : (o->objstr == p->objstr )
1524 : : );
1525 : :
1526 : : }
1527 : :
1528 : : /* criteria for being able to put some item in some slot */
1529 : 4 : int slottable(pob o, int slot)
1530 : : {
1531 : 4 : int ok = TRUE;
1532 [ - + ]: 4 : if (o == NULL) ok = FALSE;
1533 [ + + ]: 4 : else if (slot == O_ARMOR) {
1534 [ - + ]: 1 : if (o->objchar != ARMOR) {
1535 : 0 : print3("Only armor can go in the armor slot!");
1536 : 1 : ok = FALSE;
1537 : : }
1538 : : }
1539 [ - + ]: 3 : else if (slot == O_SHIELD) {
1540 [ # # ]: 0 : if (o->objchar != SHIELD) {
1541 : 0 : print3("Only a shield can go in the shield slot!");
1542 : 0 : ok = FALSE;
1543 : : }
1544 : : }
1545 [ - + ]: 3 : else if (slot == O_BOOTS) {
1546 [ # # ]: 0 : if (o->objchar != BOOTS) {
1547 : 0 : print3("Only boots can go in the boots slot!");
1548 : 0 : ok = FALSE;
1549 : : }
1550 : : }
1551 [ - + ]: 3 : else if (slot == O_CLOAK) {
1552 [ # # ]: 0 : if (o->objchar != CLOAK) {
1553 : 0 : print3("Only a cloak can go in the cloak slot!");
1554 : 0 : ok = FALSE;
1555 : : }
1556 : : }
1557 [ - + ]: 3 : else if (slot >= O_RING1) {
1558 [ # # ]: 0 : if (o->objchar != RING) {
1559 : 0 : print3("Only a ring can go in a ring slot!");
1560 : 0 : ok = FALSE;
1561 : : }
1562 : : }
1563 : 4 : return(ok);
1564 : : }
1565 : :
1566 : :
1567 : : /* whether or not an item o can be used in a slot. Assumes o can in
1568 : : fact be placed in the slot. */
1569 : 4 : int item_useable(pob o, int slot)
1570 : : {
1571 : : /* don't have to check the object in the first if since only armor
1572 : : can go in armor slot, cloak in cloak slot, etc */
1573 : :
1574 [ + + ][ + - ]: 4 : if ((slot == O_ARMOR) ||
1575 [ + - ]: 3 : (slot == O_CLOAK) ||
1576 [ + - ]: 3 : (slot == O_SHIELD) ||
1577 [ - + ]: 3 : (slot == O_BOOTS) ||
1578 : : (slot >= O_RING1))
1579 : 1 : return(TRUE);
1580 : :
1581 : : /* weapon is useable if it is put in weapon hand or if it is two-handed
1582 : : and put in either hand when the other also holds the weapon */
1583 : :
1584 [ + + ][ - + ]: 3 : else if ((o->objchar == WEAPON) ||
1585 : 1 : (o->objchar == MISSILEWEAPON)) {
1586 [ - + ][ # # ]: 2 : if (twohandedp(o->id) &&
1587 [ # # ]: 0 : ((slot==O_READY_HAND)||(slot==O_WEAPON_HAND))) {
1588 [ # # ]: 0 : if (Player.possessions[O_READY_HAND] ==
1589 : 0 : Player.possessions[O_WEAPON_HAND]) {
1590 : 0 : print1("You heft the weapon and find you must use both hands.");
1591 : 0 : morewait();
1592 : 0 : return(TRUE);
1593 : : }
1594 : : else {
1595 : 0 : print1("This weapon is two-handed, so at the moment, ");
1596 : 0 : print2("you are just lugging it around....");
1597 : 0 : morewait();
1598 : 0 : return(FALSE);
1599 : : }
1600 : : }
1601 : 2 : else return(slot == O_WEAPON_HAND);
1602 : : }
1603 : 1 : else return(FALSE);
1604 : : }
1605 : :
1606 : :
1607 : : /* returns FALSE if not cursed, TRUE if cursed but not used,
1608 : : TRUE + TRUE if cursed and used */
1609 : 7 : int cursed(pob obj)
1610 : : {
1611 : 7 : return((obj == NULL) ?
1612 [ + + ]: 12 : FALSE :
1613 : 5 : ((obj->blessing < 0) ?
1614 [ - + ][ # # ]: 5 : (obj->used == TRUE) + TRUE :
1615 : : FALSE));
1616 : : }
1617 : :
1618 : :
1619 : : /* returns true if item with id and charge is found in pack or in
1620 : : inventory slot. charge is used to differentiate
1621 : : corpses instead of aux, which is their food value. */
1622 : 0 : int find_item(pob *o, int id, int chargeval)
1623 : : {
1624 : 0 : int i,found=FALSE;
1625 : 0 : *o=NULL;
1626 [ # # ][ # # ]: 0 : for(i=1;((i<MAXITEMS)&&(! found));i++)
1627 [ # # ]: 0 : if (Player.possessions[i] != NULL)
1628 [ # # ][ # # ]: 0 : if ((Player.possessions[i]->id == id) &&
1629 [ # # ]: 0 : ((chargeval == -1) ||
1630 : 0 : (Player.possessions[i]->charge == chargeval))) {
1631 : 0 : *o = Player.possessions[i];
1632 : 0 : found = TRUE;
1633 : : }
1634 [ # # ]: 0 : if (! found)
1635 [ # # ][ # # ]: 0 : for(i=0;((i<Player.packptr)&&(! found));i++)
1636 [ # # ]: 0 : if (Player.pack[i] != NULL)
1637 [ # # ][ # # ]: 0 : if ((Player.pack[i]->id == id) &&
1638 [ # # ]: 0 : ((chargeval == -1) ||
1639 : 0 : (Player.pack[i]->charge == chargeval))) {
1640 : 0 : *o = Player.pack[i];
1641 : 0 : found = TRUE;
1642 : : }
1643 : 0 : return(found);
1644 : : }
1645 : :
1646 : :
1647 : : /* returns true if item with id and charge is found in pack or in
1648 : : inventory slot. Destroys item. charge is used to differentiate
1649 : : corpses instead of aux, which is their food value. */
1650 : 0 : int find_and_remove_item(int id, int chargeval)
1651 : : {
1652 : 0 : int i,found=FALSE;
1653 : 0 : pob o=NULL;
1654 : :
1655 [ # # ][ # # ]: 0 : for(i=1;((i<MAXITEMS)&&(! found));i++)
1656 [ # # ]: 0 : if (Player.possessions[i] != NULL)
1657 [ # # ][ # # ]: 0 : if ((Player.possessions[i]->id == id) &&
1658 [ # # ]: 0 : ((chargeval == -1) ||
1659 : 0 : (Player.possessions[i]->charge == chargeval))) {
1660 : 0 : o = Player.possessions[i];
1661 : 0 : conform_lost_objects(1, o);
1662 : 0 : found = TRUE;
1663 : : }
1664 [ # # ][ # # ]: 0 : if (! found) for(i=0;((i<Player.packptr)&&(! found));i++)
[ # # ]
1665 [ # # ]: 0 : if (Player.pack[i] != NULL)
1666 [ # # ][ # # ]: 0 : if ((Player.pack[i]->id == id) &&
1667 [ # # ]: 0 : ((chargeval == -1) ||
1668 : 0 : (Player.pack[i]->charge == chargeval))) {
1669 : 0 : Player.pack[i]->number--;
1670 [ # # ]: 0 : if (Player.pack[i]->number == 0) {
1671 : 0 : free_obj( Player.pack[i], TRUE );
1672 : 0 : Player.pack[i] = NULL;
1673 : : }
1674 : 0 : found = TRUE;
1675 : : }
1676 : 0 : fixpack();
1677 : 0 : return(found);
1678 : : }
1679 : :
1680 : :
1681 : 0 : void lose_all_items(void)
1682 : : {
1683 : : int i;
1684 : 0 : print1("You notice that you are completely devoid of all possessions.");
1685 : 0 : morewait();
1686 [ # # ]: 0 : for(i=0;i<MAXITEMS;i++)
1687 [ # # ]: 0 : if (Player.possessions[i] != NULL) {
1688 : 0 : dispose_lost_objects(Player.possessions[i]->number,
1689 : 0 : Player.possessions[i]);
1690 : 0 : Player.possessions[i] = NULL;
1691 : : }
1692 [ # # ]: 0 : for(i=0;i<MAXPACK;i++) {
1693 [ # # ]: 0 : if (Player.pack[i] != NULL)
1694 : 0 : free_obj( Player.pack[i], TRUE );
1695 : 0 : Player.pack[i] = NULL;
1696 : : }
1697 : 0 : Player.packptr = 0;
1698 : 0 : calc_melee();
1699 : 0 : morewait();
1700 : 0 : }
1701 : :
1702 : :
1703 : : /* prevents people from wielding 3 short swords, etc. */
1704 : 0 : void pack_extra_items(pob item)
1705 : : {
1706 : 0 : pob extra=copy_obj( item );
1707 : 0 : extra->number = item->number-1;
1708 : 0 : extra->used = FALSE;
1709 : 0 : item->number = 1;
1710 [ # # ]: 0 : if (Player.packptr < MAXPACK) {
1711 : 0 : print3("Putting extra items back in pack.");
1712 : 0 : morewait();
1713 : 0 : push_pack(extra);
1714 : : }
1715 [ # # ]: 0 : else if (Player.possessions[O_UP_IN_AIR] == NULL) {
1716 : 0 : print3("Extra copies of item are 'up in the air'");
1717 : 0 : Player.possessions[O_UP_IN_AIR] = extra;
1718 : : }
1719 : : else {
1720 : 0 : print3("No room for extra copies of item -- dropping them.");
1721 : 0 : drop_at(Player.x,Player.y,extra);
1722 : : }
1723 : 0 : calc_melee();
1724 : 0 : }
1725 : :
1726 : :
1727 : : /* makes sure Player.pack is OK, (used after sale from pack) */
1728 : 0 : void fixpack(void)
1729 : : {
1730 : : pob tpack[MAXPACK];
1731 : 0 : int i,tctr=0;
1732 [ # # ]: 0 : for(i=0;i<MAXPACK;i++) tpack[i] = NULL;
1733 [ # # ]: 0 : for(i=0;i<MAXPACK;i++)
1734 [ # # ]: 0 : if (Player.pack[i]!=NULL)
1735 : 0 : tpack[tctr++] = Player.pack[i];
1736 [ # # ]: 0 : for(i=0;i<MAXPACK;i++)
1737 : 0 : Player.pack[i]=tpack[i];
1738 : 0 : Player.packptr = tctr;
1739 : 0 : }
1740 : :
1741 : :
1742 : : /* show slots, with appropriate additional displays if two-handed weapons */
1743 : : /* are involved */
1744 : 23 : void show_inventory_slot(int slotnum, int topline)
1745 : : {
1746 [ + - ]: 23 : if (!topline)
1747 [ - + ][ # # ]: 23 : if (Player.possessions[O_READY_HAND] == Player.possessions[O_WEAPON_HAND] &&
1748 [ # # ]: 0 : (slotnum == O_READY_HAND || slotnum == O_WEAPON_HAND))
1749 : : {
1750 : 0 : display_inventory_slot(O_READY_HAND, topline);
1751 : 0 : display_inventory_slot(O_WEAPON_HAND, topline);
1752 : : }
1753 [ + + ]: 30 : else if (slotnum == O_UP_IN_AIR && Player.possessions[O_UP_IN_AIR] &&
[ + + - + ]
1754 : 7 : twohandedp(Player.possessions[O_UP_IN_AIR]->id))
1755 : : {
1756 : 0 : display_inventory_slot(O_READY_HAND, topline);
1757 : 0 : display_inventory_slot(O_WEAPON_HAND, topline);
1758 : 0 : display_inventory_slot(slotnum, topline);
1759 : : }
1760 : : else
1761 : 23 : display_inventory_slot(slotnum, topline);
1762 : : else
1763 : 0 : display_inventory_slot(slotnum, topline);
1764 : 23 : }
|