eldhamud/boards/
eldhamud/clans/
eldhamud/classes/
eldhamud/councils/
eldhamud/deity/
eldhamud/doc/
eldhamud/doc/DIKU/
eldhamud/doc/MERC/
eldhamud/doc/mudprogs/
eldhamud/houses/
eldhamud/src/o/CVS/
//
// C Implementation: crafting
//
// Description:
//
// Crafting.c will contain code related to the weapons and armor crafting system
// Some of the code below is copyright to various snippet authors and contains
// any headers or comments they have added. Any origional code below by Tommi
// may be used in whole or in part as long as any comment is left inplace and
// that you agree to make any changes,additions or improvements available
// to the public domain via a snippet posted on a public website.
//
// Author: tommi <powell123@yahoo.com>, (C) 2005
//
//
//
#include <sys/types.h>
#include <string.h>
#include "mud.h"
#include "crafting.h"


/*Tailor skill by Tamarae -(tamarae@zdnetonebox.com) written for The Kravothian Mysts
 *Tailoring is the act of sewing pieces of material together to create handmade clothing
 *which in turn can be dyed many different colors and worn.  Part of the Tailoring group
 *written by Tamarae
 *Tailor skill by Tamarae -(tamarae@zdnetonebox.com)
 *Syntax: tailor <material> <clothing type>
 *
 * Tailor skill ported over to smaug1.4a by Vladaar 12-22-01 
 *
 *Modified and changed how it works, SmaugFUSS1.4 by Tommi 2005*/

