/* 
 * Wynter@Eternal Demise BETA
 * brutus.fractured.org 4000
 *
 * Keyrings give the ability to "hook" and "unhook" keys onto a object
 * saving space within thier inventory.
 *
 * Implimentation should be pretty straight-forward, I cut/paste part of
 * the functions, and the +'s are what I added.
 *
 * We currently have 5 value slots on objects, so that's what used for the
 * key count, you might need to change yours to be compatible with your mud.
 *
 * I didn't add a look feature as of it, as the work load piles even as
 * I type =)
 *
 * I guess a more appropriate way to do this would be to create a
 * container type keyring and add a check to has_key, but hey.. I was tired.
 *
 */


/*
 * Create a item type of ITEM_KEYRING in merc.h
 */

/*
 * -- act_move.c --
 *
 * in: OBJ_DATA* has_key( CHAR_DATA *ch, int key )
 */

        if ( obj->pIndexData->vnum == key )
            return obj;
        
+       if ( obj->item_type == ITEM_KEYRING )
+           for ( i = 0; i < 5; i++ )
+           {
+               if ( obj->value[i] == key )
+               {
+                   sprintf( buf, "You flip through %s for the key.\n\r", obj->short_descr );
+                   send_to_char( buf, ch );
+                   return obj;
+               }
+           }
    }

    return NULL;

/*
 * in: void do_unlock( CHAR_DATA *ch, char *argument )
 */

        if ( IS_SET( pexit->exit_info, EX_EAT_KEY ) )
        {
            for ( obj = ch->carrying; obj; obj = obj->next_content )
            {
                if ( obj->pIndexData->vnum == pexit->key )
                {
                    extract_obj( obj );
                    break;
                }

+               if ( obj->item_type == ITEM_KEYRING )
+                   for ( i = 0; i < 5; i++ )
+                       if ( obj->value[i] == pexit->key )
+                           obj->value[i] = 0;
+                           break;
            }

            act( "The $d eats the key!", ch, NULL, pexit->keyword, TO_CHAR );
            act( "The $d eats the key!", ch, NULL, pexit->keyword, TO_ROOM );

/* 
 * -- bit.c --
 *
 * in: 	const   struct  flag_type       type_flags      [ ]     =
 */
     {   "drink-container",      ITEM_DRINK_CON,         TRUE    },
     {   "key",                  ITEM_KEY,               TRUE    },
+    {   "keyring",              ITEM_KEYRING,           TRUE    },
     {   "food",                 ITEM_FOOD,              TRUE    },

/*
 * -- db.c --
 *
 * in: OBJ_DATA *create_object( OBJ_INDEX_DATA *pObjIndex, int level )
 */

    case ITEM_MONEY:
    	obj->value[0]	= obj->cost;
	break;

+    case ITEM_KEYRING:
+    	obj->value[0]	= 0;
+	obj->value[1]	= 0;
+	obj->value[2]   = 0;
+	obj->value[3]   = 0;
+	obj->value[4]   = 0;
    }

    obj->next           = object_list;
    object_list         = obj;

/* 
 * -- handler.c --
 *
 * in: 	char *item_type_name( OBJ_DATA *obj )
 */

     case ITEM_DRINK_CON:        return "drink container";
     case ITEM_KEY:              return "key";
+    case ITEM_KEYRING:          return "keyring";
     case ITEM_FOOD:             return "food";

/*
 * Add these two functions to where ever you feel is best.. I put mine in
 * act_obj.c
 */

void do_hook( CHAR_DATA *ch, char *argument )
{
    OBJ_DATA *key, *keyring;
    char buf[MAX_STRING_LENGTH];
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    int  slot = 0;
    bool openslot;

    openslot = FALSE;

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );

    if ( arg1[0] == '\0' || arg2[0] == '\0' )
    {
        send_to_char( "Syntax: Hook <key> <keyring>.\n\r", ch );
        return;         
    }                          
        
    if ( ( key = get_obj_carry( ch, arg1, ch ) ) == NULL )
    {   
        send_to_char( "You don't appear to be carrying that key.\n\r", ch );
        return;                
    } 

    if ( key->item_type != ITEM_KEY )
    {
        send_to_char( "That doesn't appear to be a key.\n\r", ch );                                               
        return;
    }

    if ( ( keyring = get_obj_carry( ch, arg2, ch ) ) == NULL )
    {
	send_to_char( "You don't appear to be carrying that keyring.\n\r", ch );
	return;
    }

    if ( keyring->item_type != ITEM_KEYRING )
    {
	send_to_char( "That doesn't appear to be a keyring.\n\r", ch );
	return;
    }

    for ( slot = 0; slot <= 4; slot++ )
	if ( keyring->value[slot] == 0 )
	{
	    keyring->value[slot] = key->pIndexData->vnum;
	    sprintf( buf, "You hook %s onto %s.\n\r",
		    key->short_descr, keyring->short_descr );
	    send_to_char( buf, ch );
	    obj_from_char( key );
	    openslot = TRUE;
	    break;
	}

    if ( !openslot )
    {
	sprintf( buf, "There is no more available space on %s!\n\r", keyring->short_descr );
	send_to_char( buf, ch );
    }
    
    return;
}



void do_unhook( CHAR_DATA *ch, char *argument )
{
    OBJ_DATA *key, *keyring;
    char buf[MAX_STRING_LENGTH];
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    int  slot = 0;
    bool objfound = FALSE;

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );

    if ( arg1[0] == '\0' || arg2[0] == '\0' )
    {
    	send_to_char( "Syntax: Unhook <key> <keyring>.\n\r", ch );
	return;
    }

    if ( ( keyring = get_obj_carry( ch, arg2, ch ) ) == NULL )
    {
    	send_to_char( "You don't appear to be carrying that keyring.\n\r", ch );
	return;
    }

    if ( keyring->item_type != ITEM_KEYRING )
    {
    	send_to_char( "That doesn't appear to be a keyring.\n\r", ch );
	return;
    }

    for ( slot = 0; slot <= 4; slot++ )
    {
    	if ( keyring->value[slot] > 0 )
	{
	    key = create_object( get_obj_index( keyring->value[slot] ), 1 );

	    if ( is_name( arg1, key->name ) )
	    {
	    	obj_to_char( key, ch );
		keyring->value[slot] = 0;
		sprintf( buf, "You remove %s from %s.\n\r", key->short_descr, keyring->short_descr );
		send_to_char( buf, ch );
		objfound = TRUE;
		break;
	    }
	    
	    extract_obj( key );
	}
    }

    if ( !objfound )
    	send_to_char( "Could not find that key on keyring!\n\r", ch );

    return;
}

/* Help */
0 hook unhook keyring~

{x{cSyntax: {o{whook   <key> <keyring>{x
{o{w        unhook <key> <keyring>{x

Hook gives you the ability to store a key to a keyring which will
allow the unlocking of doors without the need to carry a bunch of
different keys in your inventory. Each keyring can hold a maximum
of 5 keys, and still can not be saved when you quit.

{o{rAlso see: {o{wPick, Open, Close, Unlock and Lock{x

~