In mix.cpp

Below void do_herbalism add:

void do_cook( char_data *ch, char *argument)
{
	mix_data	*m;
	OBJ_DATA	*container;
	OBJ_DATA	*obj;
	OBJ_DATA		*fire;
	ROOM_INDEX_DATA	*pIndexRoom = ch->in_room;
	vn_int		vnum_elements[6], vtemp = 0;
	sh_int		num_elements[6];
	int			total_elements = 0;
	int			i;
	int			chance;
	int			level;
	bool		mFound = false;
	bool			foundfire = false;

	for ( fire = pIndexRoom->contents; fire; fire = fire->next_content ) {
		if ( fire->pIndexData->vnum == OBJ_VNUM_FIRE ) {
			foundfire = true;
			break;
		}
    }

	if ( !foundfire ) {
		ch->println("There needs to be a fire for you to cook properly.");
		return;
	}


	// see if they know how to cook in the first place
	if ( get_skill( ch, gsn_cook ) == 0 )
	{
		ch->println( "You don't know the first thing about cooking." );
		return;
	}

	if ( IS_NULLSTR( argument ))
	{
		ch->println( "You must specify a valid pot or pan in which to cook your ingredients." );
		return;
	}

	// start off easy, get the container obj
	if (( container = get_obj_carry( ch, argument )) == NULL )
	{
		ch->println( "You are not carrying that." );
		return;
	}

	// determine if it's a valid container
	switch ( container->item_type )
	{
	default:
		{
			ch->println( "You can't cook with that." );
			return;
		}
	case ITEM_CAULDRON:
		{
			ch->println( "You can't cook in a cauldron.\nThose are for making potions." );
			return;
		}
	case ITEM_POT:
	case ITEM_PAN:
		break;
	}

	// check for an empty container to crap out at the earliest point
	if ( container->contains == NULL )
	{
		ch->printlnf( "There is nothing in %s.", container->short_descr );
		return;
	}

	// initialize
	for ( i = 0; i < 5; i++ )
	{
		num_elements[i]  = 0;
		vnum_elements[i] = 0;
	}

	// main counting loop to catalogue all the items in the container
	for ( obj = container->contains; obj; obj = obj->next_content )
	{
		vtemp = obj->pIndexData->vnum;

		for ( i=0; i < 5; i++ )
		{
			// increment count of elements if same object found
			if ( vtemp == vnum_elements[i] )
			{
				num_elements[i]++;
				break;
			}
			else if ( vnum_elements[i] == 0 )
			{
				// found a new unique item
				vnum_elements[i] = vtemp;
				num_elements[i]++;
				total_elements++;
				break;
			}
		}
	}

	// finally catalogued all items in the container, time to sort'em
	mix_bsort( vnum_elements, num_elements, 5 );
	
	// time to compare the catalogued contents vs the mixture dbase
	// by now, both are sorted by this point for easier comparison
	for ( m = mix_list; m; m = m->next )
	{
		if ( m->type == MIXTYPE_COOKING )
		{
			for ( i = 0; i < 5; i++ )
			{
				mFound = false;
				if (!( vnum_elements[i] == m->ingredients[i] 
					&& num_elements[i]  == m->ingredients_num[i] ))
				{
					mFound = false;
					break;
				}
				mFound = true;
			}
		}
		if ( mFound )
			break;
	}

	// if we didn't find a matching mix, ditch all the ingredients
	if ( !mFound )
	{
		ch->println( "You try to combine the ingredients.\nThey yield no useful result." );
		empty_container( container );
		return;
	}

	level = UMAX(1, ch->level - (( 5 - modifier_table[m->difficulty].type ) * 3 ));
	if ( !IS_IMMORTAL(ch) && level > LEVEL_HERO ){
		level = LEVEL_HERO;
	}

	// VESSEL CHECK ?

	// skill check to see if the result will happen or not
	chance = (( get_skill( ch, gsn_herbalism ) - m->difficulty ) + ch->modifiers[STAT_IN] );
	if ( chance >= number_percent() )
	{
		OBJ_INDEX_DATA	*obj_template;
		OBJ_DATA		*result;
		
		// success, let's restring
		if (( obj_template = get_obj_index( m->vnum_template )) == NULL )
		{
			ch->printlnf( "Vnum %d is missing for the %s mix, write a note to realm/admin",
				m->vnum_template, m->name );
			return;
		}

		result = create_object( obj_template);

		replace_string( result->name,		 m->rname );
		replace_string( result->short_descr, m->rshort );
		replace_string( result->description, m->rlong  );

		result->level			= ch->level;
		result->item_type		= m->ritem_type;
		result->wear_flags		= m->rwear;
		
		for ( i = 1; i < 5; i++ ){
			result->value[i]	= m->rvalue[i];
		}
		result->value[0]		= level;

		ch->printlnf( "You cook the ingredients within %s.\nYou have made %s.",
			container->short_descr, m->rshort );
		act( "$n busies $mself and cooks some food within $p.", ch, container, NULL, TO_ROOM );
		empty_container( container );
		obj_to_obj( result, container );
		WAIT_STATE( ch, skill_table[gsn_cook].beats );
		check_improve( ch, gsn_cook, true, 3 );
	}
	// failed, create a bad result
	else
	{
		OBJ_INDEX_DATA	*obj_template;
		OBJ_DATA		*result;

		if (( obj_template = get_obj_index( number_range( BADMIX_LVNUM, BADMIX_HVNUM ))) == NULL )
		{
			ch->printlnf( "Vnum %d (between BADMIX_LVNUM and BADMIX_HVNUM) is missing for the %s mix, write a note to realm/admin",
				m->vnum_template, m->name );
			return;
		}
		result = create_object( obj_template);
		ch->printlnf( "You cook the ingredients within  %s and have made %s.",
			container->short_descr, m->rshort );

		replace_string( result->name,		 m->rname );
		replace_string( result->short_descr, m->rshort );
		replace_string( result->description, m->rlong  );
		result->level= level;

		act( "$n busies $mself and cooks some food within $p.", ch, container, NULL, TO_ROOM );
		WAIT_STATE( ch, skill_table[gsn_cook].beats );
		check_improve( ch, gsn_cook, true, 3 );
		empty_container( container );
		obj_to_obj( result, container );
	}
}