This are the drug system used for the Metaverse Project, allowing the
players to actually mix potions from a selection of components and
this based on two skills.
2 skills, 20 components and a selection of spells will have to be 
added for this snippet to work, see details after the do_mix.

/********************************************************************
*  	Designed by Dex for the Metaverse Project.		    *
*	Charite@mail1.stofanet.dk				    *
*	home1.stofanet.dk/charite				    *
*	No fancy copyrights, you most likely know the drill	    *
********************************************************************/

void do_mix(CHAR_DATA *ch, char *argument)
{
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    char arg3[MAX_INPUT_LENGTH];
    char buf[MAX_STRING_LENGTH];
	int skill;
	char *name;
	char *type;
	int level;
    OBJ_DATA *obj1;
    OBJ_DATA *obj2;
    OBJ_DATA *obj3;
	OBJ_DATA *drug;

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

    /* check to see how many components the character wants to use */
    if ( arg1[0] == '\0' )
    {
	send_to_char( "You need 3 ingridients to mix a drug.\n\r", ch );
	return;
    }

    if ( arg2[0] == '\0' )
    {
	send_to_char( "You need 2 more ingridients.\n\r", ch );
	return;
    }

    if ( arg3[0] == '\0' )
    {
	send_to_char( "You need 1 more ingridient.\n\r", ch );
	return;
    }

    /* do he have the components ? */
    if ( ( obj1 = get_obj_carry( ch, arg1, ch ) ) == NULL )
    {
	send_to_char( "You need to have the 3 proper ingridients.\n\r", ch );
	return;
    }

    if ( ( obj2 = get_obj_carry( ch, arg2, ch ) ) == NULL )
    {
	send_to_char( "You need to have the 3 proper ingridients.\n\r", ch );
	return;
    }

    if ( ( obj3 = get_obj_carry( ch, arg3, ch ) ) == NULL )
    {
	send_to_char( "You need to have the 3 proper ingridients.\n\r", ch );
	return;
    }

	skill = 5;

	/* the formula list */
	/* first the 3 required components, then a skill counter, 1 for
	herbalism, 2 for chemistry and 3 for both, then the drug name,
	the spell name and lastly the level */
	if ( !str_cmp (arg1, "nightbloom") && !str_cmp (arg2, "starflower")
	&& !str_cmp (arg3, "boontai")) 
	{
	skill = 1;		
	name = "mind rest";		
	type = "mental restore";	
	level = 20;
	}
	if ( !str_cmp (arg1, "thinner") && !str_cmp (arg2, "biohazard")
	&& !str_cmp (arg3, "thinner"))
	{
	skill = 2;
	name = "mental restoration";
	type = "mental restore";
	level = 40;
	}
	if ( !str_cmp (arg1, "swampflower") && !str_cmp (arg2, "viral")
	&& !str_cmp (arg3, "sustainer"))
	{
	skill = 3;
	name = "mind boost";
	type = "mental restore";
	level = 60;
	}
	if ( !str_cmp (arg1, "velvet") && !str_cmp (arg2, "dustroot")
	&& !str_cmp (arg3, "mistrose"))
	{
	skill = 1;
	name = "revite";
	type = "bio restore";
	level = 20;
	}
	if ( !str_cmp (arg1, "neutralizer") && !str_cmp (arg2, "densifier")
	&& !str_cmp (arg3, "thinner"))
	{
	skill = 2;
	name = "recover";
	type = "bio restore";
	level = 40;
	}
	if ( !str_cmp (arg1, "dustroot") && !str_cmp (arg2, "viral")
	&& !str_cmp (arg3, "kchinch"))
	{
	skill = 3;
	name = "restore";
	type = "bio restore";
	level = 60;
	}
	if ( !str_cmp (arg1, "starflower") && !str_cmp (arg2, "velvet")
	&& !str_cmp (arg3, "swowroot"))
	{
	skill = 1;
	name = "vitalize";
	type = "refresh";
	level = 20;
	}
	if ( !str_cmp (arg1, "viral") && !str_cmp (arg2, "neutralizer")
	&& !str_cmp (arg3, "thinner"))
	{
	skill = 2;
	name = "stamina boost";
	type = "refresh";
	level = 40;
	}
	if ( !str_cmp (arg1, "freshener") && !str_cmp (arg2, "densifier")
	&& !str_cmp (arg3, "biohazard"))
	{
	skill = 2;
	name = "enhanced nightsight";
	type = "enhanced nightsight";
	level = 20;
	}
	if ( !str_cmp (arg1, "freshener") && !str_cmp (arg2, "swampflower")
	&& !str_cmp (arg3, "biohazard"))
	{
	skill = 3;
	name = "stamina recovery";
	type = "refresh";
	level = 60;
	}
	if ( !str_cmp (arg1, "viral") && !str_cmp (arg2, "alterator")
	&& !str_cmp (arg3, "sterilizer"))
	{
	skill = 2;
	name = "speed booster";
	type = "speed booster";
	level = 20;
	}
	if ( !str_cmp (arg1, "nightbloom") && !str_cmp (arg2, "velvet")
	&& !str_cmp (arg3, "rockweed"))
	{
	skill = 1;
	name = "antidote";
	type = "cure poison";
	level = 35;
	}
	if ( !str_cmp (arg1, "snowroot") && !str_cmp (arg2, "rockweed")
	&& !str_cmp (arg3, "nightbloom"))
	{
	skill = 1;
	name = "antibiotica";
	type = "cure disease";
	level = 40;
	}
	if ( !str_cmp (arg1, "sustainer") && !str_cmp (arg2, "alterator")
	&& !str_cmp (arg3, "viral"))
	{
	skill = 2;
	name = "sight restorer";
	type = "cure blindness";
	level = 30;
	}
	if ( !str_cmp (arg1, "viral") && !str_cmp (arg2, "dustroot")
	&& !str_cmp (arg3, "freshener"))
	{
	skill = 3;
	name = "pain killer";
	type = "cure pain";
	level = 60;
	}
	if ( !str_cmp (arg1, "viral") && !str_cmp (arg2, "biohazard")
	&& !str_cmp (arg3, "softener"))
	{
	skill = 2;
	name = "combat sense";
	type = "combat sense";
	level = 30;
	}
	if ( !str_cmp (arg1, "sustainer") && !str_cmp (arg2, "neutralizer")
	&& !str_cmp (arg3, "dustroot"))
	{
	skill = 3;
	name = "physical power";
	type = "enhance str";
	level = 30;
	}
	if ( !str_cmp (arg1, "mistrose") && !str_cmp (arg2, "rockweed")
	&& !str_cmp (arg3, "swampflower"))
	{
	skill = 1;
	name = "staminator";
	type = "enhance con";
	level = 30;
	}
	if ( !str_cmp (arg1, "sterilizer") && !str_cmp (arg2, "viral")
	&& !str_cmp (arg3, "densifier"))
	{
	skill = 2;
	name = "brain power";
	type = "enhance int";
	level = 30;
	}
	if ( !str_cmp (arg1, "sustainer") && !str_cmp (arg2, "alterator")
	&& !str_cmp (arg3, "nightbloom"))
	{
	skill = 3;
	name = "total recovery";
	type = "total recovery";
	level = 30;
	}
	if ( !str_cmp (arg1, "dustroot") && !str_cmp (arg2, "dustroot")
	&& !str_cmp (arg3, "snowroot"))
	{
	skill = 1;
	name = "sense enhancement";
	type = "sense enhancement";
	level = 30;
	}
	if ( !str_cmp (arg1, "densifier") && !str_cmp (arg2, "sterilizer")
	&& !str_cmp (arg3, "sterilizer"))
	{
	skill = 2;
	name = "reflex enhancement";
	type = "enhance dex";
	level = 30;
	}
	/* skill checks */
	if (skill == 1)
	{
    if (number_percent() <= get_skill(ch,gsn_herbalism))
	{
	check_improve(ch,gsn_manifacture,TRUE,2);
	skill = 0;
	}
	}
	if (skill == 3)
	{
    if (number_percent() <= get_skill(ch,gsn_chemistry)
	&& number_percent() <= get_skill(ch,gsn_herbalism))
	{
	check_improve(ch,gsn_manifacture,TRUE,2);
	check_improve(ch,gsn_herbalism,TRUE,2);
	skill = 0;
	}
	}
	if (skill == 2)
	{
    if (number_percent() <= get_skill(ch,gsn_chemistry))
	{
	check_improve(ch,gsn_manifacture,TRUE,2);
	skill = 0;
	}
	}

	/* skills ok, lets make the potion and remove the
	components */
	if (skill == 0)
	{
    	drug = create_object( get_obj_index( OBJ_VNUM_VIAL ), 0 );
    	drug->value[0] = level;
    	drug->value[1] = skill_lookup( type );
    	sprintf( buf, drug->short_descr, name );
    	free_string( drug->short_descr );
    	drug->short_descr = str_dup( buf );
    	sprintf( buf, drug->name, name );
    	free_string( drug->name );
    	drug->name = str_dup( buf );
    	sprintf( buf, drug->description, name );
    	free_string( drug->description );
	drug->description = str_dup( buf );
	obj_to_char (drug, ch);
	send_to_char ("You mix a drug.\n\r", ch);
	extract_obj (obj1);
	extract_obj (obj2);
	extract_obj (obj3);
	send_to_char( "you earn some exp for your work.\n\r", ch );
	gain_exp( ch, number_range (10,30) );
	}
	else
	{
	/* skills not ok, lets just remove the components */
	send_to_char ("You failed to mix it properly and spoiled the ingridients.\n\r", ch);
	extract_obj (obj1);
	extract_obj (obj2);
	extract_obj (obj3);
	}
}
------------------------------------------------------------------------
Commands needed to be added:
mix

Skills needed to be added:
chemistry	herbalism

Components, a selection of objects that needs to be added :
CHEMICAL:		HERB:
densifier		velvet
thinner			kchinch
softener		boontai
sterilizer		starflower
sustainer		nightbloom
alterator		rockweed
neutralizer		duskroot
freshener		mistrose
biohazard		snowroot
viral			swampflower

You need to make an object for each component and make sure that
one of the objects names matches the component name 100%
It may match several names if it is a mixed component, the coding
will accept that, but will still always remove 3 components (this
is a potential bug and should be avoided. The same bug may appear
if a drug has two identical components).

You will most likely need to replace many of the spell names above
as several are unique to the Metaverse Project.
-------------------------------------------------------------------
Drug sense spell.
This spell has a component table matching those in the drug mixing
section and allows a player to identify a drug he has come in
possession of.
This will have to be updated and changed whenever the drugs in
do_mix is.

void spell_drug_sense( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    OBJ_DATA *obj = (OBJ_DATA *) vo;

	if (obj->value[1] = skill_lookup( "mind rest" ))
		send_to_char ("This drug requires nightbloom, starflower, boontai.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "mental restoration" ))
		send_to_char ("This drug requires thinner, biohazard, thinner.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "mind boost" ))
		send_to_char ("This drug requires swampflower, viral, sustainer.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "revite" ))
		send_to_char ("This drug requires velvet, dustroot, mistrose.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "recover" ))
		send_to_char ("This drug requires neutralize, densifier, thinner.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "restore" ))
		send_to_char ("This drug requires dustroot, viral, kchinch.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "vitalize" ))
		send_to_char ("This drug requires starflower, velvet, snowroot.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "stamina boost" ))
		send_to_char ("This drug requires viral, densifier, thinner.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "enhanced nightsight" ))
		send_to_char ("This drug requires freshener, densifier, biohazard.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "stamina recovery" ))
		send_to_char ("This drug requires freshener, swampflower, biohazard.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "speed booster" ))
		send_to_char ("This drug requires viral, alterator, sterilizer.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "antidote" ))
		send_to_char ("This drug requires nightbloom, velvet, rockweed.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "antibiotica" ))
		send_to_char ("This drug requires snowroot, rockweed, nightbloom.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "sight restorer" ))
		send_to_char ("This drug requires sustainer, alteratr, viral.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "pain killer" ))
		send_to_char ("This drug requires viral, dustroot, freshener.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "combat sense" ))
		send_to_char ("This drug requires viral, biohazard, softener.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "physical power" ))
		send_to_char ("This drug requires sustainer, neutralizer, dustroot.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "staminator" ))
		send_to_char ("This drug requires mistrose, rockweed, swampflower.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "brain power" ))
		send_to_char ("This drug requires sterilizer, viral, densifier.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "total recovery" ))
		send_to_char ("This drug requires sustainer, alterator, nightbloom.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "sense enhancement" ))
		send_to_char ("This drug requires dustroot, dustroot, snowroot.\n\r", ch);
		return;
	if (obj->value[1] = skill_lookup( "reflex enhancement" ))
		send_to_char ("This drug requires densifier, sterilizer, sterilizer.\n\r", ch);
		return;

	send_to_char ("You cannot analyze that.\n\r", ch);

}
------------------------------------------------------------------------
This is an alpha version of the drug code, fully functional, but not 
what i want it to be. The full version of this code are intented to 
have player defined level of the drug and read the drugs from a data 
file to avoid altering the code all of the time.
If you find bugs, problems or a better way to do this, please do
contact me.

Dex.