void do_tailor( CHAR_DATA *ch, char *argument )
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char buf[MAX_INPUT_LENGTH];
  char exdesc[20], ctype[20];
  OBJ_DATA *clothing, *material, *sewkit;
  int random_number;

  /* Do we have the skill? */
  if ( !IS_NPC(ch) && !(LEARNED(ch,gsn_tailor)))
    {
      send_to_char( "You better leave that to those who have been trained to tailor.\n\r", ch );
      return;
    }


  argument = one_argument( argument, arg1 );
  if ( arg1[0] == '\0' )
    {
      send_to_char( "Tailor using which material?\n\r", ch );
      send_to_char( "Syntax: tailor corpse <clothing>\n\r", ch);
      send_to_char( "Available clothing types:  cap, scarf, gloves, boots, belt, pants, tunic, cloak, bracer, vest, whip\n\r", ch);
      return;
    }

  argument = one_argument( argument, arg2 );
  if ( arg2[0] == '\0' )
    {
      send_to_char( "Syntax: tailor corpse <clothing>\n\r", ch);
      send_to_char( "Which type of clothing are you trying to tailor?\n\r", ch );
      send_to_char( "Available clothing types:  cap, scarf, gloves, boots, belt, pants, tunic, cloak, bracer, vest, whip\n\r", ch);
      return;
    }

  if ( ( material = get_obj_carry( ch, arg1 ) ) == NULL )
    {
      send_to_char( "You do not have any material to stitch.\n\r", ch );
      return;
    }

  if (material->pIndexData->vnum != OBJ_VNUM_CORPSE)
    {
      send_to_char("Sorry, you many only tailor the skins of corpses.\n\r", ch);
      return;
    }

  if ( ( sewkit = get_eq_char( ch, WEAR_HOLD ) ) == NULL || sewkit->pIndexData->vnum != OBJ_VNUM_SEWKIT )
    {
      send_to_char( "You need a sewing kit in order to tailor.\n\r", ch );
      return;
    }

  if ( number_percent() < LEARNED(ch, gsn_tailor)  ) /* create the clothing - success! */
    {
      if (!str_cmp(arg2,"cap"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_HEAD);
          strcpy(ctype, "cap" );
          clothing->weight = 10;
        }
      else if (!str_cmp(arg2,"scarf"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_NECK);
          strcpy(ctype, "scarf" );
          clothing->weight = 5;
        }

      else if (!str_cmp(arg2,"bracer"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_WRIST);
          strcpy(ctype, "bracer" );
          clothing->weight = 5;
        }
      else if (!str_cmp(arg2,"vest"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_ABOUT);
          strcpy(ctype, "vest" );
          clothing->weight = 5;
        }
      else if (!str_cmp(arg2,"tunic"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_BODY);
          strcpy(ctype, "tunic" );
          clothing->weight = 15;
        }
      else if (!str_cmp(arg2,"gloves"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_HANDS);
          strcpy(ctype, "pair of gloves" );
          clothing->weight = 5;
        }
      else if (!str_cmp(arg2,"boots"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_FEET);
          strcpy(ctype, "pair of boots" );
          clothing->weight = 10;
        }
      else if (!str_cmp(arg2,"pants"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_LEGS);
          strcpy(ctype, "pair of pants" );
          clothing->weight = 15;
        }
      else if (!str_cmp(arg2,"belt"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_WAIST);
          strcpy(ctype, "belt" );
          clothing->weight = 5;
        }
      else if (!str_cmp(arg2,"cloak"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_CLOTHING), 0);
          SET_BIT(clothing->wear_flags,ITEM_WEAR_ABOUT);
          strcpy(ctype, "cloak" );
          clothing->weight = 20;
        }
      else if (!str_cmp(arg2,"whip"))
        {
          clothing = create_object(get_obj_index(OBJ_VNUM_FORGE_WEAPON), 0);

          clothing->value[0] = 13; //set the condition to perfect
          if(ch->level < 10)	// sets the num dice
            clothing->value[1] = 4;
          else if(ch->level < 20)
            clothing->value[1] = 6;
          else if(ch->level < 30)
            clothing->value[1] = 8;
          else if(ch->level < 40)
            clothing->value[1] = 10;
          else if(ch->level < 50)
            clothing->value[1] = 12;
          else if(ch->level < 60)
            clothing->value[1] = 14;
          else if(ch->level < 70)
            clothing->value[1] = 16;
          else if(ch->level < 80)
            clothing->value[1] = 18;
          else if(ch->level < 90)
            clothing->value[1] = 20;
          else
            clothing->value[1] = 22;


          clothing->value[2] = ch->level* 2;  //sets the size dice
          if (clothing->value[2] <= 20)
            clothing->value[2] = 20;

          clothing->level = ch->level;
          clothing->cost = 100;
          clothing->value[0] = 13;
          clothing->value[3] = 4;
          clothing->weight = 10;

          sprintf( buf, "tailored leather whip" );
          STRFREE( clothing->name );
          clothing->name = STRALLOC (buf);
          sprintf( buf, "a handmade tailored leather whip");
          STRFREE( clothing->short_descr );
          clothing->short_descr = STRALLOC ( buf );
          sprintf( buf, "A handmade tailored leather whip by %s", ch->name);
          STRFREE( clothing->description );
          clothing->description = STRALLOC ( buf );
          obj_to_char( clothing, ch );
          extract_obj( material );
          send_to_char("You snip and sew, creating a new leather whip.\n\r", ch);
          act( AT_ACTION, "$n snips and sews creating a new leather whip.", ch, NULL, NULL, TO_ROOM );
          learn_from_success( ch, gsn_tailor );
          return;

        }
      else
        {
          send_to_char( "Available clothing types:  cap, scarf, gloves, boots, belt, pants, tunic, cloak\n\r", ch);
          return;
        }

      random_number = number_range(0, 9);
      switch( random_number )
        {
        case 0:
          strcpy(exdesc, "fringed" );
          break;
        case 1:
          strcpy(exdesc, "embroidered" );
          break;
        case 2:
          strcpy(exdesc, "lacy"    );
          break;
        case 3:
          strcpy(exdesc, "scalloped" );
          break;
        case 4:
          strcpy(exdesc, "reinforced" );
          break;
        case 5:
          strcpy(exdesc, "stitched" );
          break;
        case 6:
          strcpy(exdesc, "double-stitched" );
          break;
        case 7:
          strcpy(exdesc, "patched" );
          break;
        case 8:
          strcpy(exdesc, "tailored" );
          break;
        case 9:
          strcpy(exdesc, "woven" );
          break;
        }
      separate_obj( material );
      obj_from_char( material );
      clothing->level = ch->level;
      clothing->cost = ( ch->level ) * 75;


      clothing->value[0] = ch->level / 4 + 5;
      if (clothing->value[0] < 5)
        clothing->value[0] = 5;
      clothing->value[1] = clothing->value[0];
      clothing->value[3] = 13;
      SET_BIT(clothing->item_type,ITEM_ARMOR);
      SET_BIT(clothing->wear_flags,ITEM_TAKE);
      sprintf( buf, "%s %s", exdesc, ctype );
      STRFREE( clothing->name );
      clothing->name = STRALLOC (buf);
      sprintf( buf, "a handmade %s %s", exdesc, ctype );
      STRFREE( clothing->short_descr );
      clothing->short_descr = STRALLOC ( buf );
      sprintf( buf, "A handmade %s crafted by %s", ctype, ch->name);
      STRFREE( clothing->description );
      clothing->description = STRALLOC ( buf );
      obj_to_char( clothing, ch );
      extract_obj( material );
      send_to_char("You snip and sew, creating a new piece of clothing.\n\r", ch);
      act( AT_ACTION, "$n snips and sews creating a new piece of clothing.", ch, NULL, NULL, TO_ROOM );
      learn_from_success( ch, gsn_tailor );
      return;
    }

  else
    random_number = number_range(0, 100);
  if (random_number < 20) /*did the sewkit break?*/
    {

      act( AT_ACTION, "$n pulls too hard on the needle and it breaks!", ch, NULL, NULL, TO_ROOM);
      send_to_char( "You pull too hard on the needle and it breaks!\n\r", ch );
      extract_obj( sewkit );
      learn_from_failure( ch, gsn_tailor );
      return;
    }
  else if (random_number > 20 && random_number < 40) /*small chance to loose all your material*/
    {
      send_to_char( "Your thread knots, and your material is ruined.\n\r", ch);
      act( AT_ACTION, "$n gets a knot in the thread and ruins the material.", ch, NULL, NULL, TO_ROOM);
      extract_obj( material );
      learn_from_failure( ch, gsn_tailor );
      return;
    }

  else if (random_number > 40 && random_number < 60)
    {
      send_to_char("You snip and sew, but only make a mess.\n\r", ch);
      act( AT_ACTION, "$n snips and sews but doesn't make anything useful.", ch, NULL, NULL, TO_ROOM);
      learn_from_failure( ch, gsn_tailor );
      return;
    }

  else if (random_number >60 && random_number < 100)
    {
      send_to_char("A small tear appears in the fabric, destroying all your work.\n\r", ch);
      act( AT_ACTION, "$n tears the fabric, making a total mess.", ch, NULL, NULL, TO_ROOM);
      learn_from_failure( ch, gsn_tailor );
      return;
    }
}


void do_mining( CHAR_DATA *ch, char *argument )
{
  char arg [MAX_INPUT_LENGTH];
  OBJ_DATA *obj, *bonus;
  OBJ_INDEX_DATA *ore;
  int add_weight, vnum, random_number, mineIndex;
  int CHANCE = 100;


  if ( IS_NPC(ch) )
    {
      send_to_char( "Mobs cannot use this skill.\n\r", ch );
      return;
    }
  if ( IS_AFFECTED( ch, AFF_CHARM ) )
    {
      send_to_char( "You can't concentrate enough for that.\n\r", ch );
      return;
    }
  if ( ch->mount )
    {
      send_to_char( "You can't do that while mounted.\n\r", ch );
      return;
    }
  if( IS_PLR_FLAG( ch, PLR_ONMAP ) )
    {
      send_to_char( "You cannot mine out in the wilderness.\n\r", ch );
      return;
    }
/*  if(ch->in_room->sector_type == SECT_CITY)
    {
      send_to_char( "You will not find any ore inside a city.\n\r", ch );
      return;
    } */ 
  // commented out city sector untill all rooms are checked to make sure they are not city.  
  if ( ch->move < 20 )
    {
      send_to_char( "You do not have enough movement left to mine.\n\r", ch );
      return;
    }
  if (ch->carry_weight > can_carry_w(ch))
    {
      send_to_char("You look to be over loaded and cannot mine anymore",ch);
      return;
    }

  switch( ch->substate )
    {
    default:
      add_timer( ch, TIMER_DO_FUN, UMIN(skill_table[gsn_mine]->beats, 3), do_mining, 1);
      ch->alloc_ptr = str_dup( arg );
      send_to_char( "You begin mining...\n\r", ch );
      act( AT_PLAIN, "$n begins mining...", ch, NULL, NULL, TO_ROOM );
      return;

    case 1:
      if ( !ch->alloc_ptr )
        {
          send_to_char( "Your mining was interrupted!\n\r", ch );
          act( AT_PLAIN, "$n's mining was interrupted!", ch, NULL, NULL, TO_ROOM );
          bug( "do_mining: alloc_ptr NULL", 0 );
          return;
        }
      strcpy( arg, ch->alloc_ptr );
      DISPOSE( ch->alloc_ptr );
      break;

    case SUB_TIMER_DO_ABORT:
      DISPOSE( ch->alloc_ptr );
      ch->substate = SUB_NONE;
      send_to_char( "You stop mining...\n\r", ch );
      act( AT_PLAIN, "$n stops mining...", ch, NULL, NULL, TO_ROOM );
      return;
    }
  ch->substate = SUB_NONE;

  /* Gain less chance of dirt and rocks if using pick or miners helm*/
  if ( ( bonus = get_eq_char( ch, WEAR_HOLD ) ) != NULL )
    {
      if (bonus->pIndexData->vnum == OBJ_VNUM_QUEST_PICK)
        CHANCE -= 10;
    }
  if ( ( bonus = get_eq_char( ch, WEAR_HEAD ) ) != NULL )
    {
      if (bonus->pIndexData->vnum == OBJ_VNUM_QUEST_HELM)
        CHANCE -= 10;
    }

  for(mineIndex=0; mineIndex<42; mineIndex++)
    if(ch->in_room->vnum == ore_inroom_data[mineIndex].room_vnum)
      {
        break;
      }
  if(ch->in_room->vnum != ore_inroom_data[mineIndex].room_vnum)
    {
      send_to_char( "This room does not seem suitable to mine...\n\r", ch );
      return;
    }

  /* Roll to determine what ore you get*/
  random_number = number_range(0, CHANCE);
  if (random_number < 6)
    {
      vnum = ore_inroom_data[mineIndex].mine_ore_1;
    }
  else if (random_number < 16)
    {
      vnum = ore_inroom_data[mineIndex].mine_ore_2;
    }
  else if (random_number < 31)
    {
      vnum = ore_inroom_data[mineIndex].mine_ore_3;
    }
  else if (random_number < 56)
    {
      vnum = ore_inroom_data[mineIndex].mine_ore_4;
    }
  else if (random_number < 81)
    {
      vnum = ore_inroom_data[mineIndex].mine_ore_5;
    }
  else
    {
      vnum = OBJ_VNUM_ORE_DIRT;
    }
  add_weight = number_range(2, 5);
  ore = get_obj_index( vnum );
  if ( ore == NULL )
    {
      bug( "do_mining: Cannot locate item for vnum %d", vnum );
      send_to_char( "Oops. Slight bug here. The immortals have been notified.\n\r", ch );
      return;
    }
  if ( number_percent() < ch->pcdata->learned[gsn_mine] )
    {
      if ( ( obj = get_obj_vnum( ch, vnum ) ) != NULL ) //we have the object now we need to add the weight to it
        {
          obj->weight += add_weight;
          ch->carry_weight += add_weight;
          ch_printf( ch, "After some intense mining, you unearth %d pounds of %s!\n\r",add_weight, obj->short_descr );
        }
      if ( ( obj = get_obj_vnum( ch, vnum ) ) == NULL ) //we dont have the object better put one in the inventory
        {
          obj = create_object( ore, 1 );
          obj = obj_to_char( obj, ch );
          obj->weight = add_weight;
          ch->carry_weight += add_weight;
          ch_printf( ch, "After some intense mining, you unearth %d pounds of %s!\n\r",add_weight, obj->short_descr );
        }
      learn_from_success( ch, gsn_mine );
      ch->move -= 20; //take this much if your sucessfull
      if ( ch->move < 1 )
        ch->move = 0;
    }
  else
    {
      send_to_char("You fail to find anything usefull",ch);
      learn_from_success( ch, gsn_mine );
      ch->move -= 10; //take this much if your not sucessfull
      if ( ch->move < 1 )
        ch->move = 0;
    }
  return;
}


void do_restring( CHAR_DATA *ch, char *argument )
{

  CHAR_DATA *mob = NULL;
  char arg [MAX_INPUT_LENGTH];
  char arg1 [MAX_INPUT_LENGTH];
  char arg2 [MAX_INPUT_LENGTH];
  OBJ_DATA *obj = NULL;
  int value;

  smash_tilde( argument );
  argument = one_argument( argument, arg );
  argument = one_argument( argument, arg1 );
  strcpy( arg2, argument );

  if ( arg[0] == '\0' || arg1[0] == '\0' || arg2[0] == '\0' )
    {
      send_to_char("Syntax:\n\r",ch);
      send_to_char("  restring <Obj-Name> <Field> <String>\n\r",ch);
      send_to_char("    fields: name short long\n\r",ch);
      return;
    }

  if ( ( obj = get_obj_world( ch, arg ) ) == NULL )
    {
      send_to_char( "There is nothing like that in all the realms.\n\r", ch );
      return;
    }

  for ( mob = ch->in_room->first_person; mob; mob = ch->next_in_room )
    {
      if ( IS_NPC(mob) && xIS_SET(mob->act, ACT_RESTRING) )
        break;
    }

  if ( !mob  )
    {
      send_to_char( "You need to be at a restringer to do that.\n\r", ch );
      return;
    }

  if( ch->gold < 2000)
    {
      send_to_char( "&rYou do not have enough money to restring anything!\n\r", ch);
      return;
    }

  strcpy( arg, obj->name );
  separate_obj( obj );
  value = atoi( arg2 );
  if ( !str_cmp( arg1, "name" ) )
    {
      STRFREE( obj->name );
      obj->name = STRALLOC( arg2 );
      send_to_char( "Ok.\n\r", ch );
      ch->gold -= 2000;
      return;
    }

  if ( !str_cmp( arg1, "short" ) )
    {
      STRFREE( obj->short_descr );
      obj->short_descr = STRALLOC( arg2 );
      send_to_char( "Ok.\n\r", ch );
      ch->gold -= 2000;
      return;
    }

  if ( !str_cmp( arg1, "long" ) )
    {
      STRFREE( obj->description );
      obj->description = STRALLOC( arg2 );
      send_to_char( "Ok.\n\r", ch );
      ch->gold -= 2000;
      return;
    }
}

/* expansion ore types */



void applyAffectToObject(apply_data *theData, OBJ_DATA *theObject, CHAR_DATA *theChar)
{
  int applyAmmount = 0;
  AFFECT_DATA *affData = 0;

  if(!theData)
    return;

  if(theData->applyType == APPLY_NONE)
    return;

  if(!theObject)
    return;

  if(!theChar)
    return;

  if(theData->divisor)
    applyAmmount = (theChar->level / theData->divisor);

  applyAmmount+=theData->base + number_fuzzy(theData->noise);

  CREATE(affData, AFFECT_DATA, 1);
  affData->type = -1;
  affData->duration = -1;
  affData->location = theData->applyType;
  affData->modifier = applyAmmount;
  xCLEAR_BITS(affData->bitvector);
  LINK(affData, theObject->first_affect, theObject->last_affect, next, prev);
}



bool isForgePresent(CHAR_DATA *ch)
{
  CHAR_DATA *forge;

  bool found = FALSE;

  for ( forge = ch->in_room->first_person; forge; forge = forge->next_in_room )
    if ( IS_NPC(forge) && xIS_SET(forge->act, ACT_FORGE) )
      found = TRUE;
  return (found);
}

enum ore_types lookupOreIndexFromString(char* theString)
{
  enum ore_types oreIndex;
  enum ore_types result = -1;

  for(oreIndex=enFirstOre; oreIndex<=enLastOre; oreIndex++)
    if(!str_cmp(theString, ore_data[oreIndex].name))
      {
        result = oreIndex;
        break;
      }

  return (result);
}

enum armor_types lookupArmorIndexFromString(char* theString)
{
  enum armor_types armorIndex=0;
  enum armor_types result = -1;

  for (armorIndex=enFirstArmor; armorIndex<=enLastArmor; armorIndex++)
    if(!str_cmp(theString, armor_data[armorIndex].name))
      {
        result = armorIndex;
        break;
      }

  return (result);
}

enum weapon_types lookupWeaponIndexFromString(char* theString)
{
  enum weapon_types weaponIndex=0;
  enum weapon_types result = -1;

  for (weaponIndex=enFirstWeapon; weaponIndex<=enLastWeapon; weaponIndex++)
    if(!str_cmp(theString, weapon_data[weaponIndex].name))
      {
        result = weaponIndex;
        break;
      }

  return (result);
}

void listForgableTypes(CHAR_DATA *ch)
{
  enum armor_types armorIndex;
  enum weapon_types weaponIndex;
  char buf [30];


  send_to_char("It is possible to forge the following item types:\n\r", ch);

  send_to_char("Weapons:\n\r", ch);
  for (weaponIndex=enFirstWeapon; weaponIndex<=enLastWeapon; weaponIndex++)
    {
      sprintf(buf, "\t%s\n\r", weapon_data[weaponIndex].name);
      send_to_char(buf, ch);
    }
  send_to_char("Armors:\n\r", ch);
  for (armorIndex=enFirstArmor; armorIndex<=enLastArmor; armorIndex++)
    {
      sprintf(buf, "\t%s\n\r", armor_data[armorIndex].name);
      send_to_char(buf, ch);
    }
}

void do_forge(CHAR_DATA *ch, char *argument)
{
  OBJ_DATA *ore;
  OBJ_DATA *forged_item;
  OBJ_INDEX_DATA *pForgedItemIndex;
  //  CHAR_DATA *forge = NULL;

  char arg[MAX_INPUT_LENGTH];
  char arg1[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  char obj_name[20];

  enum armor_types armorIndex;
  enum ore_types oreIndex;
  enum weapon_types weaponIndex;
  enum forge_types forgingType;

  bool foundForgingType = FALSE;

  apply_data* theData;
  //  int applyAmmount;

  argument = one_argument( argument, arg );
  argument = one_argument2( argument, arg1 );

  if (!str_cmp(arg, "list"))
    {
      listForgableTypes(ch);
      return;
    }

  if ( arg[0] == '\0' || arg1[0] == '\0' )
    {
      send_to_char("Syntax: forge  <ore> <item_type>\n\r",ch);
      send_to_char("        forge list\n\r", ch);
      send_to_char("Example: forge mithril sword\n\r",ch);
      send_to_char("Also see help forge for more details.\n\r",ch);
      return;
    }

  if(!isForgePresent(ch))
    {
      send_to_char("You require a blacksmith in order to forge\n\r", ch);
      return;
    }



  //determine if ch has ore and assign values to object based on ore type
  if ( ( ore = get_obj_carry( ch, arg ) ) == NULL )
    {
      sprintf(buf, "Sorry, you do not have any '%s' ore.\n\r", arg);
      send_to_char(buf,ch);
      return;
    }
  if ( ore->item_type != ITEM_ORE )
    {
      send_to_char("That is not real ore, you need to go and mine the real thing!!!\n\r",ch);
      return;
    }

  /*  Figure out what type of ore we are dealing with */
  if(str_cmp(arg, ore->name))
    {
      send_to_char( "That is not proper ore.  Please go and mine somewhere and leave the poor blacksmith alone.\n\r", ch );
      return;
    }

  oreIndex=lookupOreIndexFromString(arg);

  if(oreIndex == -1)
    {
      send_to_char( "Error.  Please file a note on the bug bulletin with the command you typed\n\r", ch);
      return;
    }

  if(!foundForgingType)
    {
      armorIndex=lookupArmorIndexFromString(arg1);
      if(armorIndex != -1)
        {
          forgingType = enForgeArmor;
          foundForgingType=TRUE;
          sprintf(obj_name, "%s", armor_data[armorIndex].name);
        }
    }

  if(!foundForgingType)
    {
      weaponIndex=lookupWeaponIndexFromString(arg1);
      if(weaponIndex != -1)
        {
          forgingType = enForgeWeapon;
          foundForgingType=TRUE;
          sprintf(obj_name, "%s", weapon_data[weaponIndex].name);
        }
    }

  if(!foundForgingType)
    {
      send_to_char( "You don't know how to forge that!\n\r", ch);
      send_to_char( "Type \"forge list\" for a list of objects you may forge.\n\r", ch);
      return;
    }

  if(forgingType == enForgeArmor)
    {
      if (armor_data[armorIndex].weight > ore->weight)
        {
          send_to_char( "You do not have enought ore to make that object\n\r", ch);
          return;
        }
      ore->weight -= armor_data[armorIndex].weight;

      forged_item = create_object(get_obj_index(OBJ_VNUM_FORGE_ARMOR), 0);
      forged_item->cost = ( ch->level ) * armor_data[armorIndex].costMod * number_fuzzy(10);

      SET_BIT(forged_item->wear_flags, armor_data[armorIndex].wearLocation);
      forged_item->weight = armor_data[armorIndex].weight;
      forged_item->value[0] = ((ch->level/3) + ore_data[oreIndex].modifier + armor_data[armorIndex].acMod);
      //sets the armor
      forged_item->value[3] = 12; //set the condition to perfect

      send_to_char("You work and work the ore, turning it into a piece of armor.\n\r", ch);
      act( AT_ACTION, "$n works and work the ore, turning it into a piece of armor.", ch, NULL, NULL, TO_ROOM );
    }
  if(forgingType == enForgeWeapon)
    {
      if (weapon_data[weaponIndex].weight > ore->weight)
        {
          send_to_char( "You do not have enought ore to make that object\n\r", ch);
          return;
        }
      ore->weight -= weapon_data[weaponIndex].weight;

      pForgedItemIndex=get_obj_index(OBJ_VNUM_FORGE_WEAPON);

      if(!pForgedItemIndex)
        {
          send_to_char("Please bug a coder to fix OBJ_VNUM_FORGE_WEAPON.\n\r", ch);
          return;
        }

      forged_item = create_object(pForgedItemIndex, ch->level);

      forged_item->cost = ( ch->level ) * weapon_data[weaponIndex].costMod * number_fuzzy(10);

      forged_item->value[0] = 13; //set the condition to perfect

      /*  num dice */
      forged_item->value[1] = 6 + ((ch->level / 8 ) * 4);

      /*  size of dice */
      forged_item->value[2] = ((ch->level/9) + ore_data[oreIndex].modifier ) * ((ch->level/9) + weapon_data[weaponIndex].dmgMod );
      if (forged_item->value[2] <= ( 3 * ch->level / 2 + 6 ))
        forged_item->value[2] = ( 3 * ch->level / 2 + 16);

      forged_item->value[3] = weapon_data[weaponIndex].damageType;
      forged_item->value[4] = weapon_data[weaponIndex].weaponType;
      forged_item->weight = weapon_data[weaponIndex].weight;

      send_to_char("You work and work the ore, turning it into a new weapon.\n\r", ch);
      act( AT_ACTION, "$n works and work the ore, turning it into a new weapon.", ch, NULL, NULL, TO_ROOM );

    }

  if(ore->weight <=2)
    {
      separate_obj( ore );
      obj_from_char( ore );
    }

  forged_item->level = ch->level;


  /* right not lets set some effects on the eq based on differnt ore values */
  theData = &(ore_data[oreIndex].apply_1);

  applyAffectToObject(&(ore_data[oreIndex].apply_1), forged_item, ch);

  sprintf( buf, "%s %s", ore_data[oreIndex].name, obj_name );
  STRFREE( forged_item->name );
  forged_item->name = STRALLOC (buf);

  sprintf( buf, "A forged %s %s", ore_data[oreIndex].name, obj_name );
  STRFREE( forged_item->short_descr );
  forged_item->short_descr = STRALLOC (buf);

  sprintf( buf, "A %s %s forged by %s", ore_data[oreIndex].name, obj_name, ch->name );
  STRFREE( forged_item->description );
  forged_item->description = STRALLOC (buf);

  obj_to_char( forged_item, ch ); //finally you get the newly forged object

  learn_from_success(ch, gsn_forge);
  return;
}

#define OBJ_VNUM_SUITABLE_TREE 100
#define OBJ_VNUM_CHOPPED_TREE 101
/* coded aug 2005 tommi teaching losan  *//*
void do_lumberjack( CHAR_DATA *ch, char *argument )
{
  if ( IS_NPC (ch) )
    {
      send_to_char ( "Mobiles cannot use this command.\n\r", ch );
      return;
    }
  if ( ch->in_room->sector_type != SECT_FOREST)
    {
      send_to_char ( "You aren't in a forest.\n\r", ch);
      return;
    }
  if ( argument[0] == '\0')
    {
      send_to_char ( "Syntax: Lumberjack search/chop/process.\n\r", ch);
      WAIT_STATE ( ch , 3 );
      return;
    }
  if ( !str_cmp (argument , "search" ) )
    {
      send_to_char ( "You begin your search of the forest...\n\r", ch);
      WAIT_STATE ( ch , 15 );
      int searchresult = number_range ( 0 , 10 );
      searchresult;
      if ( searchresult == 10 )
        {
          send_to_char ( "You find a suitable tree!\n\r", ch);
          create_object ( get_obj_index ( OBJ_VNUM_SUITABLE_TREE ) , 1 );
          return;
        }
      else
        {
          send_to_char ( "Your search was in vain as you did not find a suitable tree.\n\r", ch);
          return;
        }
    }
  if ( !str_cmp (argument , "chop" ) )
    {
      if (ch->in_room->obj_vnum ( OBJ_VNUM_SUITABLE_TREE ) )
        {
          send_to_char ( "You begin to chop down the tree.\n\r", ch);
          WAIT_STATE ( ch , 10 );
          create_object ( get_object_index ( OBJ_VNUM_CHOPPED_TREE ) , 1 );
          
          send_to_char ( "You successfully chop down the tree.\n\r", ch);
          return;
        }
      else
        {
          send_to_char ( "There isn't a suitable tree here.\n\r", ch);
          return;
        }
    }
  if ( !str_cmp (argument , "process" ) )
    {
      if (ch->in_room->obj_vnum ( OBJ_VNUM_CHOPPED_TREE ) )
        {
          send_to_char ( "You begin processing the chopped tree.\n\r", ch);
          WAIT_STATE ( ch , 10 );
          int logs = number_range ( 1 , 5 )
                     create_object ( get_object_index ( OBJ_VNUM_LOGS ) , logs );
          
          send_to_char ( "You have processed " logs " logs. They await on the ground.\n\r", ch);
          return;
        }
      else
        {
          send_to_char ( "There isn't a chopped tree here.\n\r", ch);
          return;
        }
    }
}

*/

/* fishing aug 2005 intalled by tommi code by qidixan
void do_fish( CHAR_DATA *ch, char *argument )
{
  OBJ_DATA *obj_pole;

  if( IS_NPC( ch ) && IS_AFFECTED( ch, AFF_CHARM ) )
    {
      send_to_char( "You can't do that right now.\n\r", ch );
      return;
    }

  if( !IS_NPC( ch ) && ch->level < skill_table[gsn_fish]->skill_level[ch->class] )
    {
      send_to_char( "You don't know how to fish.\n\r", ch );
      return;
    }

  if( ch->fighting )
    {
      send_to_char( "Wait until you are finished fighting.\n\r", ch );
      return;
    }

  if( ( obj_pole = get_eq_char( ch, WEAR_HOLD ) ) == NULL
      || obj_pole->item_type != ITEM_FISHING_POLE )
    {
      send_to_char( "You need a pole for that!\n\r", ch );
      return;
    }

  if( obj_pole->value[0] < 1 ) //check for baited - item value set
    {
      send_to_char( "You need to bait your pole first.\n\r", ch );
      return;
    }

  if( !ch->in_room )
    {
      send_to_char( "You are floating in space.\n\r", ch );
      return;
    }

  switch( ch->in_room->sector_type )
    {
      //Valid cases - in water but not underwater.
    case SECT_WATER_SWIM:
    case SECT_WATER_NOSWIM:
      //boat/flight check...
      if( !IS_AFFECTED( ch, AFF_FLYING ) && !IS_AFFECTED( ch, AFF_FLOATING) )
        {
          OBJ_DATA *obj;

          for( obj = ch->first_carrying; obj; obj = obj->next_content )
            if( obj->item_type == ITEM_BOAT )
              break;

          if( !obj )
            {
              send_to_char( "You can't fish while you are surrounded by water.\n\r", ch );
              return;
            }
        }
      break;

      //Invalid cases
    case SECT_UNDERWATER:
    case SECT_OCEANFLOOR:
      send_to_char( "You cannot fish while underwater!\n\r", ch );
      return;
    default:
      send_to_char( "You need to be near water for that!\n\r", ch );
      return;
    }

  //Ok, everything is in order - fishing . . .
  if( number_percent() < LEARNED( ch, gsn_fish ) )
    {
      //success

      int caught = number_percent() + obj_pole->value[1];
      int skill = 2 * number_percent() + LEARNED( ch, gsn_fish );
      OBJ_DATA *fish_caught;

      obj_pole->value[0] = 0; //remove bait
      obj_pole->value[1] = 0; //remove bait_type
      act( AT_MAGIC, "$n has a successful time fishing.", ch, NULL, NULL, TO_ROOM );
      if( caught < 51 ) //50%
        {
          //load common
          fish_caught = create_object( get_obj_index( OBJ_VNUM_CRESS_FISH ), 0 );

          //Determine how many are caught.
          skill /= 45;
          skill = (skill>0?skill:1);
          fish_caught->count = skill;
          fish_caught->pIndexData->count += (skill - 1);
          numobjsloaded += (skill - 1);

          act( AT_MAGIC, "You catch some cress fish.", ch, NULL, NULL, TO_CHAR );
        }
      else if( caught < 76 ) //25%
        {
          //load less common
          fish_caught = create_object( get_obj_index(OBJ_VNUM_SPUTTER_FISH), 0 );

          //Determine how many are caught.
          skill /= 55;
          skill = (skill>0?skill:1);
          fish_caught->count = skill;
          fish_caught->pIndexData->count += (skill - 1);
          numobjsloaded += (skill - 1);

          act( AT_MAGIC, "You catch some sputter fish.", ch, NULL, NULL, TO_CHAR );
        }
      else if( caught < 91 ) //15%
        {
          //load uncommon
          fish_caught = create_object( get_obj_index( OBJ_VNUM_DARG_FISH ), 0 );

          //Determine how many are caught.
          skill /= 65;
          skill = (skill>0?skill:1);
          fish_caught->count = skill;
          fish_caught->pIndexData->count += (skill - 1);
          numobjsloaded += (skill - 1);

          act( AT_MAGIC, "You catch some darg fish.", ch, NULL, NULL, TO_CHAR );
        }
      else if( caught < 98 ) //7%
        {
          //load rare
          fish_caught = create_object( get_obj_index( OBJ_VNUM_EMERALD_FISH ), 0 );

          //Determine how many are caught.
          skill /= 75;
          skill = (skill>0?skill:1);
          fish_caught->count = skill;
          fish_caught->pIndexData->count += (skill - 1);
          numobjsloaded += (skill - 1);

          act( AT_MAGIC, "You catch some emerald fish.", ch, NULL, NULL, TO_CHAR );
        }
      else //3%
        {
          //load ultra rare
          fish_caught = create_object( get_obj_index( OBJ_VNUM_ELL_FISH ), 0 );

          //Determine how many are caught.
          skill /= 85;
          skill = (skill>0?skill:1);
          fish_caught->count = skill;
          fish_caught->pIndexData->count += (skill - 1);
          numobjsloaded += (skill - 1);

          act( AT_MAGIC, "You catch some ellusive ell fish.", ch, NULL, NULL, TO_CHAR );
        }

      //Don't let us crash if the fish don't exist.
      if( !fish_caught )
        {
          log_string( "     Error: Fish not created.\n\r" );
          send_to_char( "A divine mistake robs you of your catch.\n\r", ch );
        }
      else
        obj_to_char( fish_caught, ch );
      learn_from_success( ch, gsn_fish );
    }
  else
    {
      //fail
      obj_pole->value[0] = 0; //remove bait
      obj_pole->value[1] = 0; //remove bait_type
      act( AT_MAGIC, "$n attempts to catch a fish but winds up with an empty hook.", ch, NULL, NULL, TO_ROOM );
      act( AT_MAGIC, "You fail to catch anything.", ch, NULL, NULL, TO_CHAR );
      learn_from_failure( ch, gsn_fish );
    }

}


void do_bait( CHAR_DATA * ch, char *argument )
{
  char arg[MAX_INPUT_LENGTH];
  OBJ_DATA *obj_pole;
  OBJ_DATA *bait;

  argument = one_argument( argument, arg );

  if( ms_find_obj( ch ) )
    return;

  if( arg[0] == '\0' )
    {
      if( ( bait = get_objtype_carry( ch, ITEM_BAIT ) ) == NULL )
        {
          send_to_char( "You are not carrying any bait.\n\r", ch );
          return;
        }
    }
  else
    {
      if( ( bait = get_obj_objtype_carry( ch, arg, ITEM_BAIT ) ) == NULL )
        {
          send_to_char( "You are not carrying that bait.\n\r", ch );
          return;
        }
    }

  if( ( obj_pole = get_eq_char( ch, WEAR_HOLD ) ) == NULL
      || obj_pole->item_type != ITEM_FISHING_POLE )
    {
      send_to_char( "You need to be holding your fishing pole if you want to bait it.\n\r", ch );
      return;
    }

  if( obj_pole->value[0] > 0 )
    {
      send_to_char( "You already baited your hook.\n\r", ch );
      return;
    }

  obj_pole->value[0] = 1;

  switch( bait->pIndexData->vnum )
    {
    case OBJ_VNUM_ROSE_MAGGOT:
      obj_pole->value[1] = 2;
      break;
    case OBJ_VNUM_BOG_WORM:
    default:
      obj_pole->value[1] = 0;
      break;
    }

  act( AT_MAGIC, "$n places bait on $s fishing pole.", ch, NULL, NULL, TO_ROOM );
  act( AT_MAGIC, "You place bait on your fishing pole.", ch, NULL, NULL, TO_CHAR );

  separate_obj( bait );
  if( bait->serial == cur_obj )
    global_objcode = rOBJ_USED;
  extract_obj( bait );
  return;
} */