This snippet makes use of the existing mixedit feature of the Dawn of Time Codebase to create a cooking system for crafters. The cooking snippet makes use of the herbalism code. Recipes are built the same way with mixedit. You will need to create item types POT and PAN for players to cook their food in. They’ll also need a fire nearby. Compatible with version R of Dawn of Time.
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 ); } }