LCOV - code coverage report
Current view: top level - omega-rpg-0.90-pa9 - inv.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 326 1057 30.8 %
Date: 2017-09-08 22:00:26 Functions: 29 59 49.2 %
Branches: 173 775 22.3 %

           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                 :          1 : pob detach_money(long howmuch)
      44                 :            : /* if howmuch == 0, ask the player. otherwise, just get howmuch. */
      45                 :            : {
      46                 :            :   long c;
      47                 :          1 :   pob cash=NULL;
      48         [ +  - ]:          1 :   if ( howmuch == 0 )
      49                 :          1 :   c = get_money(Player.cash);
      50                 :            :   else
      51                 :          0 :     c = howmuch;
      52         [ +  - ]:          1 :   if (c != ABORT) {
      53                 :          1 :     Player.cash -= c;
      54                 :          1 :     cash = ((pob) checkmalloc(sizeof(objtype)));
      55                 :          1 :     make_cash(cash,difficulty());
      56                 :          1 :     cash->basevalue = c;
      57                 :            :   }
      58                 :          1 :   return(cash);
      59                 :            : }
      60                 :            : 
      61                 :            : 
      62                 :            : /* gets a legal amount of money or ABORT */
      63                 :          1 : long get_money(long limit)
      64                 :            : {
      65                 :            :   long c;
      66                 :          1 :   c = parsenum("How much money? ");
      67         [ -  + ]:          1 :   if (c > limit) {
      68                 :          0 :     print3("Forget it, buddy.");
      69                 :          0 :     return(ABORT);
      70                 :            :   }
      71                 :          1 :   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                 :          3 : void pickup_at (int x, int y)
      80                 :            : {
      81                 :          3 :   char response = 0;
      82                 :            : 
      83                 :            :   pol ol;
      84                 :            :   pol temp;
      85                 :            : 
      86                 :          3 :   resetgamestatus(FAST_MOVE);
      87                 :            : 
      88                 :          3 :   ol = Level->site[x][y].things;
      89                 :          3 :   Level->site[x][y].things = 0;
      90                 :            : 
      91         [ +  + ]:         10 :   while (ol != 0)
      92                 :            :     {
      93         [ +  - ]:          7 :       if(response != 'q') {
      94                 :          7 :         clearmsg1();
      95                 :          7 :         response = cinema_ynq(strjoin("Pick up: ", itemid(ol->thing)));
      96                 :            :       }
      97                 :            : 
      98         [ +  + ]:          7 :       if (response == 'y')
      99                 :          3 :         gain_item(ol->thing);
     100                 :            :       else
     101                 :          4 :         drop_at(x,y,ol->thing);
     102                 :            : 
     103                 :          7 :       temp = ol;
     104                 :          7 :       ol = ol->next;
     105                 :          7 :       temp->next = 0;
     106                 :          7 :       temp->thing = 0;
     107                 :          7 :       free(temp);
     108                 :            :     }
     109                 :          3 : }
     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                 :         11 : 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         [ +  - ]:         47 :   for (i=0; i<MAXITEMS; i++) {
     125         [ +  + ]:         47 :     if (key == inventory_keymap[i])
     126                 :         11 :       return (signed char)i;
     127                 :            :   }
     128                 :          0 :   return O_UP_IN_AIR;
     129                 :            : }
     130                 :            : 
     131                 :        321 : signed char index_to_key(signed int index)
     132                 :            : {
     133         [ +  - ]:        321 :   if ( index < MAXITEMS )
     134                 :        321 :     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                 :          6 : void drop_at(int x, int y, pob o)
     176                 :            : {
     177                 :            :   pol tmp;
     178                 :            :   pob cpy; 
     179                 :            :   
     180         [ +  - ]:          6 :   if (Current_Environment != E_COUNTRYSIDE) {
     181 [ +  - ][ +  - ]:          6 :     if ((Level->site[x][y].locchar != VOID_CHAR) &&
     182                 :          6 :         (Level->site[x][y].locchar != ABYSS)) {
     183                 :          6 :       cpy = copy_obj( o );
     184                 :          6 :       tmp = ((pol) checkmalloc(sizeof(oltype)));
     185                 :          6 :       cpy->used = FALSE;
     186                 :          6 :       tmp->thing = cpy;
     187                 :          6 :       tmp->next = Level->site[x][y].things;
     188                 :          6 :       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                 :          6 : }  
     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                 :        274 : char *itemid(pob obj)
     220                 :            : {
     221                 :            :   char tstr[80];
     222         [ -  + ]:        274 :   if (obj->objchar==CASH){
     223                 :          0 :     strcpy(Str4,obj->truename);
     224                 :          0 :     return(Str4);
     225                 :            :   }
     226                 :            :   else {
     227         [ -  + ]:        274 :     if (Objects[obj->id].known > obj->known)
     228                 :          0 :       obj->known = Objects[obj->id].known;
     229                 :            :     
     230                 :        274 :     setnumstr(obj,tstr);
     231                 :        274 :     strcpy(Str4,tstr);
     232         [ +  + ]:        274 :     if (obj->known == 0)
     233                 :        133 :       strcat(Str4,obj->objstr);
     234         [ +  + ]:        141 :     else if (obj->known == 1) {
     235 [ +  - ][ +  - ]:         18 :       if (obj->id == OB_YENDOR || obj->id == OB_KARNAK ||
                 [ -  + ]
     236                 :         18 :         obj->id == OB_STARGEM )
     237                 :          0 :         strcat(Str4, "the ");
     238                 :         18 :       strcat(Str4,obj->truename);
     239                 :            :     }
     240                 :            :     else {
     241 [ +  - ][ +  - ]:        123 :       if (obj->id == OB_YENDOR || obj->id == OB_KARNAK ||
                 [ -  + ]
     242                 :        123 :         obj->id == OB_STARGEM )
     243                 :          0 :         strcat(Str4, "the ");
     244 [ -  + ][ #  # ]:        123 :       if (obj->usef == I_NOTHING && Objects[obj->id].usef != I_NOTHING)
     245                 :          0 :         strcat(Str4, "disenchanted ");
     246         [ +  + ]:        123 :       if (obj->blessing < 0) {
     247                 :         18 :         strcat(Str4, "cursed ");
     248                 :         18 :         strcat(Str4, obj->cursestr);
     249                 :            :       }
     250         [ +  + ]:        105 :       else if (obj->blessing > 0) {
     251                 :          9 :         strcat(Str4, "blessed ");
     252                 :          9 :         strcat(Str4, obj->truename);
     253                 :            :       }
     254                 :         96 :       else strcat(Str4,obj->truename);
     255         [ -  + ]:        123 :       if (obj->number > 1) strcat(Str4,"s");
     256      [ +  +  + ]:        123 :       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                 :         40 :         setplustr(obj,tstr);
     267                 :         40 :         strcat(Str4, tstr);
     268                 :         40 :         break;
     269                 :         80 :       default: strcat(Str4,""); break;
     270                 :            :       }
     271                 :            :     }
     272                 :        274 :     return(Str4);
     273                 :            :   }
     274                 :            : }
     275                 :            : 
     276                 :          1 : char *cashstr(void)
     277                 :            : {
     278         [ -  + ]:          1 :   if (difficulty() < 3) return("copper pieces");
     279         [ -  + ]:          1 :   else if (difficulty() < 5) return("silver pieces");
     280         [ -  + ]:          1 :   else if (difficulty() < 7) return("gold pieces");
     281         [ +  - ]:          1 :   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                 :         40 : void setplustr(pob obj, char *pstr)
     289                 :            : {
     290                 :         40 :   pstr[0] = ' ';
     291         [ +  + ]:         40 :   pstr[1] = (obj->plus < 0 ? '-' : '+' );
     292 [ +  - ][ +  - ]:         40 :   if (abs(obj->plus) < 10) {
     293                 :         40 :     pstr[2] = '0' + abs(obj->plus);
     294                 :         40 :     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                 :         40 : }
     302                 :            : 
     303                 :            : /* return an object's number as a string */
     304                 :        274 : void setnumstr(pob obj, char *nstr)
     305                 :            : {
     306         [ +  + ]:        274 :   if (obj->number < 2)
     307                 :        236 :     nstr[0] = 0;
     308         [ +  - ]:         38 :   else if (obj->number < 10) {
     309                 :         38 :     nstr[0] = '0' + obj->number;
     310                 :         38 :     nstr[1] = 'x';
     311                 :         38 :     nstr[2] = ' ';
     312                 :         38 :     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                 :        274 : }
     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                 :          1 : void give_money(struct monster *m)
     353                 :            : {
     354                 :            :   pob cash;
     355                 :            : 
     356                 :          1 :   cash = detach_money(0);
     357         [ -  + ]:          1 :   if (cash == NULL)
     358                 :          0 :     setgamestatus(SKIP_MONSTERS);
     359                 :          1 :   else givemonster(m,cash);
     360                 :          1 : }
     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                 :          1 : void givemonster(pmt m, pob o)
     387                 :            : {
     388                 :            :   /* special case -- give gem to LawBringer */
     389 [ -  + ][ #  # ]:          1 :   if ((m->id == LAWBRINGER) && (o->id == OB_STARGEM)) 
     390                 :          0 :     lawbringer_gets_gem(m,o);
     391                 :            :   else {
     392         [ +  - ]:          1 :     if (m->uniqueness == COMMON) {
     393                 :          1 :       strcpy(Str3,"The ");
     394                 :          1 :       strcat(Str3,m->monstring);
     395                 :            :     }
     396                 :          0 :     else strcpy(Str3,m->monstring);
     397                 :            :     
     398 [ +  - ][ +  - ]:          1 :     if (m_statusp(m,GREEDY) || m_statusp(m,NEEDY)) {
     399                 :          1 :       m_pickup(m,o);
     400                 :          1 :       strcat(Str3," takes your gift");
     401                 :          1 :       print1(Str3);
     402                 :          1 :       Player.alignment++;
     403 [ -  + ][ #  # ]:          2 :       if (m_statusp(m,GREEDY) && (true_item_value(o) < (long) m->level*100))
     404                 :          0 :       nprint1("...but does not appear satisfied.");
     405   [ +  -  -  + ]:          2 :       else if (m_statusp(m,NEEDY) && 
     406                 :          1 :                (true_item_value(o) < (long) Level->depth*Level->depth))
     407                 :          0 :         nprint1("...and looks chasteningly at you.");
     408                 :            :       else {
     409                 :          1 :         nprint1("...and seems happy with it.");
     410                 :          1 :         m_status_reset(m,HOSTILE);
     411                 :          1 :         m_status_reset(m,GREEDY);
     412                 :          1 :         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                 :          1 : }
     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                 :          5 : void dispose_lost_objects(int n, pob obj)
     462                 :            : {
     463                 :          5 :   int i,conformed=FALSE,subtracted=FALSE;
     464                 :            : 
     465         [ -  + ]:          5 :   if (obj == NULL)
     466                 :          0 :     return;
     467         [ +  + ]:         85 :   for(i=0;i<MAXITEMS;i++) 
     468         [ +  + ]:         80 :     if (Player.possessions[i] == obj) {
     469         [ +  - ]:          5 :       if (! subtracted) {
     470                 :          5 :         obj->number -= n;
     471                 :          5 :         subtracted = TRUE;
     472                 :            :       }
     473         [ +  + ]:          5 :       if (obj->number < 1) {
     474         [ +  - ]:          4 :         if (!conformed) {
     475                 :          4 :           conform_unused_object(obj);
     476                 :          4 :           conformed = TRUE;
     477                 :            :         }
     478                 :          4 :         Player.possessions[i] = NULL;
     479                 :            :       }
     480                 :            :     }
     481         [ +  + ]:          5 :   if (obj->number < 1)
     482                 :          4 :     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                 :          0 : void conform_lost_objects(int n, pob obj)
     489                 :            : {
     490                 :          0 :   int i,conformed=FALSE,subtracted=FALSE;
     491 [ #  # ][ #  # ]:          0 :   if (obj != NULL) for(i=0;i<MAXITEMS;i++) 
     492         [ #  # ]:          0 :     if (Player.possessions[i] == obj) {
     493         [ #  # ]:          0 :       if (! subtracted) {
     494                 :          0 :         obj->number -= n;
     495                 :          0 :         subtracted = TRUE;
     496                 :            :       }
     497         [ #  # ]:          0 :       if (obj->number < 1) {
     498         [ #  # ]:          0 :         if (!conformed) {
     499                 :          0 :           conform_unused_object(obj);
     500                 :          0 :           conformed = TRUE;
     501                 :            :         }
     502                 :          0 :         Player.possessions[i] = NULL;
     503                 :            :       }
     504                 :            :     }
     505                 :          0 : }
     506                 :            : 
     507                 :            : 
     508                 :            : /* clears unused possession */
     509                 :          5 : void conform_unused_object(pob obj)
     510                 :            : {
     511         [ -  + ]:          5 :   if (obj->used) {
     512                 :          0 :     obj->used = FALSE;
     513                 :          0 :     item_use(obj);
     514                 :          0 :     inv_display_munge();
     515                 :            :   }
     516                 :          5 :   calc_melee();
     517                 :          5 : }
     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                 :        195 : int item_is_selectable (Symbol itype, struct object * item)
     529                 :            : {
     530         [ +  + ]:        195 :   if (!item) return FALSE;
     531                 :            : 
     532         [ +  + ]:         90 :   if (CASH == itype) return TRUE;
     533         [ +  + ]:         82 :   if (NULL_ITEM == itype) return TRUE;
     534         [ +  + ]:         26 :   if (item->objchar == itype) return TRUE;
     535 [ +  + ][ -  + ]:         17 :   if (FOOD == itype && CORPSE == item->objchar) return TRUE;
     536                 :            : 
     537                 :         17 :   return FALSE;
     538                 :            : }
     539                 :            : 
     540                 :          1 : int getitem (Symbol itype)
     541                 :            : {
     542                 :          1 :   return getitem_prompt(0, itype);
     543                 :            : }
     544                 :            : 
     545                 :          8 : 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                 :          8 :   int found = FALSE;
     554                 :          8 :   int drewmenu = FALSE;
     555                 :            : 
     556 [ +  + ][ +  + ]:          8 :   found = ((itype == NULL_ITEM) || ((itype == CASH) && (Player.cash > 0)));
                 [ +  - ]
     557                 :            : 
     558                 :            :   /* build invstr, which lists all valid selections that the user can make */
     559                 :          8 :   invstr[0] = 0;
     560                 :            : 
     561                 :          8 :   k = 0;
     562         [ +  + ]:        128 :   for(i = 1; i < MAXITEMS; ++i)
     563                 :            :     {
     564         [ +  + ]:        120 :       if (item_is_selectable(itype, Player.possessions[i]))
     565                 :            :         {
     566                 :         42 :           found = TRUE;
     567                 :         42 :           invstr[k++] = index_to_key(i);
     568                 :         42 :           invstr[k] = 0;
     569                 :            :         }
     570                 :            :     }
     571                 :            : 
     572         [ -  + ]:          8 :   if (!found)
     573                 :            :     {
     574                 :          0 :       print3("Nothing appropriate.");
     575                 :          0 :       return ABORT;
     576                 :            :     }
     577                 :            : 
     578         [ +  + ]:          8 :   if (itype == CASH)
     579                 :            :     {
     580                 :          1 :       invstr[k++] = CASH & 0xff;
     581                 :          1 :       invstr[k] = 0;
     582                 :            :     }
     583                 :            : 
     584                 :            :   /* gotta let the user see what everything means... */
     585                 :          8 :   invstr[k++] = '?';
     586                 :          8 :   invstr[k] = 0;
     587                 :            : 
     588                 :          8 :   line3 = NULL;
     589                 :            : 
     590                 :            :   /* build prompt... */
     591                 :          8 :   selectstr[0] = 0;
     592         [ +  + ]:          8 :   if (prompt) strcpy(selectstr, prompt);
     593                 :          8 :   strcat(selectstr, "Select an item. (");
     594                 :            : 
     595                 :          8 :   i = 0;
     596                 :          8 :   k = strlen(selectstr);
     597                 :            :   while (TRUE)
     598                 :            :     {
     599         [ +  + ]:         51 :       if ('?' == invstr[i]) break;
     600                 :         43 :       selectstr[k++] = invstr[i++];
     601                 :         43 :       selectstr[k++] = ',';
     602         [ -  + ]:         43 :       if (k > 75) break;
     603                 :         43 :     }
     604                 :            : 
     605                 :          8 :   selectstr[k-1] = ')';
     606                 :          8 :   selectstr[k] = 0;
     607                 :            : 
     608                 :            :   /* get input from the user */
     609                 :            :   do
     610                 :            :     {
     611                 :         13 :       again = FALSE;
     612                 :            : 
     613                 :         13 :       key = cinema_interact(invstr, selectstr, "  ? to display items", line3);
     614                 :         13 :       line3 = NULL;
     615                 :            : 
     616         [ +  + ]:         13 :       if ('?' == key)
     617                 :            :         {
     618                 :          5 :           again = TRUE;
     619                 :          5 :           drewmenu = TRUE;
     620         [ +  + ]:         80 :           for (i = 1; i < MAXITEMS; ++i)
     621                 :            :             {
     622         [ +  + ]:         75 :               if (item_is_selectable(itype, Player.possessions[i]))
     623                 :         31 :                 display_inventory_slot(i, FALSE);
     624                 :            :             }
     625                 :            :         }
     626 [ +  + ][ -  + ]:          8 :       else if ((CASH & 0xff) == key && (CASH != itype))
     627                 :            :         {
     628                 :          0 :           again = TRUE;
     629                 :          0 :           line3 = "You cannot select cash now.";
     630                 :            :         }
     631                 :            :     }
     632         [ +  + ]:         13 :   while (again);
     633                 :            : 
     634         [ +  + ]:          8 :   if (drewmenu) xredraw();
     635         [ -  + ]:          8 :   if (-1 == key) return ABORT; /* cinema_interact() returns -1 for ESC */
     636         [ +  + ]:          8 :   if ((CASH & 0xff) == key) return CASHVALUE;
     637                 :            : 
     638                 :          8 :   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                 :          7 : void do_inventory_control(void)
     939                 :            : {
     940         [ -  + ]:          7 :   if (optionp(TOPINV)) top_inventory_control();
     941                 :            :   else {
     942                 :          7 :     menuclear();
     943                 :          7 :     display_possessions();
     944                 :          7 :     inventory_control();
     945                 :            :   }
     946                 :          7 : }
     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                 :          7 : void inventory_control(void)
     953                 :            : {
     954                 :          7 :   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                 :          7 :   inv_display_munge();
     962                 :          7 :   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                 :          1 :       switch_to_slot(slot);
    1048                 :          1 :       show_inventory_slot(O_UP_IN_AIR,FALSE);
    1049                 :          1 :       show_inventory_slot(slot,FALSE);
    1050                 :          1 :       Command_Duration+=2;
    1051                 :          1 :       done = (Player.possessions[O_UP_IN_AIR] == NULL);
    1052                 :          1 :       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         [ +  + ]:          6 :       if (Player.possessions[O_UP_IN_AIR] != NULL) {
    1103                 :          1 :         drop_at(Player.x,Player.y,Player.possessions[O_UP_IN_AIR]);
    1104                 :          1 :         Player.possessions[O_UP_IN_AIR] = NULL;
    1105                 :          1 :         print3("Object 'up in air' dropped.");
    1106                 :            :       }
    1107                 :          6 :       done = TRUE;
    1108                 :          6 :       break;
    1109                 :            :     default:
    1110         [ +  - ]:          2 :       if (key_to_index(response) > 0) {
    1111                 :          2 :         slot = move_slot(slot,key_to_index(response),MAXITEMS);
    1112         [ +  - ]:          2 :         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                 :          2 :           switch_to_slot(slot);
    1120                 :          2 :           show_inventory_slot(slot,FALSE);
    1121                 :          2 :           slot = O_UP_IN_AIR;
    1122                 :          2 :           show_inventory_slot(slot,FALSE);
    1123                 :          2 :           Command_Duration+=2;
    1124                 :            :         }
    1125                 :            :       }
    1126                 :            :     }
    1127                 :          9 :     calc_melee();
    1128         [ +  + ]:          9 :   } while (! done);
    1129                 :          7 :   xredraw();
    1130                 :          7 : }
    1131                 :            : 
    1132                 :            : 
    1133                 :            : /* Make it clear that the inventory window mmust be redrawn. */
    1134                 :            : static int inv_must_redraw;
    1135                 :          7 : static void inv_display_munge(void)
    1136                 :            : {
    1137                 :          7 :    inv_must_redraw = TRUE;
    1138                 :          7 : }
    1139                 :            : 
    1140                 :          9 : static void inv_display_refresh(void)
    1141                 :            : {
    1142         [ +  + ]:          9 :   if ( inv_must_redraw )
    1143                 :          7 :     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                 :          3 : void switch_to_slot(int slot)
    1379                 :            : {
    1380                 :          3 :   pob oslot = Player.possessions[slot];
    1381                 :          3 :   pob oair = Player.possessions[O_UP_IN_AIR];
    1382                 :          3 :   pob otemp = NULL;
    1383                 :          3 :   int slotnull,airnull,num=1,trade=FALSE,put=FALSE,take=FALSE,merge=FALSE;
    1384                 :          3 :   int s2h=FALSE,a2h=FALSE;
    1385                 :            : 
    1386                 :            :   /* ie, is cursed and in use */
    1387         [ +  + ]:          3 :   if (slot == O_UP_IN_AIR)
    1388                 :          1 :     print3("This action makes no sense!");
    1389         [ -  + ]:          2 :   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                 :          2 :     slotnull = (oslot == NULL); 
    1395                 :          2 :     airnull = (oair == NULL);
    1396                 :            : 
    1397         [ -  + ]:          2 :     if  (!slotnull)
    1398                 :          0 :       s2h = (Player.possessions[O_READY_HAND] ==
    1399                 :          0 :              Player.possessions[O_WEAPON_HAND]);
    1400                 :            :     
    1401         [ +  - ]:          2 :     if (! airnull)
    1402 [ -  + ][ #  # ]:          2 :       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                 :          2 :     merge = objequal(oslot,oair);
    1410                 :            : 
    1411 [ +  - ][ -  + ]:          2 :     take = ((!merge) && (!slotnull) && airnull);
                 [ #  # ]
    1412                 :            :     
    1413 [ +  - ][ +  - ]:          2 :     put = ((!merge) && slotnull && (!airnull) && slottable(oair,slot));
         [ +  - ][ +  - ]
    1414                 :            :     
    1415 [ +  - ][ -  + ]:          2 :     trade = ((!merge) && (!slotnull) && (!airnull) && slottable(oair,slot));
         [ #  # ][ #  # ]
    1416                 :            : 
    1417         [ -  + ]:          2 :     if (merge) merge_item(slot);
    1418                 :            : 
    1419         [ +  - ]:          2 :     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         [ #  # ]:          0 :     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         [ #  # ]:          0 :     else if (trade) {
    1456                 :            :       
    1457                 :            :       /* first remove item from slot */
    1458                 :          0 :       num = oslot->number;
    1459                 :          0 :       conform_lost_objects(oslot->number,oslot);
    1460                 :          0 :       oslot->number = num;
    1461                 :            :       
    1462                 :          0 :       Player.possessions[O_UP_IN_AIR] = oslot;
    1463                 :            : 
    1464                 :          0 :       Player.possessions[slot] = oair;
    1465                 :            : 
    1466         [ #  # ]:          0 :       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         [ #  # ]:          0 :       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         [ #  # ]:          0 :       if (item_useable(oair,slot)) {
    1481                 :          0 :         oair->used = TRUE;
    1482                 :          0 :         item_use(oair);
    1483                 :          0 :         inv_display_munge();
    1484                 :          0 :         morewait();
    1485         [ #  # ]:          0 :         if (oair->number > 1) pack_extra_items(oair);
    1486                 :            :       }
    1487                 :            :     }
    1488                 :            :   }
    1489                 :          3 : }
    1490                 :            : 
    1491                 :            : 
    1492                 :            : 
    1493                 :            : 
    1494                 :            : /* merges the up-in-air items into the selected items */
    1495                 :            : 
    1496                 :          0 : void merge_item(int slot)
    1497                 :            : {
    1498                 :          0 :   Player.possessions[slot]->number +=
    1499                 :          0 :     Player.possessions[O_UP_IN_AIR]->number;
    1500                 :          0 :   Player.possessions[O_UP_IN_AIR] = NULL;
    1501                 :          0 : }
    1502                 :            : 
    1503                 :            : 
    1504                 :            : /* are two objects equal except for their number field? */
    1505                 :            : /* returns false if either object is null */
    1506                 :          2 : int objequal(pob o, pob p)
    1507                 :            : {
    1508 [ -  + ][ #  # ]:          2 :   if ((o == NULL) || (p == NULL)) return(FALSE);
    1509                 :          0 :   else return(
    1510         [ #  # ]:          0 :          (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         [ #  # ]:          0 :          (o->id != CORPSEID) &&
    1514         [ #  # ]:          0 :          (o->plus == p->plus) &&
    1515         [ #  # ]:          0 :          (o->charge == 0) &&
    1516         [ #  # ]:          0 :          (p->charge == 0) &&
    1517         [ #  # ]:          0 :          (o->dmg == p->dmg) &&
    1518         [ #  # ]:          0 :          (o->hit == p->hit) &&
    1519         [ #  # ]:          0 :          (o->aux == p->aux) &&
    1520         [ #  # ]:          0 :          (o->known == p->known) &&
    1521         [ #  # ]:          0 :          (o->blessing == p->blessing) &&
    1522 [ #  # ][ #  # ]:          0 :          (o->usef == p->usef) &&
    1523                 :          0 :          (o->objstr == p->objstr )
    1524                 :            :          );
    1525                 :            : 
    1526                 :            : }
    1527                 :            : 
    1528                 :            : /* criteria for being able to put some item in some slot */
    1529                 :          2 : int slottable(pob o, int slot)
    1530                 :            : {
    1531                 :          2 :   int ok = TRUE;
    1532         [ -  + ]:          2 :   if (o == NULL) ok = FALSE;
    1533         [ -  + ]:          2 :   else if (slot == O_ARMOR) {
    1534         [ #  # ]:          0 :     if (o->objchar != ARMOR) {
    1535                 :          0 :       print3("Only armor can go in the armor slot!");
    1536                 :          0 :       ok = FALSE;
    1537                 :            :     }
    1538                 :            :   }
    1539         [ -  + ]:          2 :   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         [ -  + ]:          2 :   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         [ -  + ]:          2 :   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         [ -  + ]:          2 :   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                 :          2 :   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                 :          2 : 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 [ +  - ][ +  - ]:          2 :   if ((slot == O_ARMOR) || 
    1575         [ +  - ]:          2 :       (slot == O_CLOAK) ||
    1576         [ +  - ]:          2 :       (slot == O_SHIELD) ||
    1577         [ -  + ]:          2 :       (slot == O_BOOTS) ||
    1578                 :            :       (slot >= O_RING1))
    1579                 :          0 :     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 [ +  + ][ -  + ]:          2 :   else if ((o->objchar == WEAPON) ||
    1585                 :          1 :            (o->objchar == MISSILEWEAPON)) {
    1586 [ -  + ][ #  # ]:          1 :     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                 :          1 :     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                 :          6 : int cursed(pob obj)
    1610                 :            : {
    1611                 :          6 :   return((obj == NULL) ? 
    1612         [ +  + ]:         10 :          FALSE : 
    1613                 :          4 :          ((obj->blessing < 0) ? 
    1614 [ -  + ][ #  # ]:          4 :           (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                 :         15 : void show_inventory_slot(int slotnum, int topline)
    1745                 :            : {
    1746         [ +  - ]:         15 :   if (!topline)
    1747 [ -  + ][ #  # ]:         15 :     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         [ +  + ]:         18 :     else if (slotnum == O_UP_IN_AIR && Player.possessions[O_UP_IN_AIR] &&
           [ +  +  -  + ]
    1754                 :          3 :       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                 :         15 :       display_inventory_slot(slotnum, topline);
    1762                 :            :   else
    1763                 :          0 :     display_inventory_slot(slotnum, topline);
    1764                 :         15 : }

Generated by: LCOV version 1.11