/**************************************************************************/ // act_obj.cpp - players performing actions relating to objects /*************************************************************************** * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt * * >> A number of people have contributed to the Dawn codebase, with the * * majority of code written by Michael Garratt - www.dawnoftime.org * * >> To use this source code, you must fully comply with all the licenses * * in licenses.txt... In particular, you may not remove this copyright * * notice. * *************************************************************************** * >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. * * >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * >> ROM 2.4 is copyright 1993-1995 Russ Taylor and has been brought to * * you by the ROM consortium: Russ Taylor(rtaylor@pacinfo.com), * * Gabrielle Taylor(gtaylor@pacinfo.com) & Brian Moore(rom@rom.efn.org) * * >> Oblivion 1.2 is copyright 1996 Wes Wagner * **************************************************************************/ #include "include.h" // dawn standard includes #include "msp.h" #include "lockers.h" #include "shop.h" /* command procedures needed */ DECLARE_DO_FUN(do_split ); DECLARE_DO_FUN(do_yell ); DECLARE_DO_FUN(do_say ); DECLARE_DO_FUN(do_stand ); char *get_weapontype(OBJ_DATA *obj); /* prototype - handler.c */ bool trapcheck_get(char_data *ch, OBJ_DATA *obj); SPRESULT spell_fear_magic( int sn, int level, char_data *ch, void *vo,int ); /* magic.cpp */ // Local functions. #define CD char_data #define OD OBJ_DATA bool remove_obj args( (char_data *ch, int iWear, bool fReplace ) ); CD * find_keeper args( (char_data *ch ) ); int get_cost args( (char_data *keeper, OBJ_DATA *obj, bool fBuy ) ); void obj_to_keeper args( (OBJ_DATA *obj, char_data *ch ) ); OD * get_obj_keeper args( (char_data *ch,char_data *keeper,char *argument)); #undef OD #undef CD bool can_loot(char_data *, OBJ_DATA *) { return true; } /**************************************************************************/ void get_obj( char_data *ch, OBJ_DATA *obj, OBJ_DATA *container) { // variables for AUTOSPLIT char_data *gch; int members; char buffer[100]; if ( !CAN_WEAR(obj, OBJWEAR_TAKE) ) { ch->println("You can't take that."); return; } if ( trapcheck_get( ch, obj )) return; if ( obj->item_type == ITEM_MONEY) { // check silver first if ((get_carry_weight( ch ) + get_silver_weight(obj->value[0])) > can_carry_w( ch ) ) { ch->println("You cannot carry that much weight."); return; } // now lets check if the player can carry that much gold if ((get_carry_weight( ch ) + get_gold_weight(obj->value[1])) > can_carry_w( ch ) ) { ch->println("You cannot carry that much weight."); return; } } if ( !IS_SWITCHED (ch) && (ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ))) { act( "$d: you can't carry that many items.", ch, NULL, obj->name, TO_CHAR ); return; } if ( !IS_SWITCHED (ch) && get_carry_weight(ch) + get_obj_weight( obj ) > can_carry_w( ch ) ) { act( "$d: you can't carry that much weight.", ch, NULL, obj->name, TO_CHAR ); return; } if (obj->in_room != NULL) { for (gch = obj->in_room->people; gch != NULL; gch = gch->next_in_room) if (gch->on == obj) { act("$N appears to be using $p.", ch,obj,gch,TO_CHAR); return; } } if ( container != NULL ){ if(container->pIndexData->vnum == OBJ_VNUM_PIT && !CAN_WEAR(container, OBJWEAR_TAKE) && !IS_OBJ_STAT(obj,OBJEXTRA_HAD_TIMER)) obj->timer = 0; act( "You get $p from $P.", ch, obj, container, TO_CHAR ); act( "$n gets $p from $P.", ch, obj, container, TO_ROOM ); REMOVE_BIT(obj->extra_flags,OBJEXTRA_HAD_TIMER); obj_from_obj( obj ); }else{ act( "You get $p.", ch, obj, container, TO_CHAR ); act( "$n gets $p.", ch, obj, container, TO_ROOM ); obj_from_room( obj ); } if ( obj->item_type == ITEM_MONEY) { ch->silver += obj->value[0]; ch->gold += obj->value[1]; if (IS_SET(ch->act,PLR_AUTOSPLIT)) { // AUTOSPLIT code members = 0; for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room ) { if (!IS_AFFECTED(gch,AFF_CHARM) && is_same_group( gch, ch ) ) members++; } if ( members > 1 && (obj->value[0] > 1 || obj->value[1])) { sprintf(buffer,"%d %d",obj->value[0],obj->value[1]); do_split(ch,buffer); } } if(!IS_NPC(ch)){ if(obj->lastdrop_id!=ch->id && !strcmp(obj->lastdrop_remote_ip,ch->remote_ip_copy)) { multilog_alertf(ch, "`Y%s<%d>`x getting `Y%d gold `xand `S%d silver `xfrom somewhere " "(prob the ground), `M(room %d)`x, this was put there by someone `B(id=%d)`x other than %s but from the same " "ip address as `Y%s!`x", ch->name, ch->level, obj->value[1], obj->value[0], ch->in_room_vnum(), (int)obj->lastdrop_id, ch->name, ch->name); } } extract_obj( obj ); }else{ // multilog abuse checks if(!IS_NPC(ch)){ if(obj->lastdrop_id!=ch->id && !strcmp(obj->lastdrop_remote_ip,ch->remote_ip_copy)) { multilog_alertf(ch, "`Y%s<%d>`x getting `Gobject `x'%s'<%d>(%d)`x which was originally put where it is being 'got from' (room %d)" "by `Bsomeone (id=%d)`x different than `Y%s`x, but from the same ip address as `Y%s!`x", ch->name, ch->level, obj->short_descr, obj->level, obj->pIndexData?obj->pIndexData->vnum:0, ch->in_room_vnum(), (int)obj->lastdrop_id, ch->name, ch->name); } } obj_to_char( obj, ch ); } return; } /************************************************************************/ // get a random object from the characters inventory OBJ_DATA *get_random_obj( char_data* mob ) { OBJ_DATA *obj_next, *obj, *target=NULL; int now = 0, highest = 0; for ( obj = mob->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if ( obj->wear_loc != WEAR_NONE || !can_drop_obj( mob, obj ) ) continue; if ( ( now = number_percent() ) > highest ) { target = obj; highest = now; } } return target; } /************************************************************************/ void donate(char_data *ch, OBJ_DATA *obj) { if(!CAN_WEAR( obj, OBJWEAR_TAKE) || obj->item_type == ITEM_CORPSE_PC){ act("You can't donate $p.", ch, obj,NULL, TO_CHAR); return; } int room_vnum=0; // confirm the room they are going to donate to exists if (obj->level < 11){ if (obj->item_type == ITEM_WEAPON){ room_vnum=ROOM_VNUM_NEWBIEWEAPON_DONATE; }else if (obj->item_type == ITEM_ARMOR){ room_vnum=ROOM_VNUM_NEWBIEARMOR_DONATE; }else{ room_vnum=ROOM_VNUM_NEWBIEMISC_DONATE; } }else{ if (obj->item_type == ITEM_WEAPON){ room_vnum=ROOM_VNUM_WEAPON_DONATE; }else if (obj->item_type == ITEM_ARMOR){ room_vnum=ROOM_VNUM_ARMOR_DONATE; }else{ room_vnum=ROOM_VNUM_MISC_DONATE; } } room_index_data *room=get_room_index(room_vnum); if(!room){ act(FORMATF("Bug: couldn't find room %d to donate object %d ($p) " "- please inform the admin.", room_vnum, obj->pIndexData?obj->pIndexData->vnum:-1), ch, obj,NULL, TO_CHAR); return; } ch->println("Your donation is greatly appreciated"); ch->printlnf("%s disappears in a puff of smoke.", obj->short_descr); act( "$n donates $p.", ch, obj, NULL, TO_ROOM); obj_from_room(obj); room_index_data *oldroom=ch->in_room; ch->in_room=room; SET_BIT(obj->extra2_flags,OBJEXTRA2_NOSELL); // find the pit in the room OBJ_DATA *pit; for( pit= room->contents; pit; pit= pit->next_content ) { if(pit->pIndexData && pit->pIndexData->vnum==OBJ_VNUM_PIT){ break; } } if(pit){ act( "$p appears in $P.", ch, obj, pit, TO_ROOM); obj->timer=200; // objects donated last around 3 hours irl time obj_to_obj(obj,pit); }else{ act( "$p appears in the room by your feet.", ch, obj, NULL, TO_ROOM); obj_to_room(obj,room); } ch->in_room=oldroom; } /************************************************************************/ // multiroom donation system - by Balo and Kal void do_donate( char_data *ch, char *argument) { OBJ_DATA *obj; char arg[MIL]; OBJ_DATA *obj_next; bool found; sh_int max_don; one_argument( argument, arg); if(IS_NULLSTR(arg)){ ch->println("Donate What?!"); return; } // handle donating a specific item if( str_cmp( arg, "all" ) && str_prefix( "all.", arg ) ) { obj = get_obj_list( ch, arg, ch->in_room->contents ); if (!obj){ ch->printlnf("I don't see any '%s' on the ground here to donate!", arg); return; } donate(ch, obj); return; } // handle donating all { found = false; max_don = 0; for ( obj = ch->in_room->contents; obj; obj = obj_next ) { obj_next = obj->next_content; if(!CAN_WEAR(obj, OBJWEAR_TAKE)){ continue; } if ( ( arg[3] == '\0' || is_name( &arg[4], obj->name ) ) && can_see_obj( ch, obj ) ) { found = true; max_don++; if (max_don > 100) { ch->wrapln("That's a lot of stuff!! Hold up a sec! " "The pipelines in the sky are a little full.. " "give it a sec and try again!"); return; } donate(ch, obj); } } if ( !found ){ ch->println( "I don't see that here."); } } } /************************************************************************/ void do_get( char_data *ch, char *argument) { char arg1[MIL]; char arg2[MIL]; OBJ_DATA *obj; OBJ_DATA *obj_next; OBJ_DATA *container; bool found; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if(!str_cmp(arg2,"from")){ argument = one_argument(argument,arg2); } // Get type. if ( IS_NULLSTR(arg1) ) { ch->println( "Get what?" ); return; } // ooc rooms if(!IS_IMMORTAL(ch) && IS_SET(ch->in_room->room_flags,ROOM_OOC)){ ch->println("Not in an OOC room."); return; } if( IS_NULLSTR(arg2) ) { if ( str_cmp( arg1, "all" ) && str_prefix( "all.", arg1 ) ) { // 'get obj' obj = get_obj_list( ch, arg1, ch->in_room->contents ); if ( obj == NULL ) { act( "I see no $T here.", ch, NULL, arg1, TO_CHAR ); return; } get_obj( ch, obj, NULL); } else { // 'get all' or 'get all.obj' found = false; for ( obj = ch->in_room->contents; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if ( ( arg1[3] == '\0' || is_name( &arg1[4], obj->name ) ) && can_see_obj( ch, obj ) ) { // allow creation of objects with hidden name if(IS_SET( obj->extra_flags, OBJEXTRA_NO_GET_ALL )){ continue; } found = true; get_obj( ch, obj, NULL); } } if ( !found ) { if ( arg1[3] == '\0' ){ ch->println("I see nothing here."); }else{ act( "I see no $T here.", ch, NULL, &arg1[4], TO_CHAR ); } } } } else { // 'get ... container' if ( !str_cmp( arg2, "all" ) || !str_prefix( "all.", arg2 ) ) { ch->println("You can't do that."); ch->println("syntax: get <object> <containing_object>"); return; } if ( ( container = get_obj_here( ch, arg2 ) ) == NULL ) { act( "I see no $T here.", ch, NULL, arg2, TO_CHAR ); return; } // allow creation of objects with hidden name if(IS_SET( container->extra_flags, OBJEXTRA_NO_GET_ALL )){ act( "I see no $T here.", ch, NULL, arg2, TO_CHAR ); return; } switch ( container->item_type ) { default: { ch->printlnf( "%s is not a container.", container->short_descr); if(IS_NEWBIE(ch)){ ch->println( "`Wsyntax:`=C get <what> <container>`x"); } return; } case ITEM_CAULDRON: case ITEM_CONTAINER: case ITEM_FLASK: case ITEM_MORTAR: case ITEM_CORPSE_NPC: break; case ITEM_CORPSE_PC: { if (!can_loot(ch,container)) { ch->println("You can't do that."); return; } } } if ( IS_SET(container->value[1], CONT_CLOSED) ) { act( "The $d is closed.", ch, NULL, container->name, TO_CHAR ); return; } if ( str_cmp( arg1, "all" ) && str_prefix( "all.", arg1 ) ) { // 'get obj container' obj = get_obj_list( ch, arg1, container->contains ); if ( obj == NULL ) { act( "I see nothing like that in the $T.", ch, NULL, arg2, TO_CHAR ); return; } get_obj( ch, obj, container); } else { // 'get all container' or 'get all.obj container' found = false; for ( obj = container->contains; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if ( ( arg1[3] == '\0' || is_name( &arg1[4], obj->name ) ) && can_see_obj( ch, obj ) ) { found = true; if (container->pIndexData->vnum == OBJ_VNUM_PIT && !IS_IMMORTAL(ch)) { ch->println("Don't be so greedy!"); return; } get_obj( ch, obj, container); } } if ( !found ) { if ( arg1[3] == '\0' ){ act( "I see nothing in the $T.", ch, NULL, arg2, TO_CHAR ); }else{ act( "I see nothing like that in the $T.", ch, NULL, arg2, TO_CHAR ); } } } } return; } /************************************************************************/ void do_put( char_data *ch, char *argument ) { char arg1[MIL]; char arg2[MIL]; obj_data *container; obj_data *obj; obj_data *obj_next; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if (!str_cmp(arg2,"in") || !str_cmp(arg2,"on")) argument = one_argument(argument,arg2); if ( arg1[0] == '\0' || arg2[0] == '\0' ) { ch->println("Put what in what?"); return; } // ooc rooms if(!IS_IMMORTAL(ch) && IS_SET(ch->in_room->room_flags,ROOM_OOC)){ ch->println("Not in an OOC room."); return; } if ( !str_cmp( arg2, "all" ) || !str_prefix( "all.", arg2 ) ) { ch->println("You can't do that."); return; } if ( ( container = get_obj_here( ch, arg2 ) ) == NULL ) { act( "I see no $T here.", ch, NULL, arg2, TO_CHAR ); return; } switch ( container->item_type ) { default: ch->printlnf( "%s is not a container.", container->short_descr); if(IS_NEWBIE(ch)){ ch->println( "`Whint?:`=C put <what> <container>`x"); } return; case ITEM_CAULDRON: case ITEM_CONTAINER: case ITEM_FLASK: case ITEM_MORTAR: break; } if ( IS_SET(container->value[1], CONT_CLOSED) ) { act( "The $d is closed.", ch, NULL, container->name, TO_CHAR ); return; } if ( str_cmp( arg1, "all" ) && str_prefix( "all.", arg1 ) ) { // 'put obj container' if ( ( obj = get_obj_carry( ch, arg1 ) ) == NULL ) { ch->println("You do not have that item."); return; } if ( obj == container ) { ch->println("You can't fold it into itself."); return; } if ( !can_drop_obj( ch, obj ) ) { ch->println("You can't let go of it."); return; } if (WEIGHT_MULT(obj) != 100) { ch->println("You have a feeling that would be a bad idea."); return; } if (get_obj_weight(obj) > (container->value[3] * 10)) { ch->printlnf( "%s appears to be too big to ever be put into %s.", obj->short_descr, container->short_descr); return; } if (get_obj_weight( obj ) + get_true_weight( container ) - container->weight > (container->value[0] * 10)) { ch->printlnf( "There doesn't appears to be enough room inside %s to fit %s.`1", container->short_descr, obj->short_descr); return; } if (container->pIndexData->vnum == OBJ_VNUM_PIT && !CAN_WEAR(container,OBJWEAR_TAKE)) { if (obj->timer){ SET_BIT(obj->extra_flags,OBJEXTRA_HAD_TIMER); }else{ obj->timer = number_range(100,200); } } obj_from_char( obj ); obj_to_obj( obj, container ); if (IS_SET(container->value[1],CONT_PUT_ON)) { act("$n puts $p on $P.",ch,obj,container, TO_ROOM); act("You put $p on $P.",ch,obj,container, TO_CHAR); } else { act( "$n puts $p in $P.", ch, obj, container, TO_ROOM ); act( "You put $p in $P.", ch, obj, container, TO_CHAR ); } } else { // PC being ordered to do this if ( !IS_NPC(ch) && IS_SET( ch->dyn, DYN_IS_BEING_ORDERED )) { if ( ch->master ) ch->master->println("Not going to happen."); return; } // 'put all container' or 'put all.obj container' for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if ( ( arg1[3] == '\0' || is_name( &arg1[4], obj->name ) ) && can_see_obj( ch, obj ) && WEIGHT_MULT(obj) == 100 && obj->wear_loc == WEAR_NONE && obj != container && can_drop_obj( ch, obj ) && get_obj_weight( obj ) + get_true_weight( container ) <= (container->value[0] * 10) && get_obj_weight(obj) < (container->value[3] * 10)) { if (container->pIndexData->vnum == OBJ_VNUM_PIT && !CAN_WEAR(obj, OBJWEAR_TAKE) ) if (obj->timer) SET_BIT(obj->extra_flags,OBJEXTRA_HAD_TIMER); else obj->timer = number_range(100,200); obj_from_char( obj ); obj_to_obj( obj, container ); if (IS_SET(container->value[1],CONT_PUT_ON)) { act("$n puts $p on $P.",ch,obj,container, TO_ROOM); act("You put $p on $P.",ch,obj,container, TO_CHAR); } else { act( "$n puts $p in $P.", ch, obj, container, TO_ROOM ); act( "You put $p in $P.", ch, obj, container, TO_CHAR ); } } } } return; } /************************************************************************/ void do_drop( char_data *ch, char *argument) { char arg[MIL]; OBJ_DATA *obj; OBJ_DATA *obj_next; bool found; argument = one_argument( argument, arg ); if ( arg[0] == '\0' ) { ch->println("Drop what?"); return; } // ooc rooms if(!IS_IMMORTAL(ch) && IS_SET(ch->in_room->room_flags,ROOM_OOC)){ ch->println("Not in an OOC room."); return; } if ( is_number( arg ) ) { // 'drop NNNN coins' int amount, gold = 0, silver = 0; amount = atoi(arg); argument = one_argument( argument, arg ); if ( amount <= 0 || ( str_cmp( arg, "coins" ) && str_cmp( arg, "coin" ) && str_cmp( arg, "gold" ) && str_cmp( arg, "silver") ) ) { ch->println("Sorry, you can't do that."); return; } if ( !str_cmp( arg, "coins") || !str_cmp(arg,"coin") || !str_cmp( arg, "silver")) { if (ch->silver < amount) { ch->println("You don't have that much silver."); return; } ch->silver -= amount; silver = amount; } else { if (ch->gold < amount) { ch->println("You don't have that much gold."); return; } ch->gold -= amount; gold = amount; } for ( obj = ch->in_room->contents; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; switch ( obj->pIndexData->vnum ) { case OBJ_VNUM_SILVER_ONE: silver += 1; extract_obj(obj); break; case OBJ_VNUM_GOLD_ONE: gold += 1; extract_obj( obj ); break; case OBJ_VNUM_SILVER_SOME: silver += obj->value[0]; extract_obj(obj); break; case OBJ_VNUM_GOLD_SOME: gold += obj->value[1]; extract_obj( obj ); break; case OBJ_VNUM_COINS: silver += obj->value[0]; gold += obj->value[1]; extract_obj(obj); break; } } obj=create_money( gold, silver ); // record details for multilogging detection if(!IS_NPC(ch)){ obj->lastdrop_id=ch->id; replace_string(obj->lastdrop_remote_ip,ch->remote_ip_copy); } obj_to_room( obj, ch->in_room ); act( "$n drops some coins.", ch, NULL, NULL, TO_ROOM ); ch->println( "OK." ); return; } if ( str_cmp( arg, "all" ) && str_prefix( "all.", arg ) ) { // 'drop obj' if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ){ ch->println( "You do not have that item." ); return; } if ( !can_drop_obj( ch, obj ) ){ ch->println( "You can't let go of it." ); return; } obj_from_char( obj ); // record details for multilogging detection if(!IS_NPC(ch)){ obj->lastdrop_id=ch->id; replace_string(obj->lastdrop_remote_ip, ch->remote_ip_copy); } obj_to_room( obj, ch->in_room ); act( "$n drops $p.", ch, obj, NULL, TO_ROOM ); act( "You drop $p.", ch, obj, NULL, TO_CHAR ); if (IS_OBJ_STAT(obj,OBJEXTRA_MELT_DROP)) { act("$p dissolves into smoke.",ch,obj,NULL,TO_ROOM); act("$p dissolves into smoke.",ch,obj,NULL,TO_CHAR); extract_obj(obj); } } else { // PC being ordered to do this if ( !IS_NPC(ch) && IS_SET( ch->dyn, DYN_IS_BEING_ORDERED )) { if ( ch->master ) ch->master->println("Not going to happen."); return; } // 'drop all' or 'drop all.obj' found = false; for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if ( ( arg[3] == '\0' || is_name( &arg[4], obj->name ) ) && can_see_obj( ch, obj ) && obj->wear_loc == WEAR_NONE && can_drop_obj( ch, obj ) ) { found = true; obj_from_char( obj ); // record details for multilogging detection if(!IS_NPC(ch)){ obj->lastdrop_id=ch->id; replace_string(obj->lastdrop_remote_ip, ch->remote_ip_copy); } obj_to_room( obj, ch->in_room ); act( "$n drops $p.", ch, obj, NULL, TO_ROOM ); act( "You drop $p.", ch, obj, NULL, TO_CHAR ); if (IS_OBJ_STAT(obj,OBJEXTRA_MELT_DROP)) { act("$p dissolves into smoke.",ch,obj,NULL,TO_ROOM); act("$p dissolves into smoke.",ch,obj,NULL,TO_CHAR); extract_obj(obj); } } } if ( !found ) { if ( arg[3] == '\0' ) act( "You are not carrying anything.", ch, NULL, arg, TO_CHAR ); else act( "You are not carrying any $T.", ch, NULL, &arg[4], TO_CHAR ); } } return; } /************************************************************************/ void do_give_new( char_data *ch, char *argument, int silent) { char arg1 [MIL]; char arg2 [MIL]; char buf[MSL]; char_data *victim; OBJ_DATA *obj; argument = one_argument( argument, arg1 ); // what argument = one_argument( argument, arg2 ); // whom // display the help if they don't give enough arguments if ( IS_NULLSTR(arg1) || IS_NULLSTR(arg2) ) { ch->println(""); if(!IS_NULLSTR(arg1) && IS_NULLSTR(arg2)){ ch->printlnf("Give '%s' to who?", arg1); }else{ ch->println( "Give what to whom?"); } ch->println(""); ch->titlebar( "Giving Objects"); ch->println( "Syntax: give <object/what> [to] <person/creature>"); ch->println( "e.g. typing 'give sword guard'"); ch->println( " - will give a sword to a guard, (assuming you are carrying one)."); ch->println( "note: the word 'to' is optional in the give command."); ch->titlebar( "Giving Currency"); // 'give NNNN coins [to] victim' ch->println( "Syntax: give <amount> gold [to] <person/creature>"); ch->println( "e.g. typing 'give 15 silver guard'"); ch->println( " - will give 15 of your silver coins to a guard."); ch->println( "e.g. typing 'give 2 gold guard'"); ch->println( " - will give 2 of your gold coins to a guard."); ch->println( "note: 1 gold is worth 10 silver."); ch->titlebar( ""); return; } // ooc rooms if(!IS_IMMORTAL(ch) && IS_SET(ch->in_room->room_flags,ROOM_OOC)){ ch->println("Not in an OOC room, you can only give objects within the main game realm."); return; } if ( is_number( arg1 ) ) { // 'give NNNN coins [to] victim' int amount; bool silver; amount = atoi(arg1); if ( amount <= 0 || ( str_cmp( arg2, "coins" ) && str_cmp( arg2, "coin" ) && str_cmp( arg2, "gold" ) && str_cmp( arg2, "silver")) ) { ch->println("Sorry, you can't do that."); return; } silver = str_cmp(arg2,"gold"); argument = one_argument( argument, arg2 ); if ( IS_NULLSTR(arg2)) { ch->printlnf( "Give %d %s to whom?", amount, silver?"silver":"gold" ); return; } // using optional 'to' in give command if(!str_cmp("to", arg2)){ argument = one_argument( argument, arg2 ); } // find they person they are giving to if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->printlnf( "You can't seem to find any '%s' here to give %d %s to.", arg2, amount, silver?"silver":"gold"); return; } if(victim==ch){ ch->printlnf("What would be the purpose of giving %d %s to yourself when you already have it?", amount, silver?"silver":"gold"); return; } if (IS_NPC(victim) && IS_SET(victim->act,ACT_IS_CHANGER)) { // check that the money changer can see them if(!can_see(victim,ch)){ ch->println("They can't see you to give you your change."); return; } // check that the money changer isn't subdued if (victim->subdued){ ch->println("They don't appear to be in a state to exchange your money."); return; } // sleeping if (!IS_AWAKE(victim)){ ch->printlnf( "%s is sleeping and can not change your money right now.", PERS(victim, ch)); return; } } if ( (!silver && ch->gold < amount) || (silver && ch->silver < amount) ) { ch->printlnf( "You haven't got %d %s to give!", amount, silver?"silver":"gold"); return; } // make sure victim can carry that much money if (get_carry_weight(victim) + (silver ? get_silver_weight(amount) : get_gold_weight(amount)) > can_carry_w( victim ) ) { act( "$N can't carry that much weight.", ch, NULL, victim, TO_CHAR ); return; } // record details for multilogging detection if( !IS_NPC(ch) && !HAS_CONFIG(ch, CONFIG_IGNORE_MULTILOGINS) && !IS_NPC(victim) && !HAS_CONFIG(victim, CONFIG_IGNORE_MULTILOGINS) ) { if(!strcmp(ch->remote_ip_copy,victim->remote_ip_copy)){ multilog_alertf(victim, "`C%s<%d>`B(id=%d) `xgiving %s%d %s`x to `Y%s<%d>`x (room %d), both from same IP!", ch->name, ch->level, (int)ch->id, silver?"`S":"`Y", amount, silver?"silver":"gold", victim->name, victim->level, ch->in_room_vnum()); } } // exchange the money if (silver){ ch->silver -= amount; victim->silver += amount; }else{ ch->gold -= amount; victim->gold += amount; } if (silent){ sprintf(buf, "SILENTGIVE: %s gives %s %d %s.", ch->name , victim->name, amount, silver ? "silver" : "gold"); wiznet(buf,ch,NULL,WIZ_SECURE,0,get_trust(ch)); sprintf(buf,"You SILENTLY give $N %d %s.",amount, silver ? "silver" : "gold"); act( buf, ch, NULL, victim, TO_CHAR ); }else{ sprintf(buf,"$n gives you %d %s.",amount, silver ? "silver" : "gold"); act( buf, ch, NULL, victim, TO_VICT ); act( "$n gives $N some coins.", ch, NULL, victim, TO_NOTVICT ); sprintf(buf,"You give $N %d %s.",amount, silver ? "silver" : "gold"); act( buf, ch, NULL, victim, TO_CHAR ); // Bribe trigger if ( IS_NPC(victim) && HAS_TRIGGER( victim, TRIG_BRIBE ) ){ mp_bribe_trigger( victim, ch, silver ? amount : amount * 100 ); limit_mobile_wealth(victim); } } // handle money changers giving money back if (IS_NPC(victim) && IS_SET(victim->act,ACT_IS_CHANGER)) { int change; change = (silver ? 95 * amount / 100 / 100 : 95 * amount); if (!silver && change > victim->silver){ victim->silver += change; } if (silver && change > victim->gold){ victim->gold += change; } if (change < 1 && can_see(victim,ch)) { act( "$n tells you 'I'm sorry, you did not give me enough to change.'" ,victim,NULL,ch,TO_VICT); sprintf(buf,"%d %s %s", amount, silver ? "silver" : "gold",ch->name); do_give_new(victim,buf, silent); } else if (can_see(victim,ch)) { sprintf(buf,"%d %s %s", change, silver ? "gold" : "silver",ch->name); do_give_new(victim,buf, silent); if (silver) { sprintf(buf,"%d silver %s", (95 * amount / 100 - change * 100),ch->name); do_give_new(victim,buf, silent); } act("$n tells you 'Thank you, come again.'", victim,NULL,ch,TO_VICT); limit_mobile_wealth(victim); } } return; } // end of code which deals with giving money // === GIVING OBJECTS CODE // give <object> [to] <victim> // using optional 'to' in give command if(!str_cmp("to", arg2)){ argument = one_argument( argument, arg2 ); } // find the object if ( ( obj = get_obj_carry( ch, arg1 ) ) == NULL ) { ch->printlnf( "You are not carrying any '%s' to give to '%s'.", arg1, arg2 ); return; } if ( obj->wear_loc != WEAR_NONE ) { ch->printlnf( "You are currently using '%s', you must remove it before giving it to '%s'.", obj->short_descr, arg2 ); return; } // find the victim to receive the item if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->printlnf( "You can't seem to find any '%s' here to give '%s' to.", arg2, obj->short_descr); return; } if(victim==ch){ ch->printlnf("What would be the purpose of giving %s to yourself?", obj->short_descr); return; } if (IS_NPC(victim) && victim->pIndexData->pShop != NULL) { // if they are a shop keeper without a give trigger which // would catch the object, don't accept the item if(!mp_would_run_give_trigger(victim, ch, obj )){ act("$N tells you 'Sorry, you'll have to sell that.'", ch,NULL,victim,TO_CHAR); return; } } if ( !can_drop_obj( ch, obj ) ) { ch->printlnf( "You can't let go of %s.", obj->short_descr ); return; } if ( !IS_CONTROLLED(victim) && victim->carry_number + get_obj_number( obj ) > can_carry_n( victim ) ) { act( "$N has $S hands full.", ch, NULL, victim, TO_CHAR ); return; } if (!IS_CONTROLLED(victim) && get_carry_weight(victim) + get_obj_weight(obj) > can_carry_w( victim ) ) { act( "$N can't carry that much weight.", ch, NULL, victim, TO_CHAR ); return; } if ( !can_see_obj( victim, obj ) ) { act( FORMATF("$N can't seem to see %s.", obj->short_descr), ch, NULL, victim, TO_CHAR ); return; } obj_from_char( obj ); // check lastgive details for multilogging detection if(!IS_NPC(victim) && !HAS_CONFIG(ch, CONFIG_IGNORE_MULTILOGINS) && !HAS_CONFIG(victim, CONFIG_IGNORE_MULTILOGINS)){ // player giving objects to itself via another player or mob if( obj->lastdrop_id!=victim->id && !strcmp(obj->lastdrop_remote_ip, victim->remote_ip_copy)) { multilog_alertf(victim, "`M%s<%d>`x giving `Gobject '%s' (%d)`x to `Y%s<%d>`x (room %d), which was recently given to " "`M%s`x by `Bsomeone (id=%d)`x other than `Y%s`x from the same ip as `Y%s!`x", ch->name, ch->level, obj->short_descr, obj->pIndexData?obj->pIndexData->vnum:0, victim->name, victim->level, ch->in_room_vnum(), ch->name, (int)obj->lastdrop_id, victim->name, victim->name); // player giving directly to another of their players }else if(!strcmp(ch->remote_ip_copy, victim->remote_ip_copy)){ multilog_alertf(ch, "`C%s<%d>`B(id=%d) `xgiving `Gobject '%s' (%d) `xto `Y%s<%d>`x (room%d) - object exchange between players from the same IP!", ch->name, ch->level, (int)ch->id, obj->short_descr, obj->pIndexData?obj->pIndexData->vnum:0, victim->name, victim->level, ch->in_room_vnum()); } } // record host of giver on object if not a mob if(!IS_NPC(ch)){ obj->lastdrop_id=ch->id; replace_string(obj->lastdrop_remote_ip, ch->remote_ip_copy); } obj_to_char( obj, victim ); if (silent) { sprintf(buf, "SILENTGIVE: %s gives %s to %s.", ch->name, obj->short_descr, victim->name); wiznet(buf,ch,NULL,WIZ_SECURE,0,get_trust(ch)); act( "You SILENTLY give $p to $N.", ch, obj, victim, TO_CHAR ); } else { MOBtrigger = false; act( "$n gives $p to $N.", ch, obj, victim, TO_NOTVICT ); act( "$n gives you $p.", ch, obj, victim, TO_VICT ); act( "You give $p to $N.", ch, obj, victim, TO_CHAR ); MOBtrigger = true; } // Give mobprog trigger if ( IS_NPC(victim) && HAS_TRIGGER( victim, TRIG_GIVE ) ){ mp_give_trigger( victim, ch, obj ); } } // normal give void do_give( char_data *ch, char *argument ) { do_give_new(ch, argument, false); } // silent give void do_sgive( char_data *ch, char *argument ) { do_give_new(ch, argument, true); } /************************************************************************/ /* * Take stuff and money from subdued or sleeping characters * Written by Quenralther and Kalahn - Dec 97 */ void do_grab( char_data *ch, char *argument ) { char arg1 [MIL]; char arg2 [MIL]; char buf[MSL]; char_data *victim; OBJ_DATA *obj; int random; if( IS_OOC(ch) ) { ch->println("You may not use grab in an ooc area."); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' || arg2[0] == '\0' ) { ch->println("Take what from whom?"); return; } if ( is_number( arg1 ) ) { // 'give NNNN coins victim' int amount; bool silver; amount = atoi(arg1); if ( amount <= 0 || ( str_cmp( arg2, "coins" ) && str_cmp( arg2, "coin" ) && str_cmp( arg2, "gold" ) && str_cmp( arg2, "silver")) ) { ch->println("Sorry, you can't do that."); return; } silver = str_cmp(arg2,"gold"); argument = one_argument( argument, arg2 ); if ( arg2[0] == '\0' ) { ch->println("Take what from whom?"); return; } if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->println("They aren't here."); return; } if IS_AWAKE(victim) { ch->println("You can't grab stuff from someone who's awake."); return; } if (IS_IMMORTAL(victim)) { ch->println("You failed."); return; } if (is_safe(ch,victim)) { return; } #ifdef unix if (!IS_IMMORTAL(ch)) { WAIT_STATE( ch, PULSE_VIOLENCE ); } #endif if ((victim->position == POS_SLEEPING && !IS_IMMORTAL(ch) && (!IS_AFFECTED(victim, AFF_SLEEP) || (!is_same_group(ch, victim) && number_range(1,5)==1) || number_range(1,15)==1) ) || (victim->position<=POS_SLEEPING && IS_KEEPER(victim) && !IS_IMMORTAL(ch)) ) { random = dice(1,100); if (IS_KEEPER(victim) || ( random < 70 + victim->level-ch->level-ch->modifiers[STAT_QU]/5 + victim->modifiers[STAT_IN]/5) ) { // remove sleep spell if necessary if ( IS_AFFECTED(ch, AFF_SLEEP) ){ affect_strip( ch, gsn_sleep ); } victim->position = POS_RESTING; act("$n tried to take some coins from $N, who wakes up.",ch,NULL,victim,TO_NOTVICT ); act("You are awakened by $N trying to take some coins from you.",victim,NULL,ch,TO_CHAR); act("Your attempts have woken $N!",ch,NULL,victim,TO_CHAR); // wiznet thefts messages sprintf(buf,"$N <%d> tried to grab %d coins from %s <%d> and woke them up!", ch->level, amount, victim->name, victim->level); wiznet(buf,ch,NULL,WIZ_THEFTS,0,0); return; } random = dice(1,100); if ( random < 75-ch->level+victim->level ) { act("$n couldn't manage to pry any coins away from $N.",ch,NULL,victim,TO_NOTVICT ); act("You couldn't manage to pry any coins away from $N.",ch,NULL,victim,TO_CHAR); // wiznet thefts message sprintf(buf,"$N tried to grab %d coins from %s <%d> and failed.", amount, victim->name, victim->level); wiznet(buf,ch,NULL,WIZ_THEFTS,0,0); return; } } // endif they are in the sleeping position... if they are below that you can // always take everything if (!silver && victim->gold < amount) { amount = victim->gold; // wiznet thefts messages sprintf(buf,"$N <%d> took using grab %d gold coins from %s <%d>.", ch->level, amount, victim->name, victim->level); wiznet(buf,ch,NULL,WIZ_THEFTS,0,0); } if (silver && victim->silver < amount) { amount = victim->silver; // wiznet thefts messages sprintf(buf,"$N <%d> took using grab %d silver coins from %s <%d>.", ch->level, amount, victim->name, victim->level); wiznet(buf,ch,NULL,WIZ_THEFTS,0,0); return; } if (silver) { victim->silver -= amount; ch->silver += amount; } else { victim->gold -= amount; ch->gold += amount; } if (victim->position > POS_SLEEPING) { act( "$n took some coins from you.", ch, NULL, victim, TO_VICT); } act( "$n takes some coins from $N.", ch, NULL, victim, TO_NOTVICT ); sprintf(buf,"You take %d %s from $N.",amount, silver ? "silver" : "gold"); act( buf, ch, NULL, victim, TO_CHAR ); return; } // end of coins if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->println("They aren't here."); return; } if (IS_AWAKE(victim)) { ch->println("You can't grab stuff from someone who's awake."); return; } if (IS_IMMORTAL(victim)) { ch->println("You failed."); return; } obj = get_obj_carry_for_looker( victim, arg1, ch ); // find the object in victims inventory if ( !obj) // not in their inventory check if they are wearing it { if ((obj = get_obj_wear(victim, arg1)) != NULL) { if ( IS_SET(obj->extra_flags, OBJEXTRA_NOREMOVE )) { ch->println("You can't wrench it away...it's stuck somehow."); return; } } } if (!obj) // check if nothing was found { ch->println("You can't find that item on their person."); return; } #ifdef unix if (!IS_IMMORTAL(ch)) { WAIT_STATE( ch, PULSE_VIOLENCE ); } #endif if ((victim->position == POS_SLEEPING && !IS_IMMORTAL(ch) && (!IS_AFFECTED(victim, AFF_SLEEP) || (!is_same_group(ch, victim) && number_range(1,5)==1) || number_range(1,15)==1) ) || (victim->position<=POS_SLEEPING && IS_KEEPER(victim) && !IS_IMMORTAL(ch)) ) { random = dice(1,100); if (IS_KEEPER(victim) ||( random < 90 + victim->level - ch->level - ch->modifiers[STAT_AG]/10+victim->modifiers[STAT_IN]/5 ) ) { /* if ( victim->position == POS_SLEEPING && (!IS_AFFECTED(victim, AFF_SLEEP) || (!is_same_group(ch, victim) && number_range(1,5)==1) || number_range(1,15)==1 ) ) { random = dice(1,100); if ( random < 90 + victim->level - ch->level - ch->modifiers[STAT_AG]/10+victim->modifiers[STAT_IN]/5 ) { */ victim->position = POS_RESTING; act("$n tried to take something from $N, who wakes up.",ch,NULL,victim,TO_NOTVICT ); act("You are awakened by $N trying to take something from you.",victim,NULL,ch,TO_CHAR); act("Your attempts have woken $N!",ch,NULL,victim,TO_CHAR); // wiznet thefts messages sprintf(buf,"$N <%d> tried to grab $p from %s <%d> and woke them up!", ch->level, victim->name, victim->level); wiznet(buf,ch, obj,WIZ_THEFTS,0,0); return; } random = dice(1,100); if ( random < 100-ch->level+victim->level-ch->modifiers[STAT_ST]/5+victim->modifiers[STAT_ST]/5 ) { act("$n couldn't manage to pry anything away from $N.",ch,NULL,victim,TO_NOTVICT ); act("You couldn't manage to pry anything away from $N.",ch,NULL,victim,TO_CHAR); // wiznet thefts messages sprintf(buf,"$N <%d> tried to grab $p from %s <%d> but failed to get it!", ch->level, victim->name, victim->level); wiznet(buf,ch, obj,WIZ_THEFTS,0,0); return; } } if (is_safe(ch,victim)) { return; } if ( !can_drop_obj( victim, obj ) ) { ch->println("You can't wrench it away...it's stuck somehow."); // wiznet thefts messages sprintf(buf,"$N <%d> tried to grab $p from %s <%d> but couldn't wrench it away.", ch->level, victim->name, victim->level); wiznet(buf,ch, obj,WIZ_THEFTS,0,0); return; } if ( ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ) ) { ch->println("You have your hands full."); return; } if ( ch->carry_weight + get_obj_weight( obj ) > can_carry_w( ch ) ) { ch->println("You can't carry that much weight."); return; } // object exchanges hands now obj_from_char( obj ); obj_to_char( obj, ch ); act( "$n takes $p from $N.", ch, obj, victim, TO_NOTVICT ); if ( victim->position > POS_SLEEPING ) { act( "$n takes $p from you.", ch, obj, victim, TO_VICT ); } act( "You take $p from $N.", ch, obj, victim, TO_CHAR ); // wiznet thefts messages sprintf(buf,"$N <%d> grabbed $p from %s <%d> successfully.", ch->level, victim->name, victim->level); wiznet(buf,ch, obj,WIZ_THEFTS,0,0); return; } /************************************************************************/ /* for poisoning weapons and food/drink */ void do_envenom(char_data *ch, char *argument) { OBJ_DATA *obj; AFFECT_DATA af; int percent,skill; /* find out what */ if (IS_NULLSTR(argument)) { ch->println("Envenom what item?"); return; } obj = get_obj_list(ch,argument,ch->carrying); if (obj== NULL) { ch->println("You don't have that item."); return; } if ((skill = get_skill(ch,gsn_envenom)) < 1) { ch->println("Are you crazy? You'd poison yourself!"); return; } if (obj->item_type == ITEM_FOOD || obj->item_type == ITEM_DRINK_CON) { if (number_percent() < skill) // success! { act("$n treats $p with deadly poison.",ch,obj,NULL,TO_ROOM); act("You treat $p with deadly poison.",ch,obj,NULL,TO_CHAR); if (!obj->value[3]) { obj->value[3] = 1; check_improve(ch,gsn_envenom,true,4); } WAIT_STATE(ch,skill_table[gsn_envenom].beats); return; } act("You fail to poison $p.",ch,obj,NULL,TO_CHAR); if (!obj->value[3]) { check_improve(ch,gsn_envenom,false,4); } WAIT_STATE(ch,skill_table[gsn_envenom].beats); return; } if ( obj->item_type == ITEM_WEAPON ) { if (IS_WEAPON_STAT( obj,WEAPON_FLAMING ) || IS_WEAPON_STAT( obj,WEAPON_FROST ) || IS_WEAPON_STAT( obj,WEAPON_VAMPIRIC ) || IS_WEAPON_STAT( obj,WEAPON_SHOCKING ) || IS_WEAPON_STAT( obj,WEAPON_HOLY )) { act("You can't seem to envenom $p.",ch,obj,NULL,TO_CHAR); return; } if (obj->value[3] < 0 || attack_table[obj->value[3]].damage == DAM_BASH) { ch->println("You can only envenom edged weapons."); return; } if (IS_WEAPON_STAT(obj,WEAPON_POISON)) { act("$p is already envenomed.",ch,obj,NULL,TO_CHAR); return; } percent = number_percent(); if (percent < skill) { af.where = WHERE_WEAPON; af.type = gsn_poison; af.level = ch->level; af.duration = ch->level / 4; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = WEAPON_POISON; affect_to_obj(obj,&af); act("$n coats $p with deadly venom.",ch,obj,NULL,TO_ROOM); act("You coat $p with venom.",ch,obj,NULL,TO_CHAR); check_improve(ch,gsn_envenom,true,3); WAIT_STATE(ch,skill_table[gsn_envenom].beats); return; } else { act("You fail to envenom $p.",ch,obj,NULL,TO_CHAR); check_improve(ch,gsn_envenom,false,3); WAIT_STATE(ch,skill_table[gsn_envenom].beats); return; } } act("You can't poison $p.",ch,obj,NULL,TO_CHAR); return; } /**************************************************************************/ void do_fill( char_data *ch, char *argument ) { char arg[MIL]; char buf[MSL]; OBJ_DATA *obj; OBJ_DATA *fountain; bool found; one_argument( argument, arg ); if ( arg[0] == '\0' ) { ch->println("Fill what?"); return; } if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { ch->println("You do not have that item."); return; } found = false; for ( fountain = ch->in_room->contents; fountain != NULL; fountain = fountain->next_content ) { if ( fountain->item_type == ITEM_FOUNTAIN ) { found = true; break; } } if ( !found ) { ch->println("There is no fountain here!"); return; } // if the fountain is empty you shouldn't be able to fill a drinkcontainer if ( fountain->value[1] == 0 ) { act( "$p is empty.", ch, fountain, NULL, TO_CHAR ); return; } if ( obj->item_type != ITEM_DRINK_CON ) { ch->println("You can't fill that."); return; } if ( obj->value[1] != 0 && obj->value[2] != fountain->value[2] ) { ch->println("There is already another liquid in it."); return; } if ( obj->value[1] >= obj->value[0] ) { ch->println("Your container is full."); return; } // decrement the fountain by the fill amount // if it isn't an infinite fountain if(fountain->value[1]>=0){ fountain->value[1] -= (obj->value[0] - obj->value[1]); // in case -1 is unlimited etc if ( fountain->value[1] < 0 ){ fountain->value[1] = 0; } } sprintf(buf,"You fill $p with %s from $P.", liq_table[fountain->value[2]].liq_name); act( buf, ch, obj,fountain, TO_CHAR ); sprintf(buf,"$n fills $p with %s from $P.", liq_table[fountain->value[2]].liq_name); act(buf,ch,obj,fountain,TO_ROOM); obj->value[2] = fountain->value[2]; obj->value[1] = obj->value[0]; return; } /**************************************************************************/ void do_pour (char_data *ch, char *argument) { char arg[MSL],buf[MSL], outbuf[MSL]; OBJ_DATA *out, *in; char_data *vch = NULL; int amount; argument = one_argument(argument,arg); if (IS_NULLSTR(arg)|| IS_NULLSTR(argument)) { ch->println("Pour what into what?"); ch->println("Note: to empty a liquid container type `=Cempty <container_name>`x"); return; } if ((out = get_obj_carry(ch,arg)) == NULL) { ch->println("You don't have that item." ); return; } if (out->item_type != ITEM_DRINK_CON) { ch->println("That's not a drink container." ); return; } sprintf(outbuf,argument); one_argument(outbuf,outbuf); if (!str_cmp(outbuf,"out")) { if (out->value[1] == 0) { ch->println("It's already empty." ); return; } out->value[1] = 0; out->value[3] = 0; sprintf(buf,"You invert $p, spilling %s all over the ground.", liq_table[out->value[2]].liq_name); act(buf,ch,out,NULL,TO_CHAR); sprintf(buf,"$n inverts $p, spilling %s all over the ground.", liq_table[out->value[2]].liq_name); act(buf,ch,out,NULL,TO_ROOM); return; } if ((in = get_obj_here(ch,argument)) == NULL) { vch = get_char_room(ch,argument); if (vch == NULL) { ch->println("Pour into what?" ); return; } in = get_eq_char(vch,WEAR_HOLD); if (in == NULL) { ch->println("They aren't holding anything." ); return; } } if (in->item_type != ITEM_DRINK_CON) { ch->println("You can only pour into other drink containers." ); return; } if (in == out) { ch->println("You cannot change the laws of physics!"); return; } if (in->value[1] != 0 && in->value[2] != out->value[2]) { ch->println("They don't hold the same liquid."); return; } if (out->value[1] == 0) { act("There's nothing in $p to pour.",ch,out,NULL,TO_CHAR); return; } if (in->value[1] >= in->value[0]) { act("$p is already filled to the top.",ch,in,NULL,TO_CHAR); return; } amount = UMIN(out->value[1],in->value[0] - in->value[1]); in->value[1] += amount; out->value[1] -= amount; in->value[2] = out->value[2]; if (vch == NULL) { sprintf(buf,"You pour %s from $p into $P.", liq_table[out->value[2]].liq_name); act(buf,ch,out,in,TO_CHAR); sprintf(buf,"$n pours %s from $p into $P.", liq_table[out->value[2]].liq_name); act(buf,ch,out,in,TO_ROOM); } else { sprintf(buf,"You pour some %s for $N.", liq_table[out->value[2]].liq_name); act(buf,ch,NULL,vch,TO_CHAR); sprintf(buf,"$n pours you some %s.", liq_table[out->value[2]].liq_name); act(buf,ch,NULL,vch,TO_VICT); sprintf(buf,"$n pours some %s for $N.", liq_table[out->value[2]].liq_name); act(buf,ch,NULL,vch,TO_NOTVICT); } } /**************************************************************************/ void do_drink( char_data *ch, char *argument ) { char arg[MIL]; OBJ_DATA *obj; int amount; int liquid; int max_liq; for(max_liq=0; !IS_NULLSTR(liq_table[max_liq].liq_name); max_liq++){ } max_liq--; one_argument( argument, arg ); if ( arg[0] == '\0' ) { for ( obj = ch->in_room->contents; obj; obj = obj->next_content ) { if ( obj->item_type == ITEM_FOUNTAIN ) break; } if ( obj == NULL ) { ch->println( "Drink what?" ); return; } } else { if ( ( obj = get_obj_here( ch, arg ) ) == NULL ) { ch->println( "You can't find it." ); return; } } if ( !IS_NPC(ch) && ch->pcdata->condition[COND_DRUNK] > 10 ) { ch->println( "You fail to reach your mouth. *Hic*" ); return; } switch ( obj->item_type ) { default: ch->println( "You can't drink from that." ); return; case ITEM_FOUNTAIN: case ITEM_DRINK_CON: if ( obj->value[1]== 0 ){ ch->println( "It is already empty." ); return; } liquid = obj->value[2]; if ( liquid < 0 || liquid>max_liq) { bugf( "Do_drink: bad liquid number %d.", liquid ); autonote(NOTE_SNOTE, "do_drink()", "bad liquid number", "imm", FORMATF("Do_drink: bad liquid number %d, on object %d (%s), value reset to 0..", liquid, obj->pIndexData?obj->pIndexData->vnum:0, obj->short_descr ), true); liquid = obj->value[2] = 0; } amount = liq_table[liquid].liq_affect[4]; if(obj->item_type==ITEM_FOUNTAIN){ // naturally drink more from a fountain amount*=3; } amount = UMIN(amount, obj->value[1]); break; } if (!IS_NPC(ch) && !IS_IMMORTAL(ch) && ch->pcdata->condition[COND_FULL] > 45) { ch->println( "You're too full to drink more." ); return; } act( "$n drinks $T from $p.", ch, obj, liq_table[liquid].liq_name, TO_ROOM ); act( "You drink $T from $p.", ch, obj, liq_table[liquid].liq_name, TO_CHAR ); gain_condition( ch, COND_DRUNK, amount * liq_table[liquid].liq_affect[COND_DRUNK] / 36 ); gain_condition( ch, COND_FULL, amount * liq_table[liquid].liq_affect[COND_FULL] / 7 ); gain_condition( ch, COND_THIRST, amount * liq_table[liquid].liq_affect[COND_THIRST] / 10 ); gain_condition(ch, COND_HUNGER, amount * liq_table[liquid].liq_affect[COND_HUNGER] / 2 ); if ( !IS_NPC(ch) && ch->pcdata->condition[COND_DRUNK] > 10 ) ch->println("You feel drunk."); if ( !IS_NPC(ch) && ch->pcdata->condition[COND_FULL] > 40 ) ch->println("You are full."); if ( !IS_NPC(ch) && ch->pcdata->condition[COND_THIRST] > 40 ) ch->println("Your thirst is quenched."); if ( obj->value[3] != 0 && !HAS_CLASSFLAG(ch, CLASSFLAG_POISON_IMMUNITY) ) { // The drink was poisoned! AFFECT_DATA af; act( "$n chokes and gags.", ch, NULL, NULL, TO_ROOM ); ch->println("You choke and gag."); af.where = WHERE_AFFECTS; af.type = gsn_poison; af.level = number_fuzzy(amount); af.duration = 3 * amount; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_POISON; affect_join( ch, &af ); } // containers with -1 are infinite, so don't remove the amount. if(obj->value[1]>0){ obj->value[1] -= amount; // remove the poison if it is emptied if(obj->value[1]<=0){ obj->value[3]=0; obj->value[1]=0; } } } /**************************************************************************/ void do_eat( char_data *ch, char *argument ) { char arg[MIL]; OBJ_DATA *obj; one_argument( argument, arg ); if ( arg[0] == '\0' ) { ch->println("Eat what?"); return; } if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { ch->println("You do not have that item."); return; } if ( ch->level<LEVEL_IMMORTAL ) { if ( obj->item_type != ITEM_FOOD && obj->item_type != ITEM_PILL ) { ch->println("That's not edible."); return; } if ( !IS_NPC(ch) && ch->pcdata->condition[COND_FULL] > 40 && obj->value[0]!=0 && obj->value[1]!=0 ) { ch->println("You are too full to eat more."); return; } } act( "$n eats $p.", ch, obj, NULL, TO_ROOM ); act( "You eat $p.", ch, obj, NULL, TO_CHAR ); switch ( obj->item_type ) { case ITEM_FOOD: if ( !IS_NPC(ch) ) { int condition; condition = ch->pcdata->condition[COND_HUNGER]; gain_condition( ch, COND_HUNGER, obj->value[0] ); gain_condition( ch, COND_FULL, obj->value[1]); if ( condition == 0 && ch->pcdata->condition[COND_HUNGER] > 0 ) ch->println("You are no longer hungry."); else if ( ch->pcdata->condition[COND_FULL] > 40 ) ch->println("You are full."); } if ( obj->value[3] != 0 && !HAS_CLASSFLAG(ch, CLASSFLAG_POISON_IMMUNITY)) { // The food was poisoned!- do a saving throw if ( saves_spell( number_fuzzy(obj->value[0])*2, ch, DAM_POISON)) { act( "$n turns pale for a moment.", ch, 0, 0, TO_ROOM ); ch->println("You feel a little sick for a moment but it passes."); }else{ AFFECT_DATA af; act( "$n chokes and gags.", ch, 0, 0, TO_ROOM ); ch->println("You choke and gag."); af.where = WHERE_AFFECTS; af.type = gsn_poison; af.level = number_fuzzy(obj->value[0]); af.duration = 2 * obj->value[0]; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_POISON; affect_join( ch, &af ); } } break; case ITEM_PILL: if ( IS_SET( ch->in_room->room_flags, ROOM_ANTIMAGIC )) { ch->println("Nothing seemed to happen."); extract_obj( obj ); return; } obj_cast_spell( obj->value[1], obj->value[0], ch, ch, NULL ); obj_cast_spell( obj->value[2], obj->value[0], ch, ch, NULL ); obj_cast_spell( obj->value[3], obj->value[0], ch, ch, NULL ); obj_cast_spell( obj->value[4], obj->value[0], ch, ch, NULL ); if (ch->fighting){ WAIT_STATE( ch, 2*PULSE_VIOLENCE ); }else{ WAIT_STATE( ch, 3*PULSE_VIOLENCE/2 ); } break; } extract_obj( obj ); return; } /**************************************************************************/ // Remove an object, return true if object in wear location has been removed bool remove_obj( char_data *ch, int iWear, bool fReplace ) { OBJ_DATA *obj; if ( ( obj = get_eq_char( ch, iWear ) ) == NULL ) return true; if ( !fReplace ) return false; if ( !IS_IMMORTAL(ch) && IS_SET(obj->extra_flags, OBJEXTRA_NOREMOVE) ) { act( "You can't remove $p.", ch, obj, NULL, TO_CHAR ); return false; } if (obj->wear_loc==WEAR_SECONDARY){ act( "You stop using $p as your offhand weapon.", ch, obj, NULL, TO_CHAR ); }else if (!IS_SET(obj->extra_flags,OBJEXTRA_LODGED)){ act( "You stop using $p.", ch, obj, NULL, TO_CHAR ); } if ( IS_SET( obj->extra_flags, OBJEXTRA_LODGED )) { REMOVE_BIT( obj->extra_flags, OBJEXTRA_LODGED ); if ( get_eq_char( ch, WEAR_LODGED_ARM )) { act( "With a tug you dislodge $p from your arm.", ch, obj, NULL, TO_CHAR ); act( "With a tug, $n dislodges $p from $s arm.", ch, obj, NULL, TO_ROOM ); ch->hit -= obj->level / 4; obj->wear_loc = -1; return true; } else if ( get_eq_char( ch, WEAR_LODGED_LEG )) { act( "With a good yank you dislodge $p from your leg.", ch, obj, NULL, TO_CHAR ); act( "With a good yank, $n dislodges $p from $s leg.", ch, obj, NULL, TO_ROOM ); ch->hit -= obj->level / 5; ch->move -= obj->level / 2; obj->wear_loc = -1; return true; } else if ( get_eq_char( ch, WEAR_LODGED_RIB )) { act( "With a wrenching pull you dislodge $p from your chest.", ch, obj, NULL, TO_CHAR ); act( "With a wrenching pull, $n dislodges $p from $s chest.", ch, obj, NULL, TO_ROOM ); ch->hit -= obj->level / 2; obj->wear_loc = -1; return true; } }else{ act( "$n stops using $p.", ch, obj, NULL, TO_ROOM ); } unequip_char( ch, obj ); return true; } /**************************************************************************/ /* * Wear one object. * Optional replacement of existing objects. * Big repetitive code, ick. */ void wear_obj( char_data *ch, OBJ_DATA *obj, bool fReplace, bool hold ) { obj_data *existing_primary_position; // used for object wearing preference system // --- object wearing preference system works as follows: // if 'ch' is wearing 2 items in a particular wear location // (e.g. WEAR_FINGER_L, WEAR_FINGER_R), and try to wear an object // into that wear location, the code will favour replacing the item // which doesn't have the same vnum as the object about to be put on. // The effect of this, is you can type 'wear golden', 'wear golden'... // and you would replace both of your rings with golden rings... // instead of the second 'wear golden' replacing what you just // wore using the first 'wear golden'. // - Kal, Sept 03 // do check if objects level is LEVEL_IMMORTAL or higher, and it is a // mortal trying to wear the object, remove it from them. if (( obj->level>LEVEL_HERO)&&(ch->level < LEVEL_IMMORTAL)) { char buf[MSL]; sprintf( buf, "`x%s (%s) lvl %d`1tried to wear `1%s [%d] lvl %d`1It was removed since it was out of level.", ch->name, ch->short_descr, ch->level, obj->short_descr, obj->pIndexData->vnum, obj->level); autonote(NOTE_SNOTE, "p_anote()","`Yoverlevel object!`x", "imm", buf, true); ch->printlnf( "You try to use %s and it crumbles to dust.", obj->short_descr ); act( "$n tries to use $p, but it crumbles to dust.", ch, obj, NULL, TO_ROOM ); extract_obj(obj); return; } if ( IS_SET( obj->attune_flags, ATTUNE_NEED_TO_USE )) { if ( ch->id != obj->attune_id ) { act( "You cannot use $p until you have attuned yourself to it.", ch, obj, NULL, TO_CHAR ); return; } } if(IS_SET(obj->extra_flags, OBJEXTRA_MAGIC) && HAS_CLASSFLAG(ch, CLASSFLAG_MAGIC_ANTIPATHY)) { act("You have great antipathy towards $p.",ch,obj,NULL,TO_CHAR); return; } if ( !IS_ADMIN( ch )) // Immortal requested not to have this but I wanted it :) { if(!IS_NPC(ch) && obj->pIndexData->relative_size< race_table[ch->race]->low_size && obj->item_type != ITEM_LIGHT && !CAN_WEAR( obj, OBJWEAR_HOLD) && !CAN_WEAR( obj, OBJWEAR_FLOAT) ) { act("$p is too small for you.",ch,obj,NULL,TO_CHAR); return; } if(!IS_NPC(ch) && obj->pIndexData->relative_size> race_table[ch->race]->high_size && obj->item_type != ITEM_LIGHT && !CAN_WEAR( obj, OBJWEAR_FLOAT) ) { act("$p is too large for you.", ch, obj, NULL, TO_CHAR); return; } } if ( !IS_IMMORTAL( ch )) { if(DISALLOWED_OBJECT_FOR_CHAR(obj, ch)) { act("$p cannot be used by your class.",ch,obj,NULL,TO_CHAR); return; } } if ( obj->item_type == ITEM_LIGHT ) { if ( !remove_obj( ch, WEAR_LIGHT, fReplace ) ) return; act( "$n lights $p and holds it.", ch, obj, NULL, TO_ROOM ); act( "You light $p and hold it.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_LIGHT ); return; } if ( CAN_WEAR( obj, OBJWEAR_FINGER ) ) { // remove something from the fingers to make way for the item about to go on if necessary existing_primary_position=get_eq_char( ch, WEAR_FINGER_L ); if ( existing_primary_position && get_eq_char( ch, WEAR_FINGER_R )) { if(existing_primary_position->pIndexData && obj->pIndexData && existing_primary_position->pIndexData->vnum==obj->pIndexData->vnum) { // favour replacing the secondary position item over doing an exact swap if( !remove_obj( ch, WEAR_FINGER_R, fReplace ) &&!remove_obj( ch, WEAR_FINGER_L, fReplace ) ){ return; } }else{ if( !remove_obj( ch, WEAR_FINGER_L, fReplace ) &&!remove_obj( ch, WEAR_FINGER_R, fReplace ) ){ return; } } } if ( get_eq_char( ch, WEAR_FINGER_L ) == NULL ) { act( "$n wears $p on $s left finger.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your left finger.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_FINGER_L ); return; } if ( get_eq_char( ch, WEAR_FINGER_R ) == NULL ) { act( "$n wears $p on $s right finger.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your right finger.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_FINGER_R ); return; } bug( "Wear_obj: no free finger."); ch->println("You already wear two rings."); return; } if ( CAN_WEAR( obj, OBJWEAR_NECK ) ) { // remove something from the neck to make way for the item about to go on if necessary existing_primary_position=get_eq_char( ch, WEAR_NECK_1 ); if ( existing_primary_position && get_eq_char( ch, WEAR_NECK_2 )) { if(existing_primary_position->pIndexData && obj->pIndexData && existing_primary_position->pIndexData->vnum==obj->pIndexData->vnum) { // favour replacing the secondary position item over doing an exact swap if( !remove_obj( ch, WEAR_NECK_2, fReplace ) &&!remove_obj( ch, WEAR_NECK_1, fReplace ) ){ return; } }else{ if( !remove_obj( ch, WEAR_NECK_1, fReplace ) &&!remove_obj( ch, WEAR_NECK_2, fReplace ) ){ return; } } } // put the item onto the free wear position if ( get_eq_char( ch, WEAR_NECK_1 ) == NULL ) { act( "$n wears $p around $s neck.", ch, obj, NULL, TO_ROOM ); act( "You wear $p around your neck.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_NECK_1 ); return; } if ( get_eq_char( ch, WEAR_NECK_2 ) == NULL ) { act( "$n wears $p around $s neck.", ch, obj, NULL, TO_ROOM ); act( "You wear $p around your neck.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_NECK_2 ); return; } bug("Wear_obj: no free neck."); ch->println("You already wear two neck items."); return; } if ( CAN_WEAR( obj, OBJWEAR_TORSO ) ) { if ( !remove_obj( ch, WEAR_TORSO, fReplace ) ) return; act( "$n wears $p on $s torso.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your torso.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_TORSO ); return; } if ( CAN_WEAR( obj, OBJWEAR_HEAD ) ) { if ( !remove_obj( ch, WEAR_HEAD, fReplace ) ) return; act( "$n wears $p on $s head.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your head.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_HEAD ); return; } if ( CAN_WEAR( obj, OBJWEAR_LEGS ) ) { if ( !remove_obj( ch, WEAR_LEGS, fReplace ) ) return; act( "$n wears $p on $s legs.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your legs.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_LEGS ); return; } ////////////// if (CAN_WEAR(obj, OBJWEAR_EYES)) { if (!remove_obj (ch, WEAR_EYES, fReplace)){ return; } act( "$n wears $p on $s eyes.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your eyes.", ch, obj, NULL, TO_CHAR ); equip_char (ch, obj, WEAR_EYES); return; } if (CAN_WEAR(obj, OBJWEAR_EAR)) { // remove something from the ears to make way for the item about to go on if necessary existing_primary_position=get_eq_char( ch, WEAR_EAR_L ); if ( existing_primary_position && get_eq_char( ch, WEAR_EAR_R )) { if(existing_primary_position->pIndexData && obj->pIndexData && existing_primary_position->pIndexData->vnum==obj->pIndexData->vnum) { // favour replacing the secondary position item over doing an exact swap if( !remove_obj( ch, WEAR_EAR_R, fReplace ) &&!remove_obj( ch, WEAR_EAR_L, fReplace ) ){ return; } }else{ if( !remove_obj( ch, WEAR_EAR_L, fReplace ) &&!remove_obj( ch, WEAR_EAR_R, fReplace ) ){ return; } } } if (get_eq_char (ch, WEAR_EAR_L) == NULL) { act( "$n wears $p on $s left ear.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your left ear.", ch, obj, NULL, TO_CHAR ); equip_char (ch, obj, WEAR_EAR_L); return; } if (get_eq_char (ch, WEAR_EAR_R) == NULL) { act( "$n wears $p on $s right ear.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your right ear.", ch, obj, NULL, TO_CHAR ); equip_char (ch, obj, WEAR_EAR_R); return; } bug("Wear_obj: no free ear."); ch->println("You already wear two ear rings."); return; } if (CAN_WEAR(obj, OBJWEAR_FACE)) { if (!remove_obj (ch, WEAR_FACE, fReplace)) return; act( "$n wears $p on $s face.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your face.", ch, obj, NULL, TO_CHAR ); equip_char (ch, obj, WEAR_FACE); return; } if ( CAN_WEAR( obj, OBJWEAR_BACK ) ) { if ( !remove_obj( ch, WEAR_BACK, fReplace ) ) return; act( "$n wears $p on $s back.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your back.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_BACK ); return; } if (CAN_WEAR(obj, OBJWEAR_ANKLE)) { // remove something from the ankles to make way for the item about to go on if necessary existing_primary_position=get_eq_char( ch, WEAR_ANKLE_L ); if ( existing_primary_position && get_eq_char( ch, WEAR_ANKLE_R )) { if(existing_primary_position->pIndexData && obj->pIndexData && existing_primary_position->pIndexData->vnum==obj->pIndexData->vnum) { // favour replacing the secondary position item over doing an exact swap if( !remove_obj( ch, WEAR_ANKLE_R, fReplace ) &&!remove_obj( ch, WEAR_ANKLE_L, fReplace ) ){ return; } }else{ if( !remove_obj( ch, WEAR_ANKLE_L, fReplace ) &&!remove_obj( ch, WEAR_ANKLE_R, fReplace ) ){ return; } } } if (get_eq_char (ch, WEAR_ANKLE_L) == NULL) { act( "$n wears $p on $s left ankle.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your left ankle.", ch, obj, NULL, TO_CHAR ); equip_char (ch, obj, WEAR_ANKLE_L); return; } if (get_eq_char (ch, WEAR_ANKLE_R) == NULL) { act( "$n wears $p on $s right ankle.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your right ankle.", ch, obj, NULL, TO_CHAR ); equip_char (ch, obj, WEAR_ANKLE_R); return; } bug("Wear_obj: no free ankle."); ch->println("You already wear items on both your ankles."); return; } ////////////// if ( CAN_WEAR( obj, OBJWEAR_FEET ) ) { if ( !remove_obj( ch, WEAR_FEET, fReplace ) ) return; act( "$n wears $p on $s feet.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your feet.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_FEET ); return; } if ( CAN_WEAR( obj, OBJWEAR_HANDS ) ) { if ( !remove_obj( ch, WEAR_HANDS, fReplace ) ) return; act( "$n wears $p on $s hands.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your hands.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_HANDS ); return; } if ( CAN_WEAR( obj, OBJWEAR_ARMS ) ) { if ( !remove_obj( ch, WEAR_ARMS, fReplace ) ) return; act( "$n wears $p on $s arms.", ch, obj, NULL, TO_ROOM ); act( "You wear $p on your arms.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_ARMS ); return; } if ( CAN_WEAR( obj, OBJWEAR_ABOUT ) ) { if ( !remove_obj( ch, WEAR_ABOUT, fReplace ) ) return; act( "$n wears $p about $s torso.", ch, obj, NULL, TO_ROOM ); act( "You wear $p about your torso.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_ABOUT ); return; } if ( CAN_WEAR( obj, OBJWEAR_WAIST ) ) { if ( !remove_obj( ch, WEAR_WAIST, fReplace ) ) return; act( "$n wears $p about $s waist.", ch, obj, NULL, TO_ROOM ); act( "You wear $p about your waist.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_WAIST ); return; } if ( CAN_WEAR( obj, OBJWEAR_WRIST ) ) { // remove something from the wrists to make way for the item about to go on if necessary existing_primary_position=get_eq_char( ch, WEAR_WRIST_L ); if ( existing_primary_position && get_eq_char( ch, WEAR_WRIST_R )) { if(existing_primary_position->pIndexData && obj->pIndexData && existing_primary_position->pIndexData->vnum==obj->pIndexData->vnum) { // favour replacing the secondary position item over doing an exact swap if( !remove_obj( ch, WEAR_WRIST_R, fReplace ) &&!remove_obj( ch, WEAR_WRIST_L, fReplace ) ){ return; } }else{ if( !remove_obj( ch, WEAR_WRIST_L, fReplace ) &&!remove_obj( ch, WEAR_WRIST_R, fReplace ) ){ return; } } } if ( get_eq_char( ch, WEAR_WRIST_L ) == NULL ) { act( "$n wears $p around $s left wrist.", ch, obj, NULL, TO_ROOM ); act( "You wear $p around your left wrist.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_WRIST_L ); return; } if ( get_eq_char( ch, WEAR_WRIST_R ) == NULL ) { act( "$n wears $p around $s right wrist.", ch, obj, NULL, TO_ROOM ); act( "You wear $p around your right wrist.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_WRIST_R ); return; } bug("Wear_obj: no free wrist."); ch->println("You already wear two wrist items."); return; } if ( CAN_WEAR( obj, OBJWEAR_SHIELD ) ) { OBJ_DATA *weapon; if ( !remove_obj( ch, WEAR_SHIELD, fReplace ) ) return; weapon = get_eq_char(ch,WEAR_WIELD); if (weapon != NULL && ch->size < SIZE_LARGE && IS_WEAPON_STAT(weapon,WEAPON_TWO_HANDS)) { ch->println("Your hands are tied up with your two-handed weapon!"); return; } if (get_eq_char (ch, WEAR_SECONDARY) != NULL) { if (hold){ if ( !remove_obj( ch, WEAR_SECONDARY, true) ){ return; } }else{ ch->println("You cannot use a shield while using 2 weapons."); ch->println("(Try using hold instead of wear to automatically remove your offhand weapon.)"); return; } } act( "$n wears $p as a shield.", ch, obj, NULL, TO_ROOM ); act( "You wear $p as a shield.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_SHIELD ); return; } if ( CAN_WEAR( obj, OBJWEAR_WIELD ) ) { int sn,skill; if ( !remove_obj( ch, WEAR_WIELD, fReplace ) ) return; if ( !IS_NPC(ch) && get_obj_weight(obj) > ((ch->modifiers[STAT_ST] + 20) * 10 )) { ch->println("It is too heavy for you to wield."); return; } if (!IS_NPC(ch) && ch->size < SIZE_LARGE && IS_WEAPON_STAT(obj,WEAPON_TWO_HANDS) && ((get_eq_char(ch,WEAR_SHIELD) != NULL) || (get_eq_char(ch,WEAR_SECONDARY) != NULL))) { ch->println("You need two hands free for that weapon."); return; } if ( IS_SET( obj->extra2_flags, OBJEXTRA2_NOPRIMARY )) { act( "$p is designed to be wielded in your offhand.", ch, obj, NULL, TO_CHAR ); return; } act( "$n wields $p.", ch, obj, NULL, TO_ROOM ); act( "You wield $p.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_WIELD ); sn = get_weapon_sn(ch); if (sn == gsn_hand_to_hand) return; skill = get_weapon_skill(ch,sn); if (skill >= 100) act("$p feels like a part of you!",ch,obj,NULL,TO_CHAR); else if (skill > 85) act("You feel quite confident with $p.",ch,obj,NULL,TO_CHAR); else if (skill > 70) act("You are skilled with $p.",ch,obj,NULL,TO_CHAR); else if (skill > 50) act("Your skill with $p is adequate.",ch,obj,NULL,TO_CHAR); else if (skill > 25) act("$p feels a little clumsy in your hands.",ch,obj,NULL,TO_CHAR); else if (skill > 1) act("You fumble and almost drop $p.",ch,obj,NULL,TO_CHAR); else act("You don't even know which end is up on $p.", ch,obj,NULL,TO_CHAR); return; } if ( CAN_WEAR( obj, OBJWEAR_HOLD ) ) { if (get_eq_char (ch, WEAR_SECONDARY) != NULL) { if (hold){ if ( !remove_obj( ch, WEAR_SECONDARY, true) ){ return; } }else{ ch->println("You cannot hold an item while using 2 weapons."); ch->println("(Try using hold instead of wear to automatically remove your offhand weapon.)"); return; } } if ( !remove_obj( ch, WEAR_HOLD, fReplace ) ){ return; } act( "$n holds $p in $s hand.", ch, obj, NULL, TO_ROOM ); act( "You hold $p in your hand.", ch, obj, NULL, TO_CHAR ); equip_char( ch, obj, WEAR_HOLD ); return; } if ( CAN_WEAR(obj,OBJWEAR_FLOAT) ) { if (!remove_obj(ch,WEAR_FLOAT, fReplace) ) return; act("$n releases $p to float next to $m.",ch,obj,NULL,TO_ROOM); act("You release $p and it floats next to you.",ch,obj,NULL,TO_CHAR); equip_char(ch,obj,WEAR_FLOAT); return; } if ( CAN_WEAR( obj, OBJWEAR_LODGED_ARM ) ) { if ( !remove_obj( ch, WEAR_LODGED_ARM, fReplace ) ) return; equip_char( ch, obj, WEAR_LODGED_ARM ); return; } if ( CAN_WEAR( obj, OBJWEAR_LODGED_LEG ) ) { if ( !remove_obj( ch, WEAR_LODGED_LEG, fReplace ) ) return; equip_char( ch, obj, WEAR_LODGED_LEG ); return; } if ( CAN_WEAR( obj, OBJWEAR_LODGED_RIB ) ) { if ( !remove_obj( ch, WEAR_LODGED_RIB, fReplace ) ) return; equip_char( ch, obj, WEAR_LODGED_RIB ); return; } if ( fReplace ) ch->println("You can't wear, wield, or hold that."); return; } /**************************************************************************/ void do_wear( char_data *ch, char *argument ) { char arg[MIL]; OBJ_DATA *obj; one_argument( argument, arg ); if ( IS_NULLSTR(arg) ) { ch->println( "Wear, wield what?" ); return; } if ( !str_cmp( arg, "all" ) ) { OBJ_DATA *obj_next; for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) ){ wear_obj ( ch, obj, false, false ); } } return; } if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ){ ch->println( "You do not have that item." ); return; } wear_obj( ch, obj, true, false ); return; } /**************************************************************************/ void do_hold( char_data *ch, char *argument ) { char arg[MIL]; OBJ_DATA *obj; one_argument( argument, arg ); if ( IS_NULLSTR(arg)){ ch->println( "Hold what?" ); return; } if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ){ ch->println( "You do not have that item." ); return; } wear_obj( ch, obj, true, true ); return; } /**************************************************************************/ void do_remove( char_data *ch, char *argument ) { char arg[MIL]; OBJ_DATA *obj; one_argument( argument, arg ); if ( arg[0] == '\0' ) { ch->println("Remove what?"); return; } if (!str_cmp(arg, "all")) { // PC being ordered to do this if ( !IS_NPC(ch) && IS_SET( ch->dyn, DYN_IS_BEING_ORDERED )) { if ( ch->master ) ch->println("Not going to happen."); return; } bool found =false; for ( obj = ch->carrying; obj != NULL; obj = obj->next_content ) { if ( obj->wear_loc != WEAR_NONE && can_see_obj( ch, obj ) ) { if (!found) found = true; if ( obj->wear_loc == WEAR_SHEATHED || obj->wear_loc == WEAR_CONCEALED ) { obj->wear_loc = -1; act( "$n stops using $p.", ch, obj, NULL, TO_ROOM ); act( "You stop using $p.", ch, obj, NULL, TO_CHAR ); } else { remove_obj( ch, obj->wear_loc, true ); } WAIT_STATE(ch, 1); if (ch->fighting) WAIT_STATE(ch, 5); } } if (!found) { ch->println("You are not wearing anything."); } return; } if ( ( obj = get_obj_wear( ch, arg ) ) == NULL ) { ch->println("You do not have that item."); return; } if ( obj->wear_loc == WEAR_SHEATHED || obj->wear_loc == WEAR_CONCEALED ) { obj->wear_loc = -1; act( "$n stops using $p.", ch, obj, NULL, TO_ROOM ); act( "You stop using $p.", ch, obj, NULL, TO_CHAR ); } else remove_obj( ch, obj->wear_loc, true ); return; } /**************************************************************************/ void do_quaff( char_data *ch, char *argument ) { char arg[MIL]; OBJ_DATA *obj; one_argument( argument, arg ); if ( IS_OOC( ch )) { ch->println("Not in an OOC room."); return; } if ( arg[0] == '\0' ) { ch->println("Quaff what?"); return; } if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { ch->println("You do not have that potion."); return; } if ( obj->item_type != ITEM_POTION ) { ch->println("You can quaff only potions."); return; } if ( IS_SET( ch->in_room->room_flags, ROOM_ANTIMAGIC )) { act( "$n quaffs $p.", ch, obj, NULL, TO_ROOM ); act( "You quaff $p but nothing seems to happen.", ch, obj, NULL ,TO_CHAR ); extract_obj( obj ); return; } // Added so that barbarians have a good chance of 'fearing magic'. - Tib if(IS_SET(obj->extra_flags, OBJEXTRA_MAGIC) && HAS_CLASSFLAG(ch, CLASSFLAG_MAGIC_ANTIPATHY) && number_range(1,3)==1) { if ( IS_AFFECTED( ch, AFF_FEAR ) || IS_AFFECTED2( ch, AFF2_FEAR_MAGIC) ) { ch->println("The potion shatters on the ground, falling from your shaking hands."); extract_obj( obj ); return; } act( "$n quaffs $p and screams in terror!", ch, obj, NULL, TO_ROOM ); act( "You quaff $p and scream as you realize the potion was magic.", ch, obj, NULL ,TO_CHAR ); msp_to_room(MSPT_ACTION, MSP_SOUND_QUAFF, 0, ch, false, true); spell_fear_magic( gsn_fear_magic, UMIN(250, (obj->level*5)), ch, ch, 0); extract_obj( obj ); return; } if ((ch->level < obj->level)&&(obj->level>10)) { ch->println("This liquid is too powerful for you to drink."); return; } act( "$n quaffs $p.", ch, obj, NULL, TO_ROOM ); act( "You quaff $p.", ch, obj, NULL ,TO_CHAR ); msp_to_room(MSPT_ACTION, MSP_SOUND_QUAFF, 0, ch, false, true); obj_cast_spell( obj->value[1], obj->value[0], ch, ch, NULL ); obj_cast_spell( obj->value[2], obj->value[0], ch, ch, NULL ); obj_cast_spell( obj->value[3], obj->value[0], ch, ch, NULL ); obj_cast_spell( obj->value[4], obj->value[0], ch, ch, NULL ); if (ch->fighting){ WAIT_STATE( ch, 2*PULSE_VIOLENCE ); }else{ WAIT_STATE( ch, 3*PULSE_VIOLENCE/2 ); } extract_obj( obj ); return; } /**************************************************************************/ void do_recite( char_data *ch, char *argument ) { char arg1[MIL]; char arg2[MIL]; char_data *victim; OBJ_DATA *scroll; OBJ_DATA *obj; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( ( scroll = get_obj_carry( ch, arg1 ) ) == NULL ) { ch->println( "You do not have that scroll." ); return; } if(IS_AFFECTED( ch, AFF_BLIND ) ){ ch->println( "You can't recite scrolls while blind." ); return; } if ( scroll->item_type != ITEM_SCROLL ) { ch->println( "You can recite only scrolls." ); return; } if (( ch->level < scroll->level)&&(scroll->level>10)) { ch->println( "This scroll is too complex for you to comprehend." ); return; } obj = NULL; if ( arg2[0] == '\0' ) { victim = ch; } else { if ( ( victim = get_char_room ( ch, arg2 ) ) == NULL && ( obj = get_obj_here ( ch, arg2 ) ) == NULL ) { ch->println("You can't find it."); return; } } act( "$n recites $p.", ch, scroll, NULL, TO_ROOM ); act( "You recite $p.", ch, scroll, NULL, TO_CHAR ); if (number_percent() >= 20 + get_skill(ch,gsn_scrolls) * 4/5) { ch->println("You mispronounce a syllable."); check_improve(ch,gsn_scrolls,false,2); } else { obj_cast_spell( scroll->value[1], scroll->value[0], ch, victim, obj ); obj_cast_spell( scroll->value[2], scroll->value[0], ch, victim, obj ); obj_cast_spell( scroll->value[3], scroll->value[0], ch, victim, obj ); obj_cast_spell( scroll->value[4], scroll->value[0], ch, victim, obj ); check_improve(ch,gsn_scrolls,true,2); } extract_obj( scroll ); return; } /**************************************************************************/ void do_brandish( char_data *ch, char *argument ) { OBJ_DATA *staff; int sn; // new stuff here char arg2[MIL]; char_data *victim; OBJ_DATA *obj; void *vo; int target; strcpy(arg2, argument); if ( ( staff = get_eq_char( ch, WEAR_HOLD ) ) == NULL ) { ch->println("You hold nothing in your hands to brandish."); return; } if ( staff->item_type != ITEM_STAFF ) { ch->println("You can brandish only with a staff."); return; } if ( IS_SET( ch->in_room->room_flags, ROOM_ANTIMAGIC )) { act( "Your $p doesn't seem to have any power.", ch, staff, NULL, TO_CHAR ); return; } if (( sn = staff->value[3] ) < 0 || sn >= MAX_SKILL || skill_table[sn].spell_fun == 0 ) { bugf( "do_brandish(): bad sn %d.", sn ); return; } WAIT_STATE( ch, 2 * PULSE_VIOLENCE ); if (staff->value[2] < -1) { staff->value[2] = -1; } if (( staff->value[2] > 0 ) || (staff->value[2] = -1)) { act( "$n brandishes $p.", ch, staff, NULL, TO_ROOM ); act( "You brandish $p.", ch, staff, NULL, TO_CHAR ); if ( ch->level < staff->level || (get_skill(ch,gsn_staves)==0) || number_percent() >= 20 + get_skill(ch,gsn_staves) * 4/5) { act ("You fail to invoke $p.",ch,staff,NULL,TO_CHAR); act ("...and nothing happens.",ch,NULL,NULL,TO_ROOM); check_improve(ch,gsn_staves,false,2); } else // cast the spell { // Locate targets. victim = NULL; obj = NULL; vo = NULL; target = TARGET_NONE; switch ( skill_table[sn].target ) { default: bugf( "do_cast(): bad target for sn %d.", sn ); return; case TAR_IGNORE: break; case TAR_MOB_OFFENSIVE: case TAR_CHAR_OFFENSIVE: if ( arg2[0] == '\0' ) { if ( ( victim = ch->fighting ) == NULL ) { ch->println("Brandish the object while aiming it towards whom?"); return; } } else { if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->println("They aren't here."); return; } } if ( !IS_NPC(ch) ) { if (is_safe(ch,victim) && victim != ch) { ch->println("Not on that target."); return; } } if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim ) { ch->println("You can't do that on your own follower."); return; } vo = (void *) victim; target = TARGET_CHAR; break; case TAR_CHAR_DEFENSIVE: if ( arg2[0] == '\0' ) { victim = ch; } else { if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->println("They aren't here."); return; } } vo = (void *) victim; target = TARGET_CHAR; break; case TAR_CHAR_SELF: if ( arg2[0] != '\0' && !is_name( arg2, ch->name ) ) { ch->println("You can't brandish this object while aiming it at another."); return; } vo = (void *) ch; target = TARGET_CHAR; break; case TAR_OBJ_INV: if ( arg2[0] == '\0' ) { ch->println("You must brandish the object towards another object?"); return; } if ( ( obj = get_obj_carry( ch, arg2 ) ) == NULL ) { ch->println("You are not carrying that."); return; } vo = (void *) obj; target = TARGET_OBJ; break; case TAR_OBJ_MOB_OFF: case TAR_OBJ_CHAR_OFF: if (arg2[0] == '\0') { if ((victim = ch->fighting) == NULL) { ch->println("Brandish the object on whom or what?"); return; } target = TARGET_CHAR; } else if ((victim = get_char_room(ch,arg2)) != NULL) { target = TARGET_CHAR; } if (target == TARGET_CHAR) // check the sanity of the attack { if(is_safe_spell(ch,victim,false) && victim != ch) { ch->println("Not on that target."); return; } if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim ) { ch->println("You can't do that on your own follower."); return; } vo = (void *) victim; } else if ((obj = get_obj_here(ch,arg2)) != NULL) { vo = (void *) obj; target = TARGET_OBJ; } else { ch->println("You don't see that here."); return; } break; case TAR_OBJ_CHAR_DEF: if (arg2[0] == '\0') { vo = (void *) ch; target = TARGET_CHAR; } else if ((victim = get_char_room(ch,arg2)) != NULL) { vo = (void *) victim; target = TARGET_CHAR; } else if ((obj = get_obj_carry(ch,arg2)) != NULL) { vo = (void *) obj; target = TARGET_OBJ; } else { ch->println("You don't see that here."); return; } break; } // end of spell type switch if (IS_NPC(ch) || class_table[ch->clss].fMana) // clss has spells (*skill_table[sn].spell_fun) ( sn, staff->value[0], ch, vo,target); else (*skill_table[sn].spell_fun) (sn, staff->value[0], ch, vo,target); check_improve(ch,gsn_staves,true,2); } } // get rid of the staff if required if ( staff->value[2] == -1) { return; } staff->value[2]--; if (staff->value[2] < 1) { act( "$n's $p blazes bright and is gone.", ch, staff, NULL, TO_ROOM ); act( "Your $p blazes bright and is gone.", ch, staff, NULL, TO_CHAR ); extract_obj( staff ); } return; } /**************************************************************************/ void do_apply( char_data *ch, char *argument ) { char arg[MIL]; char_data *victim; OBJ_DATA *poultice; if ( IS_OOC( ch )) { ch->println( "Not in an OOC room." ); return; } if ( get_skill( ch, gsn_apply ) == 0 ) { ch->println( "You are not educated in the herbal arts." ); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { ch->println( "Apply what to whom?" ); return; } if (( poultice = get_eq_char( ch, WEAR_HOLD )) == NULL ) { ch->println( "You hold nothing in your hand." ); return; } if ( poultice->item_type != ITEM_POULTICE ) { ch->println( "You are not holding a suitable medicinal component." ); return; } if (( victim = get_char_room ( ch, arg ) ) == NULL ) { ch->println( "They are not here." ); return; } WAIT_STATE( ch, 2 * PULSE_VIOLENCE ); if ( poultice->value[2] != 0 ) { act( "$n applies $p to $N.", ch, poultice, victim, TO_ROOM ); act( "You apply $p to $N.", ch, poultice, victim, TO_CHAR ); } if ( ch->level < poultice->level || number_percent() >= 20 + get_skill( ch, gsn_apply ) * 4/5 ) { act( "Your efforts to apply $p didn't produce any noticeable effects.", ch, poultice, NULL, TO_CHAR ); act( "$n's efforts to apply $p had no noticeable effects.", ch, poultice, NULL, TO_ROOM ); check_improve( ch, gsn_apply, false, 2 ); } else { obj_cast_spell( poultice->value[3], poultice->value[0], ch, victim, NULL ); check_improve( ch, gsn_apply, true, 2 ); } if ( --poultice->value[2] == 0 ) { act( "$n has used up $p.", ch, poultice, NULL, TO_ROOM ); act( "You have used up $p.", ch, poultice, NULL, TO_CHAR ); extract_obj( poultice ); } if ( poultice->value[2] < 0 ) poultice->value[2] = -1; // set it back to infinite return; } /**************************************************************************/ void duel_unprotect_victim(char_data *victim); /**************************************************************************/ void do_steal( char_data *ch, char *argument ) { char buf [MSL]; char arg1 [MIL]; char arg2 [MIL]; char_data *victim; OBJ_DATA *obj; int percent; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' || arg2[0] == '\0' ) { ch->println( "Steal what from whom?" ); return; } // ooc rooms if(!IS_IMMORTAL(ch) && IS_SET(ch->in_room->room_flags,ROOM_OOC)){ ch->println("Not in an OOC room."); return; } if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->println( "They aren't here." ); return; } if(!IS_NPC(victim) && victim->level<10 && ch->level>(victim->level+10) && !IS_NPC(ch) && !IS_IMMORTAL(ch)) { ch->println( "A faint wall of light appears to surround them preventing you from robbing them." ); return; } if (!IS_IMMORTAL(ch) && !IS_NPC(ch) && !IS_NPC(victim) && GAMESETTING4(GAMESET4_PREVENT_STEALING_FROM_PLAYERS)){ if(GAMESETTING4(GAMESET4_OOC_PREVENTION_MESSAGES)){ ch->println( "Stealing from other players is not permitted on this mud." ); }else{ ch->println( "A faint wall of light appears to surround them preventing you from robbing them." ); } return; } if ( victim == ch ){ ch->println( "That's pointless." ); return; } if(GAMESETTING5(GAMESET5_NO_STEALING_FROM_FIGHTING_CHARACTERS) && victim->fighting){ ch->println( "Not while they are fighting!" ); return; } if (is_safe(ch,victim)){ return; } if ( IS_NPC(victim) && victim->position == POS_FIGHTING) { ch->println( "You'd better not -- you might get hit." ); return; } // optional stealing checks which affect stealing between players if (!IS_IMMORTAL(ch) && !IS_NPC(victim)){ if( GAMESETTING4(GAMESET4_MUST_BE_IN_CLAN_TO_STEAL_FROM_PLAYERS) ){ ch->println( "You are not in a clan, stealing from players is restricted to clan members." ); return; } if( GAMESETTING4(GAMESET4_NO_STEALING_FROM_NON_CLANNED) && !victim->clan ){ ch->println( "They are not in a clan, stealing from players is restricted to clan members." ); return; } // optional checks relating to letgain status if(GAMESETTING_LETGAINING_IS_REQUIRED){ // is the potential thief letgained if ( GAMESETTING4(GAMESET4_MUST_BE_LETGAINED_TO_STEAL_FROM_PLAYERS) && !IS_LETGAINED(ch)) { ch->println("You can't steal from non letgained players."); return; } // is the intended victim letgained if ( GAMESETTING4(GAMESET4_NO_STEALING_FROM_NON_LETGAINED) && !IS_LETGAINED(victim)) { ch->println("You can't steal from non letgained players."); return; } if(GAMESETTING5(GAMESET5_MUST_BE_ACTIVE_TO_BE_INVOLVED_IN_STEALING)){ if(!HAS_CONFIG(victim, CONFIG_ACTIVE)) { ch->println( "You can't steal from non active players." ); return; } if(!HAS_CONFIG(ch, CONFIG_ACTIVE)) { ch->println( "You must be active in order to steal from players." ); return; } } if(HAS_CONFIG2(ch,CONFIG2_NOPKILL)) { ch->println( "A faint wall of light appears to surround them preventing you from robbing them." ); return; } if(HAS_CONFIG2(victim,CONFIG2_NOPKILL)) { ch->println( "A faint wall of light appears to surround them preventing you from robbing them." ); return; } } // optional: stealing only permitted within ten levels of each other if (GAMESETTING4(GAMESET4_NO_STEALING_OUTSIDE_10_LEVELS)){ if ( (ch->level - victim->level) > 10 || (ch->level - victim->level) < -10 ) { ch->println("You may not steal from a character of more than 10 levels difference to your own." ); return; } } } // silent imms dont get lagged if (!IS_SILENT(ch) || !IS_ICIMMORTAL(ch)){ WAIT_STATE( ch, skill_table[gsn_steal].beats ); } // for 20 minutes you are unsafe if you steal if(!IS_NPC(ch) && !IS_NPC(victim)){ ch->pcdata->unsafe_due_to_stealing_till=current_time+ 20*60; if(ch->duels){ duel_unprotect_victim(ch); } } if (IS_ICIMMORTAL(victim)){ ch->println( "You failed." ); victim->wraplnf( "NOTICE: %s attempted to steal '%s' from you and failed because you are considered an IC immortal.", PERS(ch, victim), arg1); return; } percent = number_percent(); if (get_skill(ch,gsn_steal) >= 1){ percent += ( IS_AWAKE(victim) ? 10 : -50 ); } if(victim->pcdata && victim->pcdata->is_trying_aware){ percent += (get_skill(victim, gsn_awareness))/6; } if ( (IS_KEEPER(victim)) ||(!IS_NPC(ch) && (percent+2*victim->level-2*ch->level > get_skill(ch,gsn_steal))) ||(!IS_NPC(ch) && get_skill(ch,gsn_steal)==0) || (ch->level<=LEVEL_HERO && victim->level>LEVEL_HERO)) { /* * Failure. */ ch->println( "Oops." ); // make them go visible affect_strip ( ch, gsn_invisibility ); affect_strip ( ch, gsn_mass_invis ); affect_strip ( ch, gsn_sneak ); REMOVE_BIT ( ch->affected_by, AFF_HIDE ); REMOVE_BIT ( ch->affected_by, AFF_INVISIBLE ); REMOVE_BIT ( ch->affected_by, AFF_SNEAK ); if (!IS_NPC(victim)) { ch->pksafe=0; ch->pknorecall= (UMAX(ch->pknorecall,2)); ch->pknoquit=(UMAX(ch->pknoquit,10)); } if (IS_AWAKE(victim)){ act( "$n tried to steal from YOU!", ch, NULL, victim, TO_VICT ); if( victim->pcdata && victim->pcdata->is_trying_aware ) check_improve(victim,gsn_awareness,true,1); }else{ if( victim->pcdata && victim->pcdata->is_trying_aware && get_skill(victim, gsn_awareness) > number_percent() ) { victim->println( "You feel the presence of another person lurking near you." ); victim->println( "You feel someone try to take something from you and instantly pop awake!" ); victim->position=POS_RESTING; do_stand(victim,""); check_improve(victim,gsn_awareness,true,2); }else{ victim->println( "You are partially awakened by someone in the room." ); victim->println( "You roll over and drift back to sleep." ); } } act( "$n tried to steal from $N.", ch, NULL, victim, TO_NOTVICT ); if ( !IS_NPC(ch) ) { if ( IS_NPC(victim) ) { check_improve(ch,gsn_steal,false,2); multi_hit( victim, ch, TYPE_UNDEFINED ); } else { sprintf(buf,"$N tried to steal from %s <%d>.", victim->name, victim->level); wiznet(buf,ch,NULL,WIZ_THEFTS,0,0); if(GAMESETTING3(GAMESET3_THIEF_SYSTEM_ENABLED)){ if(!IS_NPC(ch)){ if(!IS_THIEF(ch)){ ch->println( "*** You are now tagged as a THIEF!! ***"); } ch->pcdata->thief_until=current_time+ (60*game_settings->thief_system_tagged_duration); save_char_obj( ch ); } } } } return; } else if (!IS_NPC(victim)) { // transfer those to the void that are attacked // while linkdead and dont have a pkill timer if ( victim->pknorecall ==0 && IS_LINKDEAD(victim) && victim->was_in_room == NULL && victim->in_room != NULL ) { victim->was_in_room = victim->in_room; if ( victim->fighting != NULL ) stop_fighting( victim, true ); act( "$n disappears into the void.", victim, NULL, NULL, TO_ROOM ); victim->println( "You disappear into the void." ); if (victim->level > 1) save_char_obj( victim); char_from_room( victim); char_to_room( victim, get_room_index( ROOM_VNUM_LIMBO ) ); return; } ch->pksafe=0; ch->pknoquit=(UMAX(ch->pknoquit,10)); } if ( !str_cmp( arg1, "coin" ) || !str_cmp( arg1, "coins" ) || !str_cmp( arg1, "gold" ) || !str_cmp( arg1, "silver")) { int gold, silver; gold = victim->gold * number_range(1, ch->level) / MAX_LEVEL; silver = victim->silver * number_range(1,ch->level) / MAX_LEVEL; if (gold > victim->gold) gold = victim->gold; if (silver > victim->silver) silver = victim->silver; if ( gold <= 0 && silver <= 0 ) { ch->println( "You couldn't get any coins." ); return; } ch->gold += gold; ch->silver += silver; victim->silver -= silver; victim->gold -= gold; if (silver <= 0) ch->printlnf( "Bingo! You got %d gold coins.", gold ); else if (gold <= 0) ch->printlnf( "Bingo! You got %d silver coins.", silver); else ch->printlnf( "Bingo! You got %d silver and %d gold coins.", silver, gold ); check_improve(ch,gsn_steal,true,2); if (!IS_NPC(victim)) { sprintf(buf,"$N successfully stole %d silver and %d " "gold coins from %s <%d>.", silver, gold, victim->name, victim->level); wiznet(buf,ch,NULL,WIZ_THEFTS,0,0); } return; } if ( ( obj = get_obj_carry_for_looker( victim, arg1, ch ) ) == NULL ) { ch->println( "You can't find it." ); return; } if ( !can_drop_obj( ch, obj ) || IS_SET(obj->extra_flags, OBJEXTRA_INVENTORY) ) { ch->println( "You can't pry it away." ); return; } if ( ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ) ) { ch->println( "You have your hands full." ); return; } if ( ch->carry_weight + get_obj_weight( obj ) > can_carry_w( ch ) ) { ch->println( "You can't carry that much weight." ); return; } obj_from_char( obj ); obj_to_char( obj, ch ); check_improve(ch,gsn_steal,true,2); ch->println( "Got it!" ); if (!IS_NPC(victim)) { sprintf(buf,"$N successfully stole %s [%d] from %s <%d>.", obj->short_descr, obj->pIndexData->vnum, victim->name, victim->level); wiznet(buf,ch,NULL,WIZ_THEFTS,0,0); } return; } /**************************************************************************/ /* * Shopping commands. */ /**************************************************************************/ char_data *find_keeper( char_data *ch ) { char_data *keeper; SHOP_DATA *pShop; pShop = NULL; for ( keeper = ch->in_room->people; keeper; keeper = keeper->next_in_room ) { if ( IS_NPC(keeper) && (pShop = keeper->pIndexData->pShop) != NULL ) break; } if ( pShop == NULL ) { ch->println("You can't do that here."); return NULL; } // Shop hours. if ( time_info.hour < pShop->open_hour ) { do_say( keeper, "Sorry, I am closed. Come back later." ); return NULL; } if ( time_info.hour > pShop->close_hour ) { do_say( keeper, "Sorry, I am closed. Come back tomorrow." ); return NULL; } // Invisible or hidden people. if ( !can_see( keeper, ch ) && INVIS_LEVEL(ch)<1) { do_say( keeper, "I don't trade with folks I can't see." ); return NULL; } return keeper; } /**************************************************************************/ // insert an object at the right spot for the keeper void obj_to_keeper( OBJ_DATA *obj, char_data *ch ) { OBJ_DATA *t_obj, *t_obj_next; // see if any duplicates are found for (t_obj = ch->carrying; t_obj != NULL; t_obj = t_obj_next) { t_obj_next = t_obj->next_content; if (obj->pIndexData == t_obj->pIndexData && !str_cmp(obj->short_descr,t_obj->short_descr)) { // if this is an unlimited item, destroy the new one if (IS_OBJ_STAT(t_obj,OBJEXTRA_INVENTORY)) { extract_obj(obj); return; } obj->cost = t_obj->cost; // keep it standard break; } } if (t_obj == NULL) { obj->next_content = ch->carrying; ch->carrying = obj; } else { obj->next_content = t_obj->next_content; t_obj->next_content = obj; } obj->carried_by = ch; obj->in_room = NULL; obj->in_obj = NULL; ch->carry_number += get_obj_number( obj ); ch->carry_weight += get_obj_weight( obj ); } /**************************************************************************/ // get an object from a shopkeeper's list OBJ_DATA *get_obj_keeper( char_data *ch, char_data *keeper, char *argument ) { char arg[MIL]; char newarg[MIL]; OBJ_DATA *obj; int number; int count; // convert 'buy 5' to 'buy 5.' if(is_number(argument)){ sprintf(newarg,"%s.",argument); argument=newarg; }; number = number_argument( argument, arg ); count = 0; int uid=get_uid(arg); if(uid){ number=1; } for ( obj = keeper->carrying; obj; obj = obj->next_content ) { if (obj->wear_loc == WEAR_NONE && can_see_obj( keeper, obj ) && can_see_obj(ch,obj) && ( (uid && uid==obj->uid) || is_name( arg, obj->name ) ) ) { if ( ++count == number ) return obj; // skip other objects of the same name while (obj->next_content != NULL && obj->pIndexData == obj->next_content->pIndexData && !str_cmp(obj->short_descr,obj->next_content->short_descr)) obj = obj->next_content; } } return NULL; } /**************************************************************************/ // figure out how much a shop keeper will pay/sell an item for. int get_cost( char_data *keeper, OBJ_DATA *obj, bool fBuy ) { SHOP_DATA *pShop; int cost; if ( obj == NULL || ( pShop = keeper->pIndexData->pShop ) == NULL ) return 0; if(IS_SET(obj->extra2_flags,OBJEXTRA2_NOSELL)){ // non sellable objects return 0; } if ( fBuy ) { cost = obj->cost * pShop->profit_buy / 100; } else { OBJ_DATA *obj2; int itype; cost = 0; for ( itype = 0; itype < MAX_TRADE; itype++ ) { if ( obj->item_type == pShop->buy_type[itype] ) { cost = obj->cost * pShop->profit_sell / 100; break; } } if (!IS_OBJ_STAT(obj,OBJEXTRA_SELL_EXTRACT)) for ( obj2 = keeper->carrying; obj2; obj2 = obj2->next_content ) { if ( obj->pIndexData == obj2->pIndexData && !str_cmp(obj->short_descr,obj2->short_descr) ) if (IS_OBJ_STAT(obj2,OBJEXTRA_INVENTORY)) cost /= 2; else cost = cost * 3 / 4; } } if ( obj->item_type == ITEM_STAFF || obj->item_type == ITEM_WAND ) { if (obj->value[1] == 0){ cost /= 4; }else{ cost = cost * obj->value[2] / obj->value[1]; } } return cost; } /**************************************************************************/ void buy_in_petshop( char_data *ch, char *argument ) { int cost,roll; char arg[MIL]; char buf[MSL]; char_data *pet; ROOM_INDEX_DATA *pRoomIndexNext; ROOM_INDEX_DATA *in_room; if ( IS_NPC(ch) ) return; argument = one_argument(argument,arg); // petshop storage room is the room which vnum // is one greater than the current room pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 ); if ( pRoomIndexNext == NULL ) { bugf( "do_buy(): bad pet shop at vnum %d.", ch->in_room->vnum ); ch->println("Sorry, you can't buy that here."); return; } in_room = ch->in_room; ch->in_room = pRoomIndexNext; pet = get_pet_room( ch, arg ); ch->in_room = in_room; if ( pet == NULL || !IS_SET(pet->act, ACT_PET) ) { ch->println("Sorry, you can't buy that here."); return; } if ( ch->pet != NULL ) { ch->println("You already own a pet."); return; } cost = 10 * pet->level * pet->level; if IS_CONTROLLED(ch) cost =0; if ( ch->level < pet->level ) { ch->println("You're not powerful enough to master this pet."); return; } // haggle roll = number_percent(); if (roll < get_skill(ch,gsn_haggle)) { cost -= cost / 2 * roll / 100; if ( (ch->silver + 100 * ch->gold) < cost) { ch->printlnf( "You haggle the price down to %d coin%s, but " "still can't afford it.", cost, cost==1?"":"s"); if ( (ch->silver + 100 * ch->gold)>0 && (ch->silver + 100 * ch->gold) < (cost* 96/100) ) { cost=(ch->silver + 100 * ch->gold); ch->printlnf( "You explain this to the pet shopkeeper and manage " "haggle the price down to the money that you do have!"); }else{ // didn't get it WAIT_STATE(ch, 20); // 5 seconds lag to reduce potential abuse return; } }else{ ch->printlnf( "You haggle the price down to %d coin%s.", cost, cost==1?"":"s"); check_improve(ch,gsn_haggle,true,4); } }else{ if ( (ch->silver + 100 * ch->gold) < cost ) { ch->println("You can't afford it."); return; } } deduct_cost(ch,cost); pet = create_mobile( pet->pIndexData, 0 ); SET_BIT(pet->act, ACT_PET); SET_BIT(pet->affected_by, AFF_CHARM); pet->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS; argument = one_argument( argument, arg ); if(!IS_NULLSTR(arg)){ sprintf( buf, "%s %s", pet->name, arg ); free_string( pet->name ); pet->name = str_dup( buf ); } sprintf( buf, "%sA neck tag says 'I belong to %s'.\r\n", pet->description, ch->short_descr ); free_string( pet->description ); pet->description = str_dup( buf ); char_to_room( pet, ch->in_room ); add_follower( pet, ch ); pet->leader = ch; ch->pet = pet; ch->println("Enjoy your pet."); act( "$n bought $N as a pet.", ch, NULL, pet, TO_ROOM ); } /**************************************************************************/ void do_lockers(char_data *ch, char *argument); /**************************************************************************/ void do_buy( char_data *ch, char *argument ) { char buf[MSL]; int cost,roll; if(IS_NULLSTR(argument)){ ch->println( "Buy what?" ); if(IS_NEWBIE(ch)){ ch->println( "Use the 'list' command to see what is available while near a shopkeeper." ); } return; } smash_tilde(argument); // pet shops if( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP)){ buy_in_petshop(ch, argument); return; } // locker code if(!str_prefix("locker", argument)){ do_lockers(ch, FORMATF("%s startrent", argument+6)); return; } { char_data *keeper; OBJ_DATA *obj,*t_obj; char arg[MIL]; int number, count = 1; if ( ( keeper = find_keeper( ch ) ) == NULL ) return; number = mult_argument(argument,arg); obj = get_obj_keeper( ch,keeper, arg ); cost = get_cost( keeper, obj, true ); if(number<1){ return; } if ( cost <= 0 || !can_see_obj( ch, obj ) ) { act( "$n tells you 'I don't sell that -- try 'list''.", keeper, NULL, ch, TO_VICT ); return; } if (!IS_OBJ_STAT(obj,OBJEXTRA_INVENTORY)) { for (t_obj = obj->next_content; count < number && t_obj != NULL; t_obj = t_obj->next_content) { if (t_obj->pIndexData == obj->pIndexData && !str_cmp(t_obj->short_descr,obj->short_descr)) count++; else break; } if (count < number) { act("$n tells you 'I don't have that many in stock.", keeper,NULL,ch,TO_VICT); //ch->reply = keeper; return; } } if (!IS_CONTROLLED(ch)) { if (ch->carry_number + number * get_obj_number(obj) > can_carry_n(ch)) { ch->println("You can't carry that many items."); return; } if ( ch->carry_weight + number * get_obj_weight(obj) > can_carry_w(ch)) { ch->println("You can't carry that much weight."); return; } // haggle roll = number_percent(); if (!IS_OBJ_STAT(obj,OBJEXTRA_SELL_EXTRACT) && roll < get_skill(ch,gsn_haggle)) { cost -= obj->cost / 2 * roll / 100; // do can afford checks if ( (ch->silver + ch->gold * 100) < cost * number ) { act("You haggle with $N.",ch,NULL,keeper,TO_CHAR); if (number > 1){ act("$n tells you 'I wont sell you that many so cheap.", keeper,obj,ch,TO_VICT); }else{ act( "$n tells you 'I wont sell $p that cheap sorry'.", keeper, obj, ch, TO_VICT ); } WAIT_STATE(ch, 20); // 5 seconds lag to reduce potential abuse return; }else{ act("You haggle with $N.",ch,NULL,keeper,TO_CHAR); check_improve(ch,gsn_haggle,true,4); } } // do can afford checks if ( (ch->silver + ch->gold * 100) < cost * number ) { if (number > 1) act("$n tells you 'You can't afford to buy that many.", keeper,obj,ch,TO_VICT); else act( "$n tells you 'You can't afford to buy $p'.", keeper, obj, ch, TO_VICT ); return; } } if (number > 1) { sprintf(buf,"$n buys $p[%d].",number); act(buf,ch,obj,NULL,TO_ROOM); sprintf(buf,"You buy $p[%d] for %d silver.",number,cost * number); act(buf,ch,obj,NULL,TO_CHAR); } else { act( "$n buys $p.", ch, obj, NULL, TO_ROOM ); sprintf(buf,"You buy $p for %d silver.",cost); act( buf, ch, obj, NULL, TO_CHAR ); } if (!IS_CONTROLLED (ch)) deduct_cost(ch,cost * number); keeper->gold += cost * number/100; keeper->silver += cost * number - (cost * number/100) * 100; // limit a shopkeepers wealth if more than 10 minutes after a reboot if(boot_time+360<current_time){ limit_mobile_wealth(keeper); } for (count = 0; count < number; count++) { if ( IS_SET( obj->extra_flags, OBJEXTRA_INVENTORY ) ){ t_obj = create_object( obj->pIndexData); }else{ t_obj = obj; obj = obj->next_content; obj_from_char( t_obj ); } if (t_obj->timer > 0 && !IS_OBJ_STAT(t_obj,OBJEXTRA_HAD_TIMER)) t_obj->timer = 0; REMOVE_BIT(t_obj->extra_flags,OBJEXTRA_HAD_TIMER); REMOVE_BIT(t_obj->extra_flags,OBJEXTRA_INVENTORY); obj_to_char( t_obj, ch ); if (cost < t_obj->cost) t_obj->cost = cost; } } } /**************************************************************************/ // wear object as a secondary weapon void do_second (char_data *ch, char *argument) { OBJ_DATA *obj; if(!GAMESETTING2(GAMESET2_NO_SECOND_SKILL_REQUIRED)){ if ( !IS_NPC(ch) && ch->get_skill(gsn_second)<1){ ch->println("You dont have a clue how to hold a weapon in your off-hand correctly."); return; } } if (IS_NULLSTR(argument)){ ch->println("Wear which weapon in your off-hand?"); return; } obj = get_obj_carry (ch, argument); // find the obj withing ch's inventory if (obj == NULL) { ch->println("You have no such thing in your backpack."); return; } if (( obj->level>LEVEL_HERO)&&(ch->level < LEVEL_IMMORTAL)) { char buf[MSL]; sprintf( buf, "`x%s (%s) lvl %d`1tried to wear `1" "%s [%d] lvl %d`1" "It was removed since it was out of level.", ch->name, ch->short_descr, ch->level, obj->short_descr, obj->pIndexData->vnum, obj->level); autonote(NOTE_SNOTE, "p_anote()","`Yoverlevel object!`x", "imm", buf, true); ch->printlnf( "You try to use %s and it crumbles to dust.", obj->short_descr ); act( "$n tries to use $p, but it crumbles to dust.", ch, obj, NULL, TO_ROOM ); extract_obj(obj); return; } if(obj->item_type != ITEM_WEAPON) { ch->println("That is not a weapon."); return; } if(!CAN_WEAR( obj, OBJWEAR_WIELD )) { ch->println("You can not wield that."); return; } if ( IS_SET( obj->extra2_flags, OBJEXTRA2_NOSECONDARY )) { act( "You cannot wield $p in your offhand.", ch, obj, NULL, TO_CHAR ); return; } if ( !IS_ADMIN( ch )) // Immortal requested not to have this but I wanted it :) { if(!IS_NPC(ch) && obj->pIndexData->relative_size< race_table[ch->race]->low_size) { act("$p is too small for you.",ch,obj,NULL,TO_CHAR); return; } if(!IS_NPC(ch) && obj->pIndexData->relative_size> race_table[ch->race]->high_size) { act("$p is too large for you.",ch,obj,NULL,TO_CHAR); return; } } if ( !IS_IMMORTAL( ch )) { if(DISALLOWED_OBJECT_FOR_CHAR(obj, ch)) { act("$p cannot be used by your class.",ch,obj,NULL,TO_CHAR); return; } } if(IS_SET(obj->extra_flags, OBJEXTRA_MAGIC) && HAS_CLASSFLAG(ch, CLASSFLAG_MAGIC_ANTIPATHY)) { act("You have great antipathy towards $p.",ch,obj,NULL,TO_CHAR); return; } // check that the character is using a first weapon at all if (get_eq_char (ch, WEAR_WIELD) == NULL) { ch->println("You need to wield a primary weapon, before using a secondary one!"); return; } // check for str - secondary weapons have to be lighter if ( get_obj_weight( obj ) > ( (ch->modifiers[STAT_ST] + 15)*5) ) { ch->println("This weapon is too heavy to be used as a secondary weapon by you."); return; } if (IS_WEAPON_STAT(get_eq_char(ch,WEAR_WIELD),WEAPON_TWO_HANDS) && ch->size < SIZE_LARGE) { ch->println("You cannot wear a weapon in your off hand if using a two handed weapon."); return; } // check if the char is using a shield or a held weapon if ( get_eq_char (ch,WEAR_SHIELD) != NULL) { if ((!remove_obj(ch, WEAR_SHIELD, true))){ // ch->println("You cannot use a secondary weapon while using a shield or holding an item."); return; } } if ( get_eq_char(ch,WEAR_HOLD) != NULL) { if ((!remove_obj(ch, WEAR_HOLD, true))){ // ch->println("You cannot use a secondary weapon while using a shield or holding an item."); return; } } // at last - the char uses the weapon if (!remove_obj(ch, WEAR_SECONDARY, true)) // remove the current weapon if any return; // remove obj tells about any no_remove if (IS_WEAPON_STAT(obj,WEAPON_TWO_HANDS)) { ch->println("You can't use a two handed weapon in your off hand."); return; } act ("$n wields $p in $s off-hand.",ch,obj,NULL,TO_ROOM); act ("You wield $p in your off-hand.",ch,obj,NULL,TO_CHAR); equip_char ( ch, obj, WEAR_SECONDARY); return; } /**************************************************************************/ char_data* find_innkeeper(char_data *ch); /**************************************************************************/ //format_obj_to_char( OBJ_DATA *obj, char_data *ch, bool fShort ) void do_list( char_data *ch, char *argument ) { char buf[MSL]; BUFFER *output; if(str_len(argument)>3 && !str_prefix(argument, "lockers")){ do_lockers(ch, "list"); return; } if (IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) ) { // pet shop ROOM_INDEX_DATA *pRoomIndexNext; char_data *pet; bool found; pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 ); if (pRoomIndexNext == NULL ) { bugf( "do_list(): bad pet shop at vnum %d.", ch->in_room->vnum ); ch->println("You can't do that here."); return; } output = new_buf(); found = false; for ( pet = pRoomIndexNext->people; pet; pet = pet->next_in_room ) { if ( IS_NPC(pet) && IS_SET(pet->act, ACT_PET) ) { if ( !found ) { found = true; add_buf(output,"Pets for sale:\r\n"); } sprintf( buf, "[%2d] %8d - %s\r\n", pet->level, 10 * pet->level * pet->level, pet->short_descr ); // holyvnum if (!IS_UNSWITCHED_MOB(ch) && IS_SET(TRUE_CH(ch)->act, PLR_HOLYVNUM)) { char buf2[MSL]; if (IS_NPC(pet) && pet->pIndexData) { if (pet->pIndexData->mprogs) { sprintf(buf2," `#`r*%d,%d*`^\r\n", pet->pIndexData->vnum, pet->level); } else { sprintf(buf2," `#`B[%d,%d]`^\r\n", pet->pIndexData->vnum, pet->level); } buf[str_len(buf)-2]= '\0'; // chop off the \r\n strcat(buf,buf2); } } add_buf(output,buf); } } if ( !found ){ add_buf(output,"Sorry, we're out of pets right now.\r\n"); } ch->sendpage(buf_string(output)); free_buf(output); return; // end of petshop code } else if ( IS_SET(ch->in_room->room_flags, ROOM_INN) ){ // Innkeeper code. ROOM_INDEX_DATA* pRoom = NULL; char_data* pInnKeeper = NULL; cInnData* pInn = NULL; char pListItem[MSL]; vn_int roomVnum = 0; int roomRate = 0; sh_int roomIdx = 0; bool foundItem = false; output = new_buf(); // Find the first mob in the room that is an innkeeper. if ( !(pInnKeeper=find_innkeeper(ch)) ) { return; } // Just a shortcut pointer to make the rest of the code more readable. pInn = pInnKeeper->pIndexData->pInnData; // Add valid rooms to the output buffer. for(roomIdx=0; roomIdx<MAX_INN; roomIdx++ ) { roomVnum = pInn->vnRoom[roomIdx]; roomRate = pInn->shRate[roomIdx]; if ( roomVnum > 0 ) { if ( (pRoom=get_room_index(roomVnum)) != NULL ) { if ( !foundItem ) { foundItem = true; add_buf(output, "INN - ROOMS FOR RENT`1"); add_buf(output, "[Number Price/Hour] Description`1"); } sprintf(pListItem, " %6d %8d `#%-32s`^\r\n", roomIdx+1, roomRate, pRoom->name); add_buf(output, pListItem); } } } if ( !foundItem ) { add_buf(output, "There are no rooms to rent here.`1"); } ch->sendpage(buf_string(output)); free_buf(output); return; }else{// end of inn start of normal shop char_data *keeper; OBJ_DATA *obj; int count, can_wear; int foundcount; char arg[MIL]; char buf2[MSL]; int cost=0, linecount; // listing by level matching system bool doingFiltering=false; bool levelBasedFiltering=false; int max_obj_level=MAX_LEVEL; int min_obj_level=0; if (!(keeper = find_keeper(ch))) return; // preparse any parameters argument=one_argument(argument,arg); if (!IS_NULLSTR(arg)){ doingFiltering=true; // figure out if it is level based if(is_number(arg)){ levelBasedFiltering=true; max_obj_level=atoi(arg); // second level - level range match argument=one_argument(argument,arg); if(!IS_NULLSTR(arg)){ if(!is_number(arg)){ ch->println("You can't search by level and substrings at the same time sorry."); return; } min_obj_level=atoi(arg); // swap the levels if necessary if (min_obj_level>max_obj_level){ foundcount=max_obj_level; max_obj_level=min_obj_level; min_obj_level=foundcount; } } }else{ // substring match } }// end of parsing format and show results output = new_buf(); foundcount=0; linecount=0; for ( obj = keeper->carrying; obj && linecount<200;obj = obj->next_content ) { if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) && ( cost = get_cost( keeper, obj, true ) ) > 0 ) { // do the filtering if (doingFiltering){ if(levelBasedFiltering){ if (obj->level<min_obj_level){ continue; } if (obj->level>max_obj_level){ continue; } }else{ // substring match filter if (!is_name(arg,obj->name)){ continue; } } } if ( foundcount==0 ){ add_buf(output," [Lv Price Qty] Item (type?)\r\n"); } foundcount++; // colour code wearable items vs unwearable if( ( IS_SET(obj->extra_flags, OBJEXTRA_MAGIC) && HAS_CLASSFLAG(ch, CLASSFLAG_MAGIC_ANTIPATHY) ) ||( !IS_NPC(ch) && obj->pIndexData->relative_size < race_table[ch->race]->low_size && obj->item_type != ITEM_LIGHT && !CAN_WEAR( obj, OBJWEAR_HOLD) && !CAN_WEAR( obj, OBJWEAR_FLOAT) ) ||( !IS_NPC(ch) && obj->pIndexData->relative_size>race_table[ch->race]->high_size && obj->item_type != ITEM_LIGHT && !CAN_WEAR( obj, OBJWEAR_FLOAT) ) ) { can_wear=0; }else{ can_wear=1; } if(!IS_NPC(ch) && can_wear) { can_wear = DISALLOWED_OBJECT_FOR_CHAR(obj, ch)?0:1; } if(can_wear==1){ add_buf(output,"`x"); }else{ add_buf(output,"`s"); } //// end of colour coding // create an mxp short descript char short_descr[MSL]; if(obj->item_type == ITEM_WEAPON){ strcpy(short_descr, mxp_create_tag(ch, FORMATF("buy-uid %d", obj->uid), FORMATF("%-25s", obj->short_descr))); }else{ strcpy(short_descr, mxp_create_tag(ch, FORMATF("buy-uid %d", obj->uid), obj->short_descr)); } if (IS_OBJ_STAT(obj,OBJEXTRA_INVENTORY)) if (obj->item_type == ITEM_WEAPON) { sprintf(buf,"[%2d %6d -- ] %s (%s)\r\n", obj->level,cost,short_descr, get_weapontype(obj)); }else{ sprintf(buf,"[%2d %6d -- ] %s\r\n", obj->level,cost,short_descr); } else { count = 1; while (obj->next_content != NULL && obj->pIndexData == obj->next_content->pIndexData && !str_cmp(obj->short_descr, obj->next_content->short_descr)) { obj = obj->next_content; count++; } if (obj->item_type == ITEM_WEAPON) { sprintf(buf,"[%2d %6d %2d ] %s (%s)\r\n", obj->level,cost,count,short_descr, get_weapontype(obj)); } else { sprintf(buf,"[%2d %6d %2d ] %s\r\n", obj->level,cost,count,short_descr); } } //holyvnum if (!IS_UNSWITCHED_MOB(ch) && IS_SET(TRUE_CH(ch)->act, PLR_HOLYVNUM)) { if (obj->pIndexData) { sprintf(buf2," `#`s[%d,%d]`^\r\n", obj->pIndexData->vnum, obj->level); buf[str_len(buf)-2]= '\0'; // chop off the \r\n strcat(buf,buf2); } } // number each item strcpy(buf2, mxp_create_tag(ch, FORMATF("buy-uid %d", obj->uid), FORMATF("%2d", linecount+1))); add_buf(output,buf2); // add the the buffer the item details add_buf(output,buf); linecount++; } } if ( linecount==0 ) { if (IS_NULLSTR(arg)) ch->println("You can't buy anything here."); else ch->println("No matching items found."); } if (linecount>200){ add_buf(output,"`xCan only list 200 lines on the list at one time.\r\n"); add_buf(output,"filter the list by level range to access the \r\n" "information regarding the complete list.\r\n"); }else if ( IS_NEWBIE(ch) && linecount>20 ) { add_buf(output,"`xYou can actually filter the list, for example if you wanted to \r\n"); add_buf(output,"purchase an item that was green, type `=Clist green`x. If the item was\r\n"); add_buf(output,"displayed as the 3rd on the list then to purchase it type `=Cbuy 3.green`x\r\n"); } ch->sendpage(buf_string(output)); free_buf(output); return; } } /************************************************************************/ void sell_object(char_data *ch, char_data *keeper, OBJ_DATA *obj) { char buf[MSL]; int cost,roll; if ( !can_drop_obj( ch, obj ) ) { ch->printlnf( "You can't let go of %s.", obj->short_descr); return; } if (( obj->item_type == ITEM_CAULDRON || obj->item_type == ITEM_CONTAINER || obj->item_type == ITEM_FLASK || obj->item_type == ITEM_MORTAR ) && obj->contains) { ch->printlnf( "Try emptying everything out of %s before selling it.", obj->short_descr); return; } if (!can_see_obj(keeper,obj)) { act("$n doesn't appear to be able to see $p.",keeper,obj,ch,TO_VICT); return; } if ( ( cost = get_cost( keeper, obj, false ) ) <= 0 ) { act( "`s$n looks uninterested in $p.`x", keeper, obj, ch, TO_VICT ); return; } if ( cost > (keeper-> silver + 100 * keeper->gold) ) { act("$n tells you 'I'm afraid I don't have enough wealth to buy $p.", keeper,obj,ch,TO_VICT); return; } act( "$n sells $p.", ch, obj, NULL, TO_ROOM ); // haggle roll = number_percent(); if (!IS_OBJ_STAT(obj,OBJEXTRA_SELL_EXTRACT) && roll < get_skill(ch,gsn_haggle)) { ch->println("You haggle with the shopkeeper."); cost += obj->cost / 2 * roll / 100; cost = UMIN(cost,95 * get_cost(keeper,obj,true) / 100); cost = UMIN(cost,(keeper->silver + 100 * keeper->gold)); check_improve(ch,gsn_haggle,true,4); } if (((int)cost/100)>0) { sprintf( buf, "You sell $p for %d silver and %d gold piece%s.", cost - (cost/100) * 100, cost/100, cost == 1 ? "" : "s" ); } else { sprintf( buf, "You sell $p for %d silver piece%s.", cost - (cost/100) * 100, cost == 1 ? "" : "s" ); } act( buf, ch, obj, NULL, TO_CHAR ); ch->gold += cost/100; ch->silver += cost - (cost/100) * 100; deduct_cost(keeper,cost); if ( keeper->gold < 0 ) keeper->gold = 0; if ( keeper->silver< 0) keeper->silver = 0; if ( obj->item_type == ITEM_TRASH || IS_OBJ_STAT(obj,OBJEXTRA_SELL_EXTRACT)) { extract_obj( obj ); } else { obj_from_char( obj ); if (obj->timer) SET_BIT(obj->extra_flags,OBJEXTRA_HAD_TIMER); else obj->timer = number_range(50,100); obj_to_keeper( obj, keeper ); } } /**************************************************************************/ void do_sell( char_data *ch, char *argument ) { char arg[MIL], allarg[MIL]; char_data *keeper; OBJ_DATA *obj, *obj_next; int count=0; one_argument( argument, arg ); if (!str_cmp("all", arg )){ strcpy(arg,"all."); } if ( !str_prefix( "all.", arg ) ) { strcpy(allarg, arg+4); } if ( arg[0] == '\0' ) { ch->println("Sell what?"); return; } if ( ( keeper = find_keeper( ch ) ) == NULL ) return; if ( str_prefix( "all.", arg) ) { if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { act( "$n tells you 'You don't have that item'",keeper, NULL, ch, TO_VICT ); return; } } else { if ( ( obj = get_obj_carry( ch, allarg ) ) == NULL ) { ch->println( "No matching items found to sell." ); return; } } if (!can_see(keeper,ch)) { act("$n doesn't appear to be able to see you.",keeper,NULL,ch,TO_VICT); return; } /* Slortar 24/03/02 This check is handled in sell_object and does not exit the function when argument is 'all' if (!can_see_obj(keeper,obj)) { act("$n doesn't appear to be able to see $p.",keeper,obj,ch,TO_VICT); return; } */ /************/ if ( str_prefix( "all.", arg ) ) { // 'sell obj' if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { ch->println( "You do not have that item." ); return; } sell_object(ch, keeper, obj); } else // 'sell all.obj' { // PC being ordered to do this if ( !IS_NPC(ch) && IS_SET( ch->dyn, DYN_IS_BEING_ORDERED )) { if ( ch->master ){ ch->master->println( "Not going to happen." ); } return; } for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if (is_name( allarg, obj->name) && can_see_obj( ch, obj ) && obj->wear_loc == WEAR_NONE) { if(IS_NULLSTR(allarg) && get_cost( keeper, obj, false )<=0 ){ // true if was a 'sell all' and keeper not interested in type of object continue; } if (count++>25) { ch->println( "You can only sell up to 25 items at a time." ); return; } sell_object(ch, keeper, obj); // lag for selling multiple items WAIT_STATE(ch, 1); if (ch->fighting) WAIT_STATE(ch, 5); } } if(IS_NULLSTR(allarg) && count==0){ act( "`s$n doesn't look interested in anything you have.`x", keeper, obj, ch, TO_VICT ); }else if(count==25){ act( "`sYou have nothing else that $n is interested in buying.`x", keeper, obj, ch, TO_VICT ); } } return; } /**************************************************************************/ void do_value( char_data *ch, char *argument ) { char buf[MSL]; char arg[MIL]; char_data *keeper; OBJ_DATA *obj; int cost; one_argument( argument, arg ); if ( IS_NULLSTR(arg) ) { ch->println( "Value what?" ); return; } if ( ( keeper = find_keeper( ch ) ) == NULL ) return; if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { act( "$n tells you 'You don't have that item'.", keeper, NULL, ch, TO_VICT ); //ch->reply = keeper; return; } if (!can_see_obj(keeper,obj)) { act("$n doesn't see what you are offering.",keeper,NULL,ch,TO_VICT); return; } if ( !can_drop_obj( ch, obj ) ) { ch->println( "You can't let go of it." ); return; } if ( ( cost = get_cost( keeper, obj, false ) ) <= 0 ) { act( "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT ); return; } sprintf( buf, "$n tells you 'I'll give you %d silver and %d gold coins for $p'.", cost - (cost/100) * 100, cost/100 ); act( buf, keeper, obj, ch, TO_VICT ); //ch->reply = keeper; return; } /**************************************************************************/ // by Rathern void do_slice( char_data *ch, char *argument ) { OBJ_DATA *corpse; OBJ_DATA *obj; OBJ_DATA *slice; int lag; bool found; char buf[MSL]; found = false; if ( !IS_NPC(ch) && (ch->level < skill_table[gsn_slice].skill_level[ch->clss] || ch->pcdata->learned[gsn_slice] < 1 )) // skill is not known { ch->println("You are not learned in slicing meat from objects."); return; } if ( IS_NULLSTR(argument) ) { ch->println("From what do you wish to slice meat?"); return; } if ( ( obj = get_eq_char( ch, WEAR_WIELD ) ) == NULL || ( obj->value[3] != 1 && obj->value[3] != 2 && obj->value[3] != 3 && obj->value[3] != 11) ) { ch->println("You need to wield a sharp weapon."); return; } if ( (corpse = get_obj_here( ch, argument )) == NULL) { ch->println("You can't find that here."); return; } if (corpse->item_type != ITEM_CORPSE_NPC && corpse->item_type != ITEM_CORPSE_PC) { ch->println("That is not a suitable source of meat."); return; } // fiddle with the corpse after its been sliced to much if (corpse->timer < 2) { sprintf( buf,"A sliced up and rotting %s is lying here.", corpse->short_descr); free_string(corpse->description); corpse->description=str_dup(buf); ch->println("That meat is to old and used now."); return; } if ( get_obj_index(OBJ_VNUM_SLICE) == NULL ) { bugf("Vnum %d not found for do_slice!", OBJ_VNUM_SLICE); ch->printlnf( "Vnum %d not found for do_slice!, please report to the admin.", OBJ_VNUM_SLICE); return; } if ( !IS_NPC(ch) && !IS_IMMORTAL(ch) && number_percent() > ch->pcdata->learned[gsn_slice] ) { ch->println("You fail to slice the meat properly."); check_improve(ch,gsn_slice,false,1); // Just in case they die :> if ( number_percent() + ch->modifiers[STAT_QU] - 13 < 10) { act("You cut yourself, ouch that hurt!.",ch,NULL,NULL,TO_CHAR); damage( ch, ch, obj->level / 2, gsn_slice, DAM_SLASH, false ); } return; } // make and restring the slice of meat buf[0]='\0'; strcat(buf,"a slice of raw meat from "); strcat(buf,corpse->short_descr); strcat(buf," is lying here."); slice = create_object( get_obj_index(OBJ_VNUM_SLICE)); free_string(slice->description); slice->description=str_dup(buf); buf[0]='\0'; strcat(buf,"a slice of raw meat from "); strcat(buf,corpse->short_descr); free_string(slice->short_descr); slice->short_descr=str_dup(buf); slice->timer = 24; // make the meat rot in 1 day act("$n cuts a slice of meat from $p.", ch, corpse, NULL, TO_ROOM); act("You cut a slice of meat from $p.", ch, corpse, NULL, TO_CHAR); // give the sliced meat to the character obj_to_char(slice, ch); // make it so only 5 slices can be cut from any one corpse corpse->value[2]+=10; if (corpse->value[2] > 40) { corpse->timer = 1; } // delay depends on skill lag = skill_table[gsn_slice].beats; if (!IS_NPC(ch)) { lag -= (ch->pcdata->learned[gsn_slice] * 30 /100 ); } // reduce the lag for first slicing if (corpse->value[2]==10){ lag/=3; }else if (corpse->value[2]==20){ lag/=2; } check_improve(ch,gsn_slice,true,1); WAIT_STATE(ch,lag); return; } /**************************************************************************/ // Kalahn, May 98 - based off do_pour() void do_empty(char_data *ch, char *argument) { char arg[MSL], buf[MSL]; OBJ_DATA *out; argument = one_argument(argument,arg); if (IS_NULLSTR(arg)) { ch->println("Empty what drink container?"); return; } if ((out = get_obj_carry(ch,arg)) == NULL) { ch->println("You don't have that item."); return; } if (out->item_type != ITEM_DRINK_CON) { ch->println("That's not a drink container."); return; } if (out->value[1] == 0) { ch->println("It's already empty."); return; } out->value[1] = 0; out->value[3] = 0; sprintf(buf,"You invert $p, spilling %s all over the ground.", liq_table[out->value[2]].liq_name); act(buf,ch,out,NULL,TO_CHAR); sprintf(buf,"$n inverts $p, spilling %s all over the ground.", liq_table[out->value[2]].liq_name); act(buf,ch,out,NULL,TO_ROOM); return; } /**************************************************************************/ // By Kerenos & Kal - July 98 void do_throw( char_data *ch, char *argument ) { char arg1[MIL], arg2[MIL]; OBJ_DATA *obj; ROOM_INDEX_DATA *in_room, *to_room; EXIT_DATA *pexit; int door; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( IS_NULLSTR(arg1) || IS_NULLSTR(arg2)) { ch->println("Throw what in which direction?"); ch->println("syntax: throw <object> <direction>"); return; } if (IS_OOC(ch)){ ch->println("You can't throw objects in OOC rooms."); return; } if (( obj = get_obj_carry( ch, arg1)) == NULL ) { ch->println("You are not carrying that item."); return; } if ( !can_drop_obj( ch, obj )) { ch->println("You can't let go of that."); return; } door = dir_lookup( arg2 ); if ( door == -1 ) { ch->printlnf( "'%s' is an invalid direction.", arg2 ); ch->println("Syntax: throw <object> <direction>"); return; } in_room = ch->in_room; to_room = NULL; if ( (( pexit = in_room->exit[door] ) == NULL || ( to_room = pexit->u1.to_room ) == NULL || !can_see_room( ch, pexit->u1.to_room )) && strcmp( arg2, "down" )) { ch->println("You cannot throw in that direction."); return; } if ( to_room == NULL ) { act( "You throw $p to the floor.", ch, obj, NULL, TO_CHAR ); act( "$n throws $p to the floor.", ch, obj, NULL, TO_ROOM ); obj_from_char( obj ); obj_to_room( obj, in_room ); } else { if (IS_SET(to_room->room_flags, ROOM_OOC)){ ch->println("You can't throw objects into OOC rooms."); return; } // Allow those with holywalk to throw thru closed doors if ( IS_SET( pexit->exit_info, EX_CLOSED ) && !IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK) ) { ch->println("Try opening the door first."); return; } act( "You throw $p $T.", ch, obj, dir_name[door], TO_CHAR ); act( "$n throws $p $T.", ch, obj, dir_name[door], TO_ROOM ); obj_from_char( obj ); obj_to_room( obj, to_room ); ch->in_room = to_room; act( "With a resounding thud, $p lands in the room.", ch, obj, NULL, TO_ROOM ); ch->in_room = in_room; } if ( IS_OBJ_STAT( obj, OBJEXTRA_MELT_DROP )) { act( "$p dissolves into smoke.", ch, obj, NULL, TO_ROOM ); extract_obj( obj ); } #ifdef unix if (!IS_IMMORTAL(ch)) { WAIT_STATE( ch, PULSE_VIOLENCE ); } #endif } /**************************************************************************/ // mods by Kerenos void do_zap( char_data *ch, char *argument ) { OBJ_DATA *wand; int sn; // new stuff here char arg2[MIL]; char_data *victim; OBJ_DATA *obj; void *vo; int target; strcpy(arg2, argument); if ( ( wand = get_eq_char( ch, WEAR_HOLD ) ) == NULL ) { ch->println("You are holding nothing in your hands."); return; } if ( wand->item_type != ITEM_WAND ) { ch->println("You can only zap with a wand."); return; } if ( IS_SET( ch->in_room->room_flags, ROOM_ANTIMAGIC )) { act( "$p doesn't seem to have any power.", ch, wand, NULL, TO_CHAR ); return; } if (( sn = wand->value[3] ) < 0 || sn >= MAX_SKILL || skill_table[sn].spell_fun == 0 ) { bugf( "do_zap(): bad sn %d.", sn ); return; } WAIT_STATE( ch, 2 * PULSE_VIOLENCE ); if (wand->value[2] < -1){ wand->value[2] = -1; } if (( wand->value[2] > 0 ) || (wand->value[2] = -1)) { act( "$n holds out $p.", ch, wand, NULL, TO_ROOM ); act( "You hold out $p.", ch, wand, NULL, TO_CHAR ); if ( ch->level < wand->level || (get_skill(ch,gsn_wands)==0) || number_percent() >= 20 + get_skill(ch,gsn_wands) * 4/5) { act ("Your efforts with $p produce only smoke and sparks.",ch,wand,NULL,TO_CHAR); act ("...and nothing happens.",ch,NULL,NULL,TO_ROOM); check_improve(ch,gsn_wands,false,2); } else // cast the spell { // Locate targets. victim = NULL; obj = NULL; vo = NULL; target = TARGET_NONE; switch ( skill_table[sn].target ) { default: bugf( "do_zap(): bad target for sn %d.", sn ); return; case TAR_IGNORE: break; case TAR_MOB_OFFENSIVE: case TAR_CHAR_OFFENSIVE: if ( arg2[0] == '\0' ) { if ( ( victim = ch->fighting ) == NULL ) { ch->println("Zap whom?"); return; } } else { if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->println("They aren't here."); return; } } if ( !IS_NPC(ch) ) { if (is_safe(ch,victim) && victim != ch) { ch->println("Not on that target."); return; } } if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim ) { ch->println("You can't do that on your own follower."); return; } vo = (void *) victim; target = TARGET_CHAR; break; case TAR_CHAR_DEFENSIVE: if ( arg2[0] == '\0' ) { victim = ch; } else { if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->println("They aren't here."); return; } } vo = (void *) victim; target = TARGET_CHAR; break; case TAR_CHAR_SELF: if ( arg2[0] != '\0' && !is_name( arg2, ch->name ) ) { ch->println("You can't zap yourself while aiming it at another."); return; } vo = (void *) ch; target = TARGET_CHAR; break; case TAR_OBJ_INV: if ( arg2[0] == '\0' ) { ch->println("You can't find that."); return; } if ( ( obj = get_obj_carry( ch, arg2 ) ) == NULL ) { ch->println("You are not carrying that."); return; } vo = (void *) obj; target = TARGET_OBJ; break; case TAR_OBJ_MOB_OFF: case TAR_OBJ_CHAR_OFF: if (arg2[0] == '\0') { if ((victim = ch->fighting) == NULL) { ch->println("Zap whom or what?"); return; } target = TARGET_CHAR; } else if ((victim = get_char_room(ch,arg2)) != NULL) { target = TARGET_CHAR; } if (target == TARGET_CHAR) // check the sanity of the attack { if(is_safe_spell(ch,victim,false) && victim != ch) { ch->println("Not on that target."); return; } if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim ) { ch->println("You can't do that on your own follower."); return; } vo = (void *) victim; } else if ((obj = get_obj_here(ch,arg2)) != NULL) { vo = (void *) obj; target = TARGET_OBJ; } else { ch->println("You don't see that here."); return; } break; case TAR_OBJ_CHAR_DEF: if (arg2[0] == '\0') { vo = (void *) ch; target = TARGET_CHAR; } else if ((victim = get_char_room(ch,arg2)) != NULL) { vo = (void *) victim; target = TARGET_CHAR; } else if ((obj = get_obj_carry(ch,arg2)) != NULL) { vo = (void *) obj; target = TARGET_OBJ; } else { ch->println("You don't see that here."); return; } break; }// end of spell type switch if (IS_NPC(ch) || class_table[ch->clss].fMana) // clss has spells (*skill_table[sn].spell_fun) ( sn, wand->value[0], ch, vo,target); else (*skill_table[sn].spell_fun) (sn, wand->value[0], ch, vo,target); check_improve(ch,gsn_wands,true,2); } } // get rid of the staff if required if ( wand->value[2] == -1) { return; } wand->value[2]--; if (wand->value[2] < 1) { act( "$p blazes bright and is gone.", ch, wand, NULL, TO_ROOM ); act( "$p blazes bright and is gone.", ch, wand, NULL, TO_CHAR ); extract_obj( wand ); } return; } /************************************************************************/ void do_place( char_data *ch, char *argument) { char arg1 [MIL]; char arg2 [MIL]; char_data *victim; OBJ_DATA *obj; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' || arg2[0] == '\0' ) { ch->println("Place what on whom?"); return; } if ( ( obj = get_obj_carry( ch, arg1 ) ) == NULL ) { ch->println("You do not have that item."); return; } if ( obj->wear_loc != WEAR_NONE ) { ch->println("You must remove it first."); return; } if ( !can_drop_obj( ch, obj ) ) { ch->println("You can't let go of it."); return; } int chance = get_skill(ch, gsn_place); if (!str_cmp( arg2, "ground")) { char_data *vch, *vch_next; int lowerchance; for ( vch = char_list; vch != NULL; vch = vch_next ) { vch_next = vch->next; lowerchance=0; if ( vch->in_room == NULL ) continue; if ( vch->in_room == ch->in_room ) { if(vch->pcdata && vch->pcdata->is_trying_aware) lowerchance = (get_skill(vch, gsn_awareness))/6; lowerchance += (vch->level - ch->level)/3; if(IS_IMMORTAL(vch) || (number_percent()+lowerchance > chance && str_cmp(ch->name, vch->name))){ vch->printlnf( "You notice %s drop %s", ch->short_descr, obj->short_descr); check_improve(vch,gsn_awareness,true,1); } } } // silently drop it { int old_invis_level; SET_BIT(ch->dyn,DYN_SILENTLY); // back up the wizi level old_invis_level= ch->invis_level; // hide it from mortals ch->invis_level= UMAX(ch->invis_level, LEVEL_IMMORTAL); // drop the object do_drop(ch, arg1); // restore the wizi level ch->invis_level=old_invis_level; } WAIT_STATE( ch, skill_table[gsn_place].beats ); //shouldn't check improve if all they are doing is dropping it return; } if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { ch->println("They aren't here."); return; } if (!IS_NPC(victim) && victim->level<10 && ch->level>(victim->level+10) && !IS_NPC(ch) && !IS_IMMORTAL(ch)) { ch->println("A faint wall of light appears to surround them preventing you from placing that on them."); return; } if ( victim == ch ) { ch->println("That's pointless."); return; } if (IS_NPC(victim) && victim->pIndexData->pShop != NULL) { act("$N tells you 'Sorry, you'll have to sell that.'", ch,NULL,victim,TO_CHAR); return; } if ( !IS_CONTROLLED(victim) && victim->carry_number + get_obj_number( obj ) > can_carry_n( victim ) ) { act( "$N has $S hands full.", ch, NULL, victim, TO_CHAR ); return; } if (!IS_CONTROLLED(victim) && get_carry_weight(victim) + get_obj_weight(obj) > can_carry_w( victim ) ) { act( "$N can't carry that much weight.", ch, NULL, victim, TO_CHAR ); return; } if(victim->pcdata && victim->pcdata->is_trying_aware) chance -= (get_skill(victim, gsn_awareness))/6; if(!IS_AWAKE(victim)) chance += 50; if(number_percent() < chance+((ch->level - victim->level)/3)) { obj_from_char( obj ); obj_to_char( obj, victim ); ch->printlnf( "You successfully place %s on %s.", obj->short_descr, victim->short_descr ); check_improve(ch, gsn_place, true, 1); WAIT_STATE( ch, skill_table[gsn_place].beats ); return; } act( "$n tries to sneak $p to $N.", ch, obj, victim, TO_NOTVICT ); act( "You try to sneak $p to $N but get caught!", ch, obj, victim, TO_CHAR ); if (IS_AWAKE(victim)){ act( "$n tries to sneak $p into your inventory!", ch, obj, victim, TO_VICT ); if(victim->pcdata && victim->pcdata->is_trying_aware ) check_improve(victim,gsn_awareness,true,1); } else{ if( victim->pcdata && victim->pcdata->is_trying_aware && get_skill(victim, gsn_awareness) > number_percent() ) { victim->printlnf( "You feel the presence of another person lurking near you.\r\n" "You feel someone messing with your things and instantly pop awake!" ); victim->position=POS_RESTING; do_stand(victim,""); check_improve(victim,gsn_awareness,true,2); }else{ victim->printlnf( "You are partially awakened by someone in the room,\r\n" "you roll over and drift back to sleep." ); } } affect_strip ( ch, gsn_invisibility ); affect_strip ( ch, gsn_mass_invis ); affect_strip ( ch, gsn_sneak ); REMOVE_BIT ( ch->affected_by, AFF_HIDE ); REMOVE_BIT ( ch->affected_by, AFF_INVISIBLE ); REMOVE_BIT ( ch->affected_by, AFF_SNEAK ); if (!IS_NPC(victim)) { ch->pksafe=0; ch->pknorecall= (UMAX(ch->pknorecall,2)); ch->pknoquit=(UMAX(ch->pknoquit,10)); } check_improve(ch, gsn_place, false, 1); WAIT_STATE( ch, skill_table[gsn_place].beats*3/2 ); return; } /************************************************************************/ void do_attune( char_data *ch, char *argument) { OBJ_DATA *obj; int modifier = 0; int percent = number_percent(); int failure = 0; int seconds; if ( IS_NULLSTR( argument )) { ch->println( "Attune to which item?" ); return; } if ( IS_NPC( ch )) { ch->println( "Players only!" ); return; } obj = get_obj_list(ch,argument,ch->carrying); if (obj== NULL) { ch->println( "You don't have that item." ); return; } if ( !IS_SET( obj->attune_flags, ATTUNE_NEED_TO_USE )) { ch->println( "You don't need to attune yourself to that." ); return; } if ( obj->attune_id == ch->id ) { act( "You have already attuned yourself to $p.", ch, obj, NULL, TO_CHAR ); return; } if ( IS_SET( obj->attune_flags, ATTUNE_PREVIOUS )) { if ( IS_SET( obj->attune_flags, ATTUNE_ONCE_ONLY )) { act( "$p cannot be reattuned, it only obeys one master.", ch, obj, NULL, TO_CHAR ); return; } } if ( IS_SET( obj->attune_flags, ATTUNE_EQUAL_LEVEL )) { if (obj->level > ch->level) { act( "You lack the power to attune yourself to $p.", ch, obj, NULL, TO_CHAR ); return; } } if ( current_time < obj->attune_next ) { act( "You cannot attune to $p yet.", ch, obj, NULL, TO_CHAR ); return; } // ATTUNE mods modifier = ( ch->level - obj->level ); if ( modifier > 0 ) modifier *= 3; // +3% per positive level diff else modifier *=5; // -5% per negative level diff modifier += 50; // 50% mean chance // EM+EM+PR/3 bonus modifier += (( ch->modifiers[STAT_EM] + ch->modifiers[STAT_EM] +ch->modifiers[STAT_PR] )/3); // LORE bonus modifier += ((( get_skill( ch, gsn_lore) - 50 ) / 5) + (get_skill(ch, gsn_lore) > 0) ? 5 : 0); // +5% if lore > 50... range is -10 to +15% if ( IS_SET( obj->attune_flags, ATTUNE_TRIVIAL )) modifier += 25; if ( IS_SET( obj->attune_flags, ATTUNE_EASY )) modifier += 10; if ( IS_SET( obj->attune_flags, ATTUNE_HARD )) modifier -= 10; if ( IS_SET( obj->attune_flags, ATTUNE_INFURIATING )) modifier -= 25; if ( IS_SET( obj->attune_flags, ATTUNE_PREVIOUS )) obj->attune_modifier -= 10; modifier += obj->attune_modifier; failure = percent - modifier; // flag it as previously attempt at attunement for next time :) SET_BIT( obj->attune_flags, ATTUNE_PREVIOUS ); // they failed, let's set the next attune time (in ticks) if ( failure > 0 ) { if ( IS_SET( obj->attune_flags, ATTUNE_VANISH )) { act( "$p glows brightly for an instant, then crumbles to dust.", ch, obj, NULL, TO_CHAR ); act( "A flash of light emanates from $n and is gone in an instant.", ch, NULL, NULL, TO_ROOM ); extract_obj(obj); return; } seconds = obj->level * 3600; // 1 hour per object level base if ( failure > 30 ) { obj->attune_modifier -= 25; seconds *= 2; } else if ( failure > 10 ) { obj->attune_modifier -= 10; seconds *= 3/2; } else if ( failure > 0 ) { obj->attune_modifier += 10; seconds /= 2; } if ( IS_SET( obj->attune_flags, ATTUNE_TRIVIAL )) seconds /= 4; if ( IS_SET( obj->attune_flags, ATTUNE_EASY )) seconds /= 2; if ( IS_SET( obj->attune_flags, ATTUNE_HARD )) seconds *= 2; if ( IS_SET( obj->attune_flags, ATTUNE_INFURIATING )) seconds *= 3; obj->attune_next = current_time + seconds; act( "You try to exert your will upon $p but were unable to attune yourself to it.", ch, obj, NULL, TO_CHAR ); if ( !is_affected( ch, gsn_cause_headache )) { AFFECT_DATA af; ch->println( "Your head seems to explode with a sudden wave of indescribable pain!" ); af.where = WHERE_MODIFIER; af.type = gsn_cause_headache; af.level = obj->level; af.duration = obj->level; af.location = APPLY_SD; af.modifier = - obj->level/5; af.bitvector = 0; affect_to_char( ch, &af ); } act( "$p pulsates softly and falls to the ground.", ch, obj, NULL, TO_CHAR ); act( "$n holds $s head in pain and drops $p.", ch, obj, NULL, TO_ROOM ); obj_from_char( obj ); obj_to_room( obj, ch->in_room ); return; } else { obj->attune_id = ch->id; obj->attune_next = 0; act( "A bright flash envelops $p as you concentrate on it.", ch, obj, NULL, TO_CHAR ); act( "You have become one with $p.", ch, obj, NULL, TO_CHAR ); act( "$n is bathed in a flash of light as $e holds $p.", ch, obj, NULL, TO_ROOM ); } return; } /**************************************************************************/ void letter_read( char_data *ch, OBJ_DATA *letter ); /**************************************************************************/ // Show an object to another player - Kal Mar 01 void do_show( char_data *ch, char *argument) { char arg[MIL]; char *pdesc; char objname[MIL]; int number,count; OBJ_DATA *obj; argument=one_argument(argument, arg); number = number_argument(arg,objname); count = 0; if(IS_NULLSTR(argument)){ ch->println("Show what object to whom?"); ch->println("hint: if you want to display your affects at the bottom of your score use the `=Cshowaffects`x command"); return; } char_data *victim=get_char_room(ch, argument); if(!victim){ ch->printlnf("Could not find any '%s' in the room to show '%s' to.", argument, objname); return; } if(!IS_AWAKE(victim)){ ch->printlnf("%s doesnt appear to be awake.", capitalize(PERS(victim, ch))); return; } if(!can_see(victim, ch)){ ch->printlnf("%s doesn't appear to be able to see you.", capitalize(PERS(victim, ch))); return; } for ( obj = ch->carrying; obj != NULL; obj = obj->next_content ) { if ( can_see_obj( ch, obj ) ) { // player can see object // parchments take highest priority if ( obj->item_type == ITEM_PARCHMENT && is_name( objname, obj->name ) ) { if (++count == number) { if(can_see_obj( victim, obj )){ ch->printlnf("You show %s to %s.", obj->short_descr, PERS(victim, ch)); victim->printlnf("`W%s shows you %s, it reads:`x", capitalize(PERS(ch, victim)), obj->short_descr); letter_read( victim, obj ); }else{ ch->printlnf("It doesn't appear as though %s can see %s.", PERS(victim, ch), obj->short_descr); } return; } } // use only one of the sets of extended descriptions if (obj->extra_descr) { // unique objects extended descriptions pdesc = get_extra_descr( objname, obj->extra_descr ); if ( pdesc != NULL ) { if (++count == number) { if(can_see_obj( victim, obj )){ ch->printlnf("You show %s to %s.", obj->short_descr, PERS(victim, ch)); victim->printlnf("`W%s shows you %s:`x", capitalize(PERS(ch, victim)), obj->short_descr); victim->sendpage(pdesc); }else{ ch->printlnf("It doesn't appear as though %s can see %s.", PERS(victim, ch), obj->short_descr); } return; } else { continue; } } } else // vnums extended descriptions { pdesc = get_extra_descr( objname, obj->pIndexData->extra_descr ); if ( pdesc != NULL ) { if (++count == number) { if(can_see_obj( victim, obj )){ ch->printlnf("You show %s to %s.", obj->short_descr, PERS(victim, ch)); victim->printlnf("`W%s shows you %s:`x", capitalize(PERS(ch, victim)), obj->short_descr); victim->sendpage(pdesc); }else{ ch->printlnf("It doesn't appear as though %s can see %s.", PERS(victim, ch), obj->short_descr); } return; } else { continue; } } } if ( is_name( objname, obj->name ) ) { if (++count == number) { if(can_see_obj( victim, obj )){ ch->printlnf("You show %s to %s.", obj->short_descr, PERS(victim, ch)); victim->printlnf("`W%s shows you %s:`x", capitalize(PERS(ch, victim)), obj->short_descr); victim->printlnf( "%s", obj->description ); }else{ ch->printlnf("It doesn't appear as though %s can see %s.", PERS(victim, ch), obj->short_descr); } return; } } } } ch->printlnf("You possess no '%s' object to show %s.", arg, PERS(victim, ch)); } /************************************************************************/ /************************************************************************/ /************************************************************************/ /************************************************************************/