Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

act_obj.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
00003  *  Michael Seifert, Hans Henrik Strfeldt, Tom Madsen, and Katja Nyboe.    *
00004  *                                                                         *
00005  *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
00006  *  Chastain, Michael Quan, and Mitchell Tse.                              *
00007  *                                                                         *
00008  *  In order to use any part of this Merc Diku Mud, you must comply with   *
00009  *  both the original Diku license in 'license.doc' as well the Merc       *
00010  *  license in 'license.txt'.  In particular, you may not remove either of *
00011  *  these copyright notices.                                               *
00012  *                                                                         *
00013  *  Much time and thought has gone into this software and you are          *
00014  *  benefitting.  We hope that you share your changes too.  What goes      *
00015  *  around, comes around.                                                  *
00016  **************************************************************************/
00017 
00018 /***************************************************************************
00019  *   ROM 2.4 is copyright 1993-1998 Russ Taylor                            *
00020  *   ROM has been brought to you by the ROM consortium                     *
00021  *       Russ Taylor (rtaylor@hypercube.org)                               *
00022  *       Gabrielle Taylor (gtaylor@hypercube.org)                          *
00023  *       Brian Moore (zump@rom.org)                                        *
00024  *   By using this code, you have agreed to follow the terms of the        *
00025  *   ROM license, in the file Rom24/doc/rom.license                        *
00026  **************************************************************************/
00027 
00028 /*   QuickMUD - The Lazy Man's ROM - $Id: act_obj.c,v 1.2 2000/12/01 10:48:33 ring0 Exp $ */
00029 
00030 #if defined(macintosh)
00031 #include <types.h>
00032 #include <time.h>
00033 #else
00034 #include <sys/types.h>
00035 #include <sys/time.h>
00036 #endif
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include <stdlib.h>
00040 #include "merc.h"
00041 #include "interp.h"
00042 
00043 /*
00044  * Local functions.
00045  */
00046 #define CD CHAR_DATA
00047 #define OD OBJ_DATA
00048 bool remove_obj args ((CHAR_DATA * ch, int iWear, bool fReplace));
00049 void wear_obj args ((CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace));
00050 CD *find_keeper args ((CHAR_DATA * ch));
00051 int get_cost args ((CHAR_DATA * keeper, OBJ_DATA * obj, bool fBuy));
00052 void obj_to_keeper args ((OBJ_DATA * obj, CHAR_DATA * ch));
00053 OD *get_obj_keeper
00054 args ((CHAR_DATA * ch, CHAR_DATA * keeper, char *argument));
00055 
00056 #undef OD
00057 #undef    CD
00058 
00059 /* RT part of the corpse looting code */
00060 
00061 bool can_loot (CHAR_DATA * ch, OBJ_DATA * obj)
00062 {
00063     CHAR_DATA *owner, *wch;
00064 
00065     if (IS_IMMORTAL (ch))
00066         return TRUE;
00067 
00068     if (!obj->owner || obj->owner == NULL)
00069         return TRUE;
00070 
00071     owner = NULL;
00072     for (wch = char_list; wch != NULL; wch = wch->next)
00073         if (!str_cmp (wch->name, obj->owner))
00074             owner = wch;
00075 
00076     if (owner == NULL)
00077         return TRUE;
00078 
00079     if (!str_cmp (ch->name, owner->name))
00080         return TRUE;
00081 
00082     if (!IS_NPC (owner) && IS_SET (owner->act, PLR_CANLOOT))
00083         return TRUE;
00084 
00085     if (is_same_group (ch, owner))
00086         return TRUE;
00087 
00088     return FALSE;
00089 }
00090 
00091 
00092 void get_obj (CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * container)
00093 {
00094     /* variables for AUTOSPLIT */
00095     CHAR_DATA *gch;
00096     int members;
00097     char buffer[100];
00098 
00099     if (!CAN_WEAR (obj, ITEM_TAKE))
00100     {
00101         send_to_char ("You can't take that.\n\r", ch);
00102         return;
00103     }
00104 
00105     if (ch->carry_number + get_obj_number (obj) > can_carry_n (ch))
00106     {
00107         act ("$d: you can't carry that many items.",
00108              ch, NULL, obj->name, TO_CHAR);
00109         return;
00110     }
00111 
00112     if ((!obj->in_obj || obj->in_obj->carried_by != ch)
00113         && (get_carry_weight (ch) + get_obj_weight (obj) > can_carry_w (ch)))
00114     {
00115         act ("$d: you can't carry that much weight.",
00116              ch, NULL, obj->name, TO_CHAR);
00117         return;
00118     }
00119 
00120     if (!can_loot (ch, obj))
00121     {
00122         act ("Corpse looting is not permitted.", ch, NULL, NULL, TO_CHAR);
00123         return;
00124     }
00125 
00126     if (obj->in_room != NULL)
00127     {
00128         for (gch = obj->in_room->people; gch != NULL; gch = gch->next_in_room)
00129             if (gch->on == obj)
00130             {
00131                 act ("$N appears to be using $p.", ch, obj, gch, TO_CHAR);
00132                 return;
00133             }
00134     }
00135 
00136 
00137     if (container != NULL)
00138     {
00139         if (container->pIndexData->vnum == OBJ_VNUM_PIT
00140             && get_trust (ch) < obj->level)
00141         {
00142             send_to_char ("You are not powerful enough to use it.\n\r", ch);
00143             return;
00144         }
00145 
00146         if (container->pIndexData->vnum == OBJ_VNUM_PIT
00147             && !CAN_WEAR (container, ITEM_TAKE)
00148             && !IS_OBJ_STAT (obj, ITEM_HAD_TIMER))
00149             obj->timer = 0;
00150         act ("You get $p from $P.", ch, obj, container, TO_CHAR);
00151         act ("$n gets $p from $P.", ch, obj, container, TO_ROOM);
00152         REMOVE_BIT (obj->extra_flags, ITEM_HAD_TIMER);
00153         obj_from_obj (obj);
00154     }
00155     else
00156     {
00157         act ("You get $p.", ch, obj, container, TO_CHAR);
00158         act ("$n gets $p.", ch, obj, container, TO_ROOM);
00159         obj_from_room (obj);
00160     }
00161 
00162     if (obj->item_type == ITEM_MONEY)
00163     {
00164         
00165     
00166     //ch->silver += obj->value[0];
00167         //ch->gold += obj->value[1];
00168     check_tithe(ch, obj->value[0], obj->value[1]);
00169         if (IS_SET (ch->act, PLR_AUTOSPLIT))
00170         {                        /* AUTOSPLIT code */
00171             members = 0;
00172             for (gch = ch->in_room->people; gch != NULL;
00173                  gch = gch->next_in_room)
00174             {
00175                 if (!IS_AFFECTED (gch, AFF_CHARM) && is_same_group (gch, ch))
00176                     members++;
00177             }
00178 
00179             if (members > 1 && (obj->value[0] > 1 || obj->value[1]))
00180             {
00181                 sprintf (buffer, "%d %d", obj->value[0], obj->value[1]);
00182                 do_function (ch, &do_split, buffer);
00183             }
00184         }
00185 
00186         extract_obj (obj);
00187     }
00188     else
00189     {
00190         obj_to_char (obj, ch);
00191     }
00192 
00193     return;
00194 }
00195 
00196 
00197 
00198 void do_second (CHAR_DATA *ch, char *argument)
00199 /* wear object as a secondary weapon */
00200 {
00201     OBJ_DATA *obj;
00202     char buf[MAX_STRING_LENGTH]; /* overkill, but what the heck */
00203         if (!IS_NPC (ch) && ch->level < skill_table[gsn_dual_wield].skill_level[ch->class])
00204     {
00205         send_to_char("Don't you think one weapon is enough for you?\n\r",ch);
00206         return;
00207     }
00208 
00209                 
00210 
00211     if (argument[0] == '\0') /* empty */
00212     {
00213         send_to_char ("Which weapon would you wish to dual wield with??\n\r",ch);
00214         return;
00215     }
00216 
00217     obj = get_obj_carry (ch, argument,ch); /* find the obj withing ch's inventory */
00218 
00219     if (obj == NULL)
00220     {
00221         send_to_char ("You own no such thing.\n\r",ch);
00222         return;
00223     }
00224 
00225 
00226     /* check if the char is using a shield or a held weapon */
00227 
00228     if ( (get_eq_char (ch,WEAR_SHIELD) != NULL))
00229     {
00230         send_to_char ("You cannot use a shield, and dual wield!\n\r",ch);
00231         return;
00232     }
00233 
00234 
00235     if ( ch->level < obj->level )
00236     {
00237         sprintf( buf, "You must be level %d to use this object.\n\r",
00238             obj->level );
00239         send_to_char( buf, ch );
00240         act( "$n tries to use $p, but is too inexperienced.",
00241             ch, obj, NULL, TO_ROOM );
00242         return;
00243     }
00244 
00245 /* check that the character is using a first weapon at all */
00246     if (get_eq_char (ch, WEAR_WIELD) == NULL) /* oops - != here was a bit wrong :) */
00247     {
00248         send_to_char ("You must be holding your primary weapon first!\n\r",ch);
00249         return;
00250     }
00251 
00252 
00253 /* check for str - secondary weapons have to be lighter */
00254  /*  if ( get_obj_weight( obj ) > ( str_app[get_curr_str(ch)].wield / 2) )
00255     {
00256         send_to_char( "This weapon is too heavy to be used as a secondary weapon by you.\n\r", ch );
00257         return;
00258     }
00259 */
00260 /* check if the secondary weapon is at least half as light as the primary weapon */
00261     if ( (get_obj_weight (obj)*2) > get_obj_weight(get_eq_char(ch,WEAR_WIELD)) )
00262     {
00263         send_to_char ("You cannot hold a weapon that weighs more then your primary.\n\r",ch);
00264         return;
00265     }
00266 
00267 /* at last - the char uses the weapon */
00268 
00269     if (!remove_obj(ch, WEAR_SECONDARY, TRUE)) /* remove the current weapon if any */
00270         return;                                /* remove obj tells about any no_remove */
00271 
00272 /* char CAN use the item! that didn't take long at aaall */
00273 
00274     act ("$n wields $p as a secondary weapon.",ch,obj,NULL,TO_ROOM);
00275     act ("You wield $p as a secondary weapon.",ch,obj,NULL,TO_CHAR);
00276     equip_char ( ch, obj, WEAR_SECONDARY);
00277     return;
00278 }
00279 
00280 /* in the wear_obj function, replace the shield and wield sections with this: */
00281 
00282 /* shield section */
00283    
00284 
00285 
00286 /* wield section */
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 void do_get (CHAR_DATA * ch, char *argument)
00298 {
00299     char arg1[MAX_INPUT_LENGTH];
00300     char arg2[MAX_INPUT_LENGTH];
00301     OBJ_DATA *obj;
00302     OBJ_DATA *obj_next;
00303     OBJ_DATA *container;
00304     bool found;
00305 
00306     argument = one_argument (argument, arg1);
00307     argument = one_argument (argument, arg2);
00308 
00309     if (!str_cmp (arg2, "from"))
00310         argument = one_argument (argument, arg2);
00311 
00312     /* Get type. */
00313     if (arg1[0] == '\0')
00314     {
00315         send_to_char ("Get what?\n\r", ch);
00316         return;
00317     }
00318 
00319     if (arg2[0] == '\0')
00320     {
00321         if (str_cmp (arg1, "all") && str_prefix ("all.", arg1))
00322         {
00323             /* 'get obj' */
00324             obj = get_obj_list (ch, arg1, ch->in_room->contents);
00325             if (obj == NULL)
00326             {
00327                 act ("I see no $T here.", ch, NULL, arg1, TO_CHAR);
00328                 return;
00329             }
00330 
00331             get_obj (ch, obj, NULL);
00332         }
00333         else
00334         {
00335             /* 'get all' or 'get all.obj' */
00336             found = FALSE;
00337             for (obj = ch->in_room->contents; obj != NULL; obj = obj_next)
00338             {
00339                 obj_next = obj->next_content;
00340                 if ((arg1[3] == '\0' || is_name (&arg1[4], obj->name))
00341                     && can_see_obj (ch, obj))
00342                 {
00343                     found = TRUE;
00344                     get_obj (ch, obj, NULL);
00345                 }
00346             }
00347 
00348             if (!found)
00349             {
00350                 if (arg1[3] == '\0')
00351                     send_to_char ("I see nothing here.\n\r", ch);
00352                 else
00353                     act ("I see no $T here.", ch, NULL, &arg1[4], TO_CHAR);
00354             }
00355         }
00356     }
00357     else
00358     {
00359         /* 'get ... container' */
00360         if (!str_cmp (arg2, "all") || !str_prefix ("all.", arg2))
00361         {
00362             send_to_char ("You can't do that.\n\r", ch);
00363             return;
00364         }
00365 
00366         if ((container = get_obj_here (ch, arg2)) == NULL)
00367         {
00368             act ("I see no $T here.", ch, NULL, arg2, TO_CHAR);
00369             return;
00370         }
00371 
00372         switch (container->item_type)
00373         {
00374             default:
00375                 send_to_char ("That's not a container.\n\r", ch);
00376                 return;
00377 
00378             case ITEM_CONTAINER:
00379             case ITEM_CORPSE_NPC:
00380                 break;
00381 
00382             case ITEM_CORPSE_PC:
00383                 {
00384 
00385                     if (!can_loot (ch, container))
00386                     {
00387                         send_to_char ("You can't do that.\n\r", ch);
00388                         return;
00389                     }
00390                 }
00391         }
00392 
00393         if (IS_SET (container->value[1], CONT_CLOSED))
00394         {
00395             act ("The $d is closed.", ch, NULL, container->name, TO_CHAR);
00396             return;
00397         }
00398 
00399         if (str_cmp (arg1, "all") && str_prefix ("all.", arg1))
00400         {
00401             /* 'get obj container' */
00402             obj = get_obj_list (ch, arg1, container->contains);
00403             if (obj == NULL)
00404             {
00405                 act ("I see nothing like that in the $T.",
00406                      ch, NULL, arg2, TO_CHAR);
00407                 return;
00408             }
00409             get_obj (ch, obj, container);
00410         }
00411         else
00412         {
00413             /* 'get all container' or 'get all.obj container' */
00414             found = FALSE;
00415             for (obj = container->contains; obj != NULL; obj = obj_next)
00416             {
00417                 obj_next = obj->next_content;
00418                 if ((arg1[3] == '\0' || is_name (&arg1[4], obj->name))
00419                     && can_see_obj (ch, obj))
00420                 {
00421                     found = TRUE;
00422                     if (container->pIndexData->vnum == OBJ_VNUM_PIT
00423                         && !IS_IMMORTAL (ch))
00424                     {
00425                         send_to_char ("Don't be so greedy!\n\r", ch);
00426                         return;
00427                     }
00428                     get_obj (ch, obj, container);
00429                 }
00430             }
00431 
00432             if (!found)
00433             {
00434                 if (arg1[3] == '\0')
00435                     act ("I see nothing in the $T.", ch, NULL, arg2, TO_CHAR);
00436                 else
00437                     act ("I see nothing like that in the $T.",
00438                          ch, NULL, arg2, TO_CHAR);
00439             }
00440         }
00441     }
00442 
00443     return;
00444 }
00445 
00446 
00447 
00448 void do_put (CHAR_DATA * ch, char *argument)
00449 {
00450     char arg1[MAX_INPUT_LENGTH];
00451     char arg2[MAX_INPUT_LENGTH];
00452     OBJ_DATA *container;
00453     OBJ_DATA *obj;
00454     OBJ_DATA *obj_next;
00455 
00456     argument = one_argument (argument, arg1);
00457     argument = one_argument (argument, arg2);
00458 
00459     if (!str_cmp (arg2, "in") || !str_cmp (arg2, "on"))
00460         argument = one_argument (argument, arg2);
00461 
00462     if (arg1[0] == '\0' || arg2[0] == '\0')
00463     {
00464         send_to_char ("Put what in what?\n\r", ch);
00465         return;
00466     }
00467 
00468     if (!str_cmp (arg2, "all") || !str_prefix ("all.", arg2))
00469     {
00470         send_to_char ("You can't do that.\n\r", ch);
00471         return;
00472     }
00473 
00474     if ((container = get_obj_here (ch, arg2)) == NULL)
00475     {
00476         act ("I see no $T here.", ch, NULL, arg2, TO_CHAR);
00477         return;
00478     }
00479 
00480     if (container->item_type != ITEM_CONTAINER)
00481     {
00482         send_to_char ("That's not a container.\n\r", ch);
00483         return;
00484     }
00485 
00486     if (IS_SET (container->value[1], CONT_CLOSED))
00487     {
00488         act ("The $d is closed.", ch, NULL, container->name, TO_CHAR);
00489         return;
00490     }
00491 
00492     if (str_cmp (arg1, "all") && str_prefix ("all.", arg1))
00493     {
00494         /* 'put obj container' */
00495         if ((obj = get_obj_carry (ch, arg1, ch)) == NULL)
00496         {
00497             send_to_char ("You do not have that item.\n\r", ch);
00498             return;
00499         }
00500 
00501         if (obj == container)
00502         {
00503             send_to_char ("You can't fold it into itself.\n\r", ch);
00504             return;
00505         }
00506 
00507         if (!can_drop_obj (ch, obj))
00508         {
00509             send_to_char ("You can't let go of it.\n\r", ch);
00510             return;
00511         }
00512 
00513         if (WEIGHT_MULT (obj) != 100)
00514         {
00515             send_to_char ("You have a feeling that would be a bad idea.\n\r",
00516                           ch);
00517             return;
00518         }
00519 
00520         if (get_obj_weight (obj) + get_true_weight (container)
00521             > (container->value[0] * 10)
00522             || get_obj_weight (obj) > (container->value[3] * 10))
00523         {
00524             send_to_char ("It won't fit.\n\r", ch);
00525             return;
00526         }
00527 
00528         if (container->pIndexData->vnum == OBJ_VNUM_PIT
00529             && !CAN_WEAR (container, ITEM_TAKE))
00530         {
00531             if (obj->timer)
00532                 SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
00533             else
00534                 obj->timer = number_range (100, 200);
00535         }
00536 
00537         obj_from_char (obj);
00538         obj_to_obj (obj, container);
00539 
00540         if (IS_SET (container->value[1], CONT_PUT_ON))
00541         {
00542             act ("$n puts $p on $P.", ch, obj, container, TO_ROOM);
00543             act ("You put $p on $P.", ch, obj, container, TO_CHAR);
00544         }
00545         else
00546         {
00547             act ("$n puts $p in $P.", ch, obj, container, TO_ROOM);
00548             act ("You put $p in $P.", ch, obj, container, TO_CHAR);
00549         }
00550     }
00551     else
00552     {
00553         /* 'put all container' or 'put all.obj container' */
00554         for (obj = ch->carrying; obj != NULL; obj = obj_next)
00555         {
00556             obj_next = obj->next_content;
00557 
00558             if ((arg1[3] == '\0' || is_name (&arg1[4], obj->name))
00559                 && can_see_obj (ch, obj)
00560                 && WEIGHT_MULT (obj) == 100
00561                 && obj->wear_loc == WEAR_NONE
00562                 && obj != container && can_drop_obj (ch, obj)
00563                 && get_obj_weight (obj) + get_true_weight (container)
00564                 <= (container->value[0] * 10)
00565                 && get_obj_weight (obj) < (container->value[3] * 10))
00566             {
00567                 if (container->pIndexData->vnum == OBJ_VNUM_PIT
00568                     && !CAN_WEAR (obj, ITEM_TAKE))
00569                 {
00570                     if (obj->timer)
00571                         SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
00572                     else
00573                         obj->timer = number_range (100, 200);
00574                 }
00575 
00576                 obj_from_char (obj);
00577                 obj_to_obj (obj, container);
00578 
00579                 if (IS_SET (container->value[1], CONT_PUT_ON))
00580                 {
00581                     act ("$n puts $p on $P.", ch, obj, container, TO_ROOM);
00582                     act ("You put $p on $P.", ch, obj, container, TO_CHAR);
00583                 }
00584                 else
00585                 {
00586                     act ("$n puts $p in $P.", ch, obj, container, TO_ROOM);
00587                     act ("You put $p in $P.", ch, obj, container, TO_CHAR);
00588                 }
00589             }
00590         }
00591     }
00592 
00593     return;
00594 }
00595 
00596 
00597 
00598 void do_drop (CHAR_DATA * ch, char *argument)
00599 {
00600     char arg[MAX_INPUT_LENGTH];
00601     OBJ_DATA *obj;
00602     OBJ_DATA *obj_next;
00603     bool found;
00604 
00605     argument = one_argument (argument, arg);
00606 
00607     if (arg[0] == '\0')
00608     {
00609         send_to_char ("Drop what?\n\r", ch);
00610         return;
00611     }
00612 
00613     if (is_number (arg))
00614     {
00615         /* 'drop NNNN coins' */
00616         int amount, gold = 0, silver = 0;
00617 
00618         amount = atoi (arg);
00619         argument = one_argument (argument, arg);
00620         if (amount <= 0
00621             || (str_cmp (arg, "coins") && str_cmp (arg, "coin") &&
00622                 str_cmp (arg, "gold") && str_cmp (arg, "silver")))
00623         {
00624             send_to_char ("Sorry, you can't do that.\n\r", ch);
00625             return;
00626         }
00627 
00628         if (!str_cmp (arg, "coins") || !str_cmp (arg, "coin")
00629             || !str_cmp (arg, "silver"))
00630         {
00631             if (ch->silver < amount)
00632             {
00633                 send_to_char ("You don't have that much silver.\n\r", ch);
00634                 return;
00635             }
00636 
00637             ch->silver -= amount;
00638             silver = amount;
00639         }
00640 
00641         else
00642         {
00643             if (ch->gold < amount)
00644             {
00645                 send_to_char ("You don't have that much gold.\n\r", ch);
00646                 return;
00647             }
00648 
00649             ch->gold -= amount;
00650             gold = amount;
00651         }
00652 
00653         for (obj = ch->in_room->contents; obj != NULL; obj = obj_next)
00654         {
00655             obj_next = obj->next_content;
00656 
00657             switch (obj->pIndexData->vnum)
00658             {
00659                 case OBJ_VNUM_SILVER_ONE:
00660                     silver += 1;
00661                     extract_obj (obj);
00662                     break;
00663 
00664                 case OBJ_VNUM_GOLD_ONE:
00665                     gold += 1;
00666                     extract_obj (obj);
00667                     break;
00668 
00669                 case OBJ_VNUM_SILVER_SOME:
00670                     silver += obj->value[0];
00671                     extract_obj (obj);
00672                     break;
00673 
00674                 case OBJ_VNUM_GOLD_SOME:
00675                     gold += obj->value[1];
00676                     extract_obj (obj);
00677                     break;
00678 
00679                 case OBJ_VNUM_COINS:
00680                     silver += obj->value[0];
00681                     gold += obj->value[1];
00682                     extract_obj (obj);
00683                     break;
00684             }
00685         }
00686 
00687         obj_to_room (create_money (gold, silver), ch->in_room);
00688         act ("$n drops some coins.", ch, NULL, NULL, TO_ROOM);
00689         send_to_char ("OK.\n\r", ch);
00690         return;
00691     }
00692 
00693     if (str_cmp (arg, "all") && str_prefix ("all.", arg))
00694     {
00695         /* 'drop obj' */
00696         if ((obj = get_obj_carry (ch, arg, ch)) == NULL)
00697         {
00698             send_to_char ("You do not have that item.\n\r", ch);
00699             return;
00700         }
00701 
00702         if (!can_drop_obj (ch, obj))
00703         {
00704             send_to_char ("You can't let go of it.\n\r", ch);
00705             return;
00706         }
00707 
00708         obj_from_char (obj);
00709         obj_to_room (obj, ch->in_room);
00710         act ("$n drops $p.", ch, obj, NULL, TO_ROOM);
00711         act ("You drop $p.", ch, obj, NULL, TO_CHAR);
00712         if (IS_OBJ_STAT (obj, ITEM_MELT_DROP))
00713         {
00714             act ("$p dissolves into smoke.", ch, obj, NULL, TO_ROOM);
00715             act ("$p dissolves into smoke.", ch, obj, NULL, TO_CHAR);
00716             extract_obj (obj);
00717         }
00718     }
00719     else
00720     {
00721         /* 'drop all' or 'drop all.obj' */
00722         found = FALSE;
00723         for (obj = ch->carrying; obj != NULL; obj = obj_next)
00724         {
00725             obj_next = obj->next_content;
00726 
00727             if ((arg[3] == '\0' || is_name (&arg[4], obj->name))
00728                 && can_see_obj (ch, obj)
00729                 && obj->wear_loc == WEAR_NONE && can_drop_obj (ch, obj))
00730             {
00731                 found = TRUE;
00732                 obj_from_char (obj);
00733                 obj_to_room (obj, ch->in_room);
00734                 act ("$n drops $p.", ch, obj, NULL, TO_ROOM);
00735                 act ("You drop $p.", ch, obj, NULL, TO_CHAR);
00736                 if (IS_OBJ_STAT (obj, ITEM_MELT_DROP))
00737                 {
00738                     act ("$p dissolves into smoke.", ch, obj, NULL, TO_ROOM);
00739                     act ("$p dissolves into smoke.", ch, obj, NULL, TO_CHAR);
00740                     extract_obj (obj);
00741                 }
00742             }
00743         }
00744 
00745         if (!found)
00746         {
00747             if (arg[3] == '\0')
00748                 act ("You are not carrying anything.",
00749                      ch, NULL, arg, TO_CHAR);
00750             else
00751                 act ("You are not carrying any $T.",
00752                      ch, NULL, &arg[4], TO_CHAR);
00753         }
00754     }
00755 
00756     return;
00757 }
00758 
00759 
00760 
00761 void do_give (CHAR_DATA * ch, char *argument)
00762 {
00763     char arg1[MAX_INPUT_LENGTH];
00764     char arg2[MAX_INPUT_LENGTH];
00765     char buf[MAX_STRING_LENGTH];
00766     CHAR_DATA *victim;
00767     OBJ_DATA *obj;
00768 
00769     argument = one_argument (argument, arg1);
00770     argument = one_argument (argument, arg2);
00771 
00772     if (arg1[0] == '\0' || arg2[0] == '\0')
00773     {
00774         send_to_char ("Give what to whom?\n\r", ch);
00775         return;
00776     }
00777 
00778     if (is_number (arg1))
00779     {
00780         /* 'give NNNN coins victim' */
00781         int amount;
00782         bool silver;
00783 
00784         amount = atoi (arg1);
00785         if (amount <= 0
00786             || (str_cmp (arg2, "coins") && str_cmp (arg2, "coin") &&
00787                 str_cmp (arg2, "gold") && str_cmp (arg2, "silver")))
00788         {
00789             send_to_char ("Sorry, you can't do that.\n\r", ch);
00790             return;
00791         }
00792 
00793         silver = str_cmp (arg2, "gold");
00794 
00795         argument = one_argument (argument, arg2);
00796         if (arg2[0] == '\0')
00797         {
00798             send_to_char ("Give what to whom?\n\r", ch);
00799             return;
00800         }
00801 
00802         if ((victim = get_char_room (ch, arg2)) == NULL)
00803         {
00804             send_to_char ("They aren't here.\n\r", ch);
00805             return;
00806         }
00807 
00808         if ((!silver && ch->gold < amount) || (silver && ch->silver < amount))
00809         {
00810             send_to_char ("You haven't got that much.\n\r", ch);
00811             return;
00812         }
00813 
00814         if (silver)
00815         {
00816             ch->silver -= amount;
00817             victim->silver += amount;
00818         }
00819         else
00820         {
00821             ch->gold -= amount;
00822             victim->gold += amount;
00823         }
00824 
00825         sprintf (buf, "$n gives you %d %s.", amount,
00826                  silver ? "silver" : "gold");
00827         act (buf, ch, NULL, victim, TO_VICT);
00828         act ("$n gives $N some coins.", ch, NULL, victim, TO_NOTVICT);
00829         sprintf (buf, "You give $N %d %s.", amount,
00830                  silver ? "silver" : "gold");
00831         act (buf, ch, NULL, victim, TO_CHAR);
00832 
00833         /*
00834          * Bribe trigger
00835          */
00836         if (IS_NPC (victim) && HAS_TRIGGER (victim, TRIG_BRIBE))
00837             mp_bribe_trigger (victim, ch, silver ? amount : amount * 100);
00838 
00839         if (IS_NPC (victim) && IS_SET (victim->act, ACT_IS_CHANGER))
00840         {
00841             int change;
00842 
00843             change = (silver ? 95 * amount / 100 / 100 : 95 * amount);
00844 
00845 
00846             if (!silver && change > victim->silver)
00847                 victim->silver += change;
00848 
00849             if (silver && change > victim->gold)
00850                 victim->gold += change;
00851 
00852             if (change < 1 && can_see (victim, ch))
00853             {
00854                 act
00855                     ("$n tells you 'I'm sorry, you did not give me enough to change.'",
00856                      victim, NULL, ch, TO_VICT);
00857                 ch->reply = victim;
00858                 sprintf (buf, "%d %s %s",
00859                          amount, silver ? "silver" : "gold", ch->name);
00860                 do_function (victim, &do_give, buf);
00861             }
00862             else if (can_see (victim, ch))
00863             {
00864                 sprintf (buf, "%d %s %s",
00865                          change, silver ? "gold" : "silver", ch->name);
00866                 do_function (victim, &do_give, buf);
00867                 if (silver)
00868                 {
00869                     sprintf (buf, "%d silver %s",
00870                              (95 * amount / 100 - change * 100), ch->name);
00871                     do_function (victim, &do_give, buf);
00872                 }
00873                 act ("$n tells you 'Thank you, come again.'",
00874                      victim, NULL, ch, TO_VICT);
00875                 ch->reply = victim;
00876             }
00877         }
00878         return;
00879     }
00880 
00881     if ((obj = get_obj_carry (ch, arg1, ch)) == NULL)
00882     {
00883         send_to_char ("You do not have that item.\n\r", ch);
00884         return;
00885     }
00886 
00887     if (obj->wear_loc != WEAR_NONE)
00888     {
00889         send_to_char ("You must remove it first.\n\r", ch);
00890         return;
00891     }
00892 
00893     if ((victim = get_char_room (ch, arg2)) == NULL)
00894     {
00895         send_to_char ("They aren't here.\n\r", ch);
00896         return;
00897     }
00898 
00899     if (IS_NPC (victim) && victim->pIndexData->pShop != NULL)
00900     {
00901         act ("$N tells you 'Sorry, you'll have to sell that.'",
00902              ch, NULL, victim, TO_CHAR);
00903         ch->reply = victim;
00904         return;
00905     }
00906 
00907     if (!can_drop_obj (ch, obj))
00908     {
00909         send_to_char ("You can't let go of it.\n\r", ch);
00910         return;
00911     }
00912 
00913     if (victim->carry_number + get_obj_number (obj) > can_carry_n (victim))
00914     {
00915         act ("$N has $S hands full.", ch, NULL, victim, TO_CHAR);
00916         return;
00917     }
00918 
00919     if (get_carry_weight (victim) + get_obj_weight (obj) >
00920         can_carry_w (victim))
00921     {
00922         act ("$N can't carry that much weight.", ch, NULL, victim, TO_CHAR);
00923         return;
00924     }
00925 
00926     if (!can_see_obj (victim, obj))
00927     {
00928         act ("$N can't see it.", ch, NULL, victim, TO_CHAR);
00929         return;
00930     }
00931 
00932     obj_from_char (obj);
00933     obj_to_char (obj, victim);
00934     MOBtrigger = FALSE;
00935     act ("$n gives $p to $N.", ch, obj, victim, TO_NOTVICT);
00936     act ("$n gives you $p.", ch, obj, victim, TO_VICT);
00937     act ("You give $p to $N.", ch, obj, victim, TO_CHAR);
00938     MOBtrigger = TRUE;
00939 
00940     /*
00941      * Give trigger
00942      */
00943     if (IS_NPC (victim) && HAS_TRIGGER (victim, TRIG_GIVE))
00944         mp_give_trigger (victim, ch, obj);
00945 
00946     return;
00947 }
00948 
00949 
00950 /* for poisoning weapons and food/drink */
00951 void do_envenom (CHAR_DATA * ch, char *argument)
00952 {
00953     OBJ_DATA *obj;
00954     AFFECT_DATA af;
00955     int percent, skill;
00956 
00957     /* find out what */
00958     if (argument[0] == '\0')
00959     {
00960         send_to_char ("Envenom what item?\n\r", ch);
00961         return;
00962     }
00963 
00964     obj = get_obj_list (ch, argument, ch->carrying);
00965 
00966     if (obj == NULL)
00967     {
00968         send_to_char ("You don't have that item.\n\r", ch);
00969         return;
00970     }
00971 
00972     if ((skill = get_skill (ch, gsn_envenom)) < 1)
00973     {
00974         send_to_char ("Are you crazy? You'd poison yourself!\n\r", ch);
00975         return;
00976     }
00977 
00978     if (obj->item_type == ITEM_FOOD || obj->item_type == ITEM_DRINK_CON)
00979     {
00980         if (IS_OBJ_STAT (obj, ITEM_BLESS)
00981             || IS_OBJ_STAT (obj, ITEM_BURN_PROOF))
00982         {
00983             act ("You fail to poison $p.", ch, obj, NULL, TO_CHAR);
00984             return;
00985         }
00986 
00987         if (number_percent () < skill)
00988         {                        /* success! */
00989             act ("$n treats $p with deadly poison.", ch, obj, NULL, TO_ROOM);
00990             act ("You treat $p with deadly poison.", ch, obj, NULL, TO_CHAR);
00991             if (!obj->value[3])
00992             {
00993                 obj->value[3] = 1;
00994                 check_improve (ch, gsn_envenom, TRUE, 4);
00995             }
00996             WAIT_STATE (ch, skill_table[gsn_envenom].beats);
00997             return;
00998         }
00999 
01000         act ("You fail to poison $p.", ch, obj, NULL, TO_CHAR);
01001         if (!obj->value[3])
01002             check_improve (ch, gsn_envenom, FALSE, 4);
01003         WAIT_STATE (ch, skill_table[gsn_envenom].beats);
01004         return;
01005     }
01006 
01007     if (obj->item_type == ITEM_WEAPON)
01008     {
01009         if (IS_WEAPON_STAT (obj, WEAPON_FLAMING)
01010             || IS_WEAPON_STAT (obj, WEAPON_FROST)
01011             || IS_WEAPON_STAT (obj, WEAPON_VAMPIRIC)
01012             || IS_WEAPON_STAT (obj, WEAPON_SHARP)
01013             || IS_WEAPON_STAT (obj, WEAPON_VORPAL)
01014             || IS_WEAPON_STAT (obj, WEAPON_SHOCKING)
01015             || IS_OBJ_STAT (obj, ITEM_BLESS)
01016             || IS_OBJ_STAT (obj, ITEM_BURN_PROOF))
01017         {
01018             act ("You can't seem to envenom $p.", ch, obj, NULL, TO_CHAR);
01019             return;
01020         }
01021 
01022         if (obj->value[3] < 0
01023             || attack_table[obj->value[3]].damage == DAM_BASH)
01024         {
01025             send_to_char ("You can only envenom edged weapons.\n\r", ch);
01026             return;
01027         }
01028 
01029         if (IS_WEAPON_STAT (obj, WEAPON_POISON))
01030         {
01031             act ("$p is already envenomed.", ch, obj, NULL, TO_CHAR);
01032             return;
01033         }
01034 
01035         percent = number_percent ();
01036         if (percent < skill)
01037         {
01038 
01039             af.where = TO_WEAPON;
01040             af.type = gsn_poison;
01041             af.level = ch->level * percent / 100;
01042             af.duration = ch->level / 2 * percent / 100;
01043             af.location = 0;
01044             af.modifier = 0;
01045             af.bitvector = WEAPON_POISON;
01046             affect_to_obj (obj, &af);
01047 
01048             act ("$n coats $p with deadly venom.", ch, obj, NULL, TO_ROOM);
01049             act ("You coat $p with venom.", ch, obj, NULL, TO_CHAR);
01050             check_improve (ch, gsn_envenom, TRUE, 3);
01051             WAIT_STATE (ch, skill_table[gsn_envenom].beats);
01052             return;
01053         }
01054         else
01055         {
01056             act ("You fail to envenom $p.", ch, obj, NULL, TO_CHAR);
01057             check_improve (ch, gsn_envenom, FALSE, 3);
01058             WAIT_STATE (ch, skill_table[gsn_envenom].beats);
01059             return;
01060         }
01061     }
01062 
01063     act ("You can't poison $p.", ch, obj, NULL, TO_CHAR);
01064     return;
01065 }
01066 
01067 void do_fill (CHAR_DATA * ch, char *argument)
01068 {
01069     char arg[MAX_INPUT_LENGTH];
01070     char buf[MAX_STRING_LENGTH];
01071     OBJ_DATA *obj;
01072     OBJ_DATA *fountain;
01073     bool found;
01074 
01075     one_argument (argument, arg);
01076 
01077     if (arg[0] == '\0')
01078     {
01079         send_to_char ("Fill what?\n\r", ch);
01080         return;
01081     }
01082 
01083     if ((obj = get_obj_carry (ch, arg, ch)) == NULL)
01084     {
01085         send_to_char ("You do not have that item.\n\r", ch);
01086         return;
01087     }
01088 
01089     found = FALSE;
01090     for (fountain = ch->in_room->contents; fountain != NULL;
01091          fountain = fountain->next_content)
01092     {
01093         if (fountain->item_type == ITEM_FOUNTAIN)
01094         {
01095             found = TRUE;
01096             break;
01097         }
01098     }
01099 
01100     if (!found)
01101     {
01102         send_to_char ("There is no fountain here!\n\r", ch);
01103         return;
01104     }
01105 
01106     if (obj->item_type != ITEM_DRINK_CON)
01107     {
01108         send_to_char ("You can't fill that.\n\r", ch);
01109         return;
01110     }
01111 
01112     if (obj->value[1] != 0 && obj->value[2] != fountain->value[2])
01113     {
01114         send_to_char ("There is already another liquid in it.\n\r", ch);
01115         return;
01116     }
01117 
01118     if (obj->value[1] >= obj->value[0])
01119     {
01120         send_to_char ("Your container is full.\n\r", ch);
01121         return;
01122     }
01123 
01124     sprintf (buf, "You fill $p with %s from $P.",
01125              liq_table[fountain->value[2]].liq_name);
01126     act (buf, ch, obj, fountain, TO_CHAR);
01127     sprintf (buf, "$n fills $p with %s from $P.",
01128              liq_table[fountain->value[2]].liq_name);
01129     act (buf, ch, obj, fountain, TO_ROOM);
01130     obj->value[2] = fountain->value[2];
01131     obj->value[1] = obj->value[0];
01132     return;
01133 }
01134 
01135 void do_pour (CHAR_DATA * ch, char *argument)
01136 {
01137     char arg[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH];
01138     OBJ_DATA *out, *in;
01139     CHAR_DATA *vch = NULL;
01140     int amount;
01141 
01142     argument = one_argument (argument, arg);
01143 
01144     if (arg[0] == '\0' || argument[0] == '\0')
01145     {
01146         send_to_char ("Pour what into what?\n\r", ch);
01147         return;
01148     }
01149 
01150 
01151     if ((out = get_obj_carry (ch, arg, ch)) == NULL)
01152     {
01153         send_to_char ("You don't have that item.\n\r", ch);
01154         return;
01155     }
01156 
01157     if (out->item_type != ITEM_DRINK_CON)
01158     {
01159         send_to_char ("That's not a drink container.\n\r", ch);
01160         return;
01161     }
01162 
01163     if (!str_cmp (argument, "out"))
01164     {
01165         if (out->value[1] == 0)
01166         {
01167             send_to_char ("It's already empty.\n\r", ch);
01168             return;
01169         }
01170 
01171         out->value[1] = 0;
01172         out->value[3] = 0;
01173         sprintf (buf, "You invert $p, spilling %s all over the ground.",
01174                  liq_table[out->value[2]].liq_name);
01175         act (buf, ch, out, NULL, TO_CHAR);
01176 
01177         sprintf (buf, "$n inverts $p, spilling %s all over the ground.",
01178                  liq_table[out->value[2]].liq_name);
01179         act (buf, ch, out, NULL, TO_ROOM);
01180         return;
01181     }
01182 
01183     if ((in = get_obj_here (ch, argument)) == NULL)
01184     {
01185         vch = get_char_room (ch, argument);
01186 
01187         if (vch == NULL)
01188         {
01189             send_to_char ("Pour into what?\n\r", ch);
01190             return;
01191         }
01192 
01193         in = get_eq_char (vch, WEAR_HOLD);
01194 
01195         if (in == NULL)
01196         {
01197             send_to_char ("They aren't holding anything.", ch);
01198             return;
01199         }
01200     }
01201 
01202     if (in->item_type != ITEM_DRINK_CON)
01203     {
01204         send_to_char ("You can only pour into other drink containers.\n\r",
01205                       ch);
01206         return;
01207     }
01208 
01209     if (in == out)
01210     {
01211         send_to_char ("You cannot change the laws of physics!\n\r", ch);
01212         return;
01213     }
01214 
01215     if (in->value[1] != 0 && in->value[2] != out->value[2])
01216     {
01217         send_to_char ("They don't hold the same liquid.\n\r", ch);
01218         return;
01219     }
01220 
01221     if (out->value[1] == 0)
01222     {
01223         act ("There's nothing in $p to pour.", ch, out, NULL, TO_CHAR);
01224         return;
01225     }
01226 
01227     if (in->value[1] >= in->value[0])
01228     {
01229         act ("$p is already filled to the top.", ch, in, NULL, TO_CHAR);
01230         return;
01231     }
01232 
01233     amount = UMIN (out->value[1], in->value[0] - in->value[1]);
01234 
01235     in->value[1] += amount;
01236     out->value[1] -= amount;
01237     in->value[2] = out->value[2];
01238 
01239     if (vch == NULL)
01240     {
01241         sprintf (buf, "You pour %s from $p into $P.",
01242                  liq_table[out->value[2]].liq_name);
01243         act (buf, ch, out, in, TO_CHAR);
01244         sprintf (buf, "$n pours %s from $p into $P.",
01245                  liq_table[out->value[2]].liq_name);
01246         act (buf, ch, out, in, TO_ROOM);
01247     }
01248     else
01249     {
01250         sprintf (buf, "You pour some %s for $N.",
01251                  liq_table[out->value[2]].liq_name);
01252         act (buf, ch, NULL, vch, TO_CHAR);
01253         sprintf (buf, "$n pours you some %s.",
01254                  liq_table[out->value[2]].liq_name);
01255         act (buf, ch, NULL, vch, TO_VICT);
01256         sprintf (buf, "$n pours some %s for $N.",
01257                  liq_table[out->value[2]].liq_name);
01258         act (buf, ch, NULL, vch, TO_NOTVICT);
01259 
01260     }
01261 }
01262 
01263 void do_drink (CHAR_DATA * ch, char *argument)
01264 {
01265     char arg[MAX_INPUT_LENGTH];
01266     OBJ_DATA *obj;
01267     int amount;
01268     int liquid;
01269 
01270     one_argument (argument, arg);
01271 
01272     if (arg[0] == '\0')
01273     {
01274         for (obj = ch->in_room->contents; obj; obj = obj->next_content)
01275         {
01276             if (obj->item_type == ITEM_FOUNTAIN)
01277                 break;
01278         }
01279 
01280         if (obj == NULL)
01281         {
01282             send_to_char ("Drink what?\n\r", ch);
01283             return;
01284         }
01285     }
01286     else
01287     {
01288         if ((obj = get_obj_here (ch, arg)) == NULL)
01289         {
01290             send_to_char ("You can't find it.\n\r", ch);
01291             return;
01292         }
01293     }
01294 
01295     if (!IS_NPC (ch) && ch->pcdata->condition[COND_DRUNK] > 10)
01296     {
01297         send_to_char ("You fail to reach your mouth.  *Hic*\n\r", ch);
01298         return;
01299     }
01300 
01301     switch (obj->item_type)
01302     {
01303         default:
01304             send_to_char ("You can't drink from that.\n\r", ch);
01305             return;
01306 
01307         case ITEM_FOUNTAIN:
01308             if ((liquid = obj->value[2]) < 0)
01309             {
01310                 bug ("Do_drink: bad liquid number %d.", liquid);
01311                 liquid = obj->value[2] = 0;
01312             }
01313             amount = liq_table[liquid].liq_affect[4] * 3;
01314             break;
01315 
01316         case ITEM_DRINK_CON:
01317             if (obj->value[1] <= 0)
01318             {
01319                 send_to_char ("It is already empty.\n\r", ch);
01320                 return;
01321             }
01322 
01323             if ((liquid = obj->value[2]) < 0)
01324             {
01325                 bug ("Do_drink: bad liquid number %d.", liquid);
01326                 liquid = obj->value[2] = 0;
01327             }
01328 
01329             amount = liq_table[liquid].liq_affect[4];
01330             amount = UMIN (amount, obj->value[1]);
01331             break;
01332     }
01333     if (!IS_NPC (ch) && !IS_IMMORTAL (ch)
01334         && ch->pcdata->condition[COND_FULL] > 45)
01335     {
01336         send_to_char ("You're too full to drink more.\n\r", ch);
01337         return;
01338     }
01339 
01340     act ("$n drinks $T from $p.",
01341          ch, obj, liq_table[liquid].liq_name, TO_ROOM);
01342     act ("You drink $T from $p.",
01343          ch, obj, liq_table[liquid].liq_name, TO_CHAR);
01344 
01345     gain_condition (ch, COND_DRUNK,
01346                     amount * liq_table[liquid].liq_affect[COND_DRUNK] / 36);
01347     gain_condition (ch, COND_FULL,
01348                     amount * liq_table[liquid].liq_affect[COND_FULL] / 4);
01349     gain_condition (ch, COND_THIRST,
01350                     amount * liq_table[liquid].liq_affect[COND_THIRST] / 10);
01351     gain_condition (ch, COND_HUNGER,
01352                     amount * liq_table[liquid].liq_affect[COND_HUNGER] / 2);
01353 
01354     if (!IS_NPC (ch) && ch->pcdata->condition[COND_DRUNK] > 10)
01355         send_to_char ("You feel drunk.\n\r", ch);
01356     if (!IS_NPC (ch) && ch->pcdata->condition[COND_FULL] > 40)
01357         send_to_char ("You are full.\n\r", ch);
01358     if (!IS_NPC (ch) && ch->pcdata->condition[COND_THIRST] > 40)
01359         send_to_char ("Your thirst is quenched.\n\r", ch);
01360 
01361     if (obj->value[3] != 0)
01362     {
01363         /* The drink was poisoned ! */
01364         AFFECT_DATA af;
01365 
01366         act ("$n chokes and gags.", ch, NULL, NULL, TO_ROOM);
01367         send_to_char ("You choke and gag.\n\r", ch);
01368         af.where = TO_AFFECTS;
01369         af.type = gsn_poison;
01370         af.level = number_fuzzy (amount);
01371         af.duration = 3 * amount;
01372         af.location = APPLY_NONE;
01373         af.modifier = 0;
01374         af.bitvector = AFF_POISON;
01375         affect_join (ch, &af);
01376     }
01377 
01378     if (obj->value[0] > 0)
01379         obj->value[1] -= amount;
01380 
01381     return;
01382 }
01383 
01384 
01385 
01386 void do_eat (CHAR_DATA * ch, char *argument)
01387 {
01388     char arg[MAX_INPUT_LENGTH];
01389     OBJ_DATA *obj;
01390 
01391     one_argument (argument, arg);
01392     if (arg[0] == '\0')
01393     {
01394         send_to_char ("Eat what?\n\r", ch);
01395         return;
01396     }
01397 
01398     if ((obj = get_obj_carry (ch, arg, ch)) == NULL)
01399     {
01400         send_to_char ("You do not have that item.\n\r", ch);
01401         return;
01402     }
01403 
01404     if (!IS_IMMORTAL (ch))
01405     {
01406         if (obj->item_type != ITEM_FOOD && obj->item_type != ITEM_PILL)
01407         {
01408             send_to_char ("That's not edible.\n\r", ch);
01409             return;
01410         }
01411 
01412         if (!IS_NPC (ch) && ch->pcdata->condition[COND_FULL] > 40)
01413         {
01414             send_to_char ("You are too full to eat more.\n\r", ch);
01415             return;
01416         }
01417     }
01418 
01419     act ("$n eats $p.", ch, obj, NULL, TO_ROOM);
01420     act ("You eat $p.", ch, obj, NULL, TO_CHAR);
01421 
01422     switch (obj->item_type)
01423     {
01424 
01425         case ITEM_FOOD:
01426             if (!IS_NPC (ch))
01427             {
01428                 int condition;
01429 
01430                 condition = ch->pcdata->condition[COND_HUNGER];
01431                 gain_condition (ch, COND_FULL, obj->value[0]);
01432                 gain_condition (ch, COND_HUNGER, obj->value[1]);
01433                 if (condition == 0 && ch->pcdata->condition[COND_HUNGER] > 0)
01434                     send_to_char ("You are no longer hungry.\n\r", ch);
01435                 else if (ch->pcdata->condition[COND_FULL] > 40)
01436                     send_to_char ("You are full.\n\r", ch);
01437             }
01438 
01439             if (obj->value[3] != 0)
01440             {
01441                 /* The food was poisoned! */
01442                 AFFECT_DATA af;
01443 
01444                 act ("$n chokes and gags.", ch, 0, 0, TO_ROOM);
01445                 send_to_char ("You choke and gag.\n\r", ch);
01446 
01447                 af.where = TO_AFFECTS;
01448                 af.type = gsn_poison;
01449                 af.level = number_fuzzy (obj->value[0]);
01450                 af.duration = 2 * obj->value[0];
01451                 af.location = APPLY_NONE;
01452                 af.modifier = 0;
01453                 af.bitvector = AFF_POISON;
01454                 affect_join (ch, &af);
01455             }
01456             break;
01457 
01458         case ITEM_PILL:
01459             obj_cast_spell (obj->value[1], obj->value[0], ch, ch, NULL);
01460             obj_cast_spell (obj->value[2], obj->value[0], ch, ch, NULL);
01461             obj_cast_spell (obj->value[3], obj->value[0], ch, ch, NULL);
01462             break;
01463     }
01464 
01465     extract_obj (obj);
01466     return;
01467 }
01468 
01469 
01470 
01471 /*
01472  * Remove an object.
01473  */
01474 bool remove_obj (CHAR_DATA * ch, int iWear, bool fReplace)
01475 {
01476     OBJ_DATA *obj;
01477 
01478     if ((obj = get_eq_char (ch, iWear)) == NULL)
01479         return TRUE;
01480 
01481     if (!fReplace)
01482         return FALSE;
01483 
01484     if (IS_SET (obj->extra_flags, ITEM_NOREMOVE) && ch->level < 51)
01485     {
01486         act ("You can't remove $p.", ch, obj, NULL, TO_CHAR);
01487         return FALSE;
01488     }
01489 
01490     if (obj == get_eq_char(ch, WEAR_WIELD) && (get_eq_char(ch, WEAR_SECONDARY) != NULL))
01491     {
01492         OBJ_DATA *secondary;
01493         secondary = get_eq_char(ch, WEAR_SECONDARY);
01494         unequip_char(ch, secondary);
01495         act ("You stop using $p.", ch, secondary, NULL, TO_CHAR);
01496         act ("$n stops using $p.", ch, secondary, NULL, TO_ROOM);
01497     }
01498 
01499     unequip_char (ch, obj);
01500     
01501     act ("$n stops using $p.", ch, obj, NULL, TO_ROOM);
01502     act ("You stop using $p.", ch, obj, NULL, TO_CHAR);
01503     return TRUE;
01504 }
01505 
01506 
01507 
01508 /*
01509  * Wear one object.
01510  * Optional replacement of existing objects.
01511  * Big repetitive code, ick.
01512  */
01513 void wear_obj (CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace)
01514 {
01515     char buf[MAX_STRING_LENGTH];
01516 
01517     if (ch->level < obj->level)
01518     {
01519         sprintf (buf, "You must be level %d to use this object.\n\r",
01520                  obj->level);
01521         send_to_char (buf, ch);
01522         act ("$n tries to use $p, but is too inexperienced.",
01523              ch, obj, NULL, TO_ROOM);
01524         return;
01525     }
01526 
01527     if (obj->item_type == ITEM_LIGHT)
01528     {
01529         if (!remove_obj (ch, WEAR_LIGHT, fReplace))
01530             return;
01531         act ("$n lights $p and holds it.", ch, obj, NULL, TO_ROOM);
01532         act ("You light $p and hold it.", ch, obj, NULL, TO_CHAR);
01533         equip_char (ch, obj, WEAR_LIGHT);
01534         return;
01535     }
01536 
01537     if (CAN_WEAR (obj, ITEM_WEAR_FINGER))
01538     {
01539         if (get_eq_char (ch, WEAR_FINGER_L) != NULL
01540             && get_eq_char (ch, WEAR_FINGER_R) != NULL
01541             && !remove_obj (ch, WEAR_FINGER_L, fReplace)
01542             && !remove_obj (ch, WEAR_FINGER_R, fReplace))
01543             return;
01544 
01545         if (get_eq_char (ch, WEAR_FINGER_L) == NULL)
01546         {
01547             act ("$n wears $p on $s left finger.", ch, obj, NULL, TO_ROOM);
01548             act ("You wear $p on your left finger.", ch, obj, NULL, TO_CHAR);
01549             equip_char (ch, obj, WEAR_FINGER_L);
01550             return;
01551         }
01552 
01553         if (get_eq_char (ch, WEAR_FINGER_R) == NULL)
01554         {
01555             act ("$n wears $p on $s right finger.", ch, obj, NULL, TO_ROOM);
01556             act ("You wear $p on your right finger.", ch, obj, NULL, TO_CHAR);
01557             equip_char (ch, obj, WEAR_FINGER_R);
01558             return;
01559         }
01560 
01561         bug ("Wear_obj: no free finger.", 0);
01562         send_to_char ("You already wear two rings.\n\r", ch);
01563         return;
01564     }
01565 
01566     if (CAN_WEAR (obj, ITEM_WEAR_NECK))
01567     {
01568         if (get_eq_char (ch, WEAR_NECK_1) != NULL
01569             && get_eq_char (ch, WEAR_NECK_2) != NULL
01570             && !remove_obj (ch, WEAR_NECK_1, fReplace)
01571             && !remove_obj (ch, WEAR_NECK_2, fReplace))
01572             return;
01573 
01574         if (get_eq_char (ch, WEAR_NECK_1) == NULL)
01575         {
01576             act ("$n wears $p around $s neck.", ch, obj, NULL, TO_ROOM);
01577             act ("You wear $p around your neck.", ch, obj, NULL, TO_CHAR);
01578             equip_char (ch, obj, WEAR_NECK_1);
01579             return;
01580         }
01581 
01582         if (get_eq_char (ch, WEAR_NECK_2) == NULL)
01583         {
01584             act ("$n wears $p around $s neck.", ch, obj, NULL, TO_ROOM);
01585             act ("You wear $p around your neck.", ch, obj, NULL, TO_CHAR);
01586             equip_char (ch, obj, WEAR_NECK_2);
01587             return;
01588         }
01589 
01590         bug ("Wear_obj: no free neck.", 0);
01591         send_to_char ("You already wear two neck items.\n\r", ch);
01592         return;
01593     }
01594 
01595     if (CAN_WEAR (obj, ITEM_WEAR_BODY))
01596     {
01597         if (!