shadow/
shadow/data/command/
shadow/data/help/
shadow/data/religion/
shadow/data/skill/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

/***************************************************************************
*       ROM 2.4 is copyright 1993-1998 Russ Taylor                         *
*       ROM has been brought to you by the ROM consortium                  *
*           Russ Taylor (rtaylor@hypercube.org)                            *
*           Gabrielle Taylor (gtaylor@hypercube.org)                       *
*           Brian Moore (zump@rom.org)                                     *
*       By using this code, you have agreed to follow the terms of the     *
*       ROM license, in the file Rom24/doc/rom.license                     *
***************************************************************************/   

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "magic.h"
#include "tables.h"
#include "lookup.h"
#include "olc.h"
#include "const.h"

#define MAX_ARMOR_SUFFIX 25
#define MAX_WEAPON_SUFFIX 15
#define MAX_PREFIX 18

CHAR_DATA *random_mob args( (void) );
void format_obj args( (OBJ_DATA *obj) );
void format_obj_weapon args( (OBJ_DATA *obj) );
void format_obj_armor args( (OBJ_DATA *obj) );
int wear_bit args( (int loc) );
void name_obj args( (CHAR_DATA *mob,OBJ_DATA *obj) );
char *weapon_type_name args( (OBJ_DATA *obj) );
char *armor_type_name args( (OBJ_DATA *obj) );
int which_location args( (void) );
void apply_good_affect args( (OBJ_DATA *obj,bool positive) );

DECLARE_DO_FUN(do_wear );

struct unique_attrib_table unique_table_armor_suffix[MAX_ARMOR_SUFFIX]    =
{
  { "" },
  { "taste"           },
  { "protection"      },
  { "value"           },
  { "power"           },
  { "dark power"      },
  { "holiness"        },
  { "desecration"     },
  { "hope"            },
  { "hopelessness"    },
  { "care"            },
  { "invunlerability" },
  { "Ferric"          },
  { "Dagda"           },
  { "Chele"           },
  { "Khain"           },
  { "Keogh"           },
  { "Svartalfar"      },
  { "Makaruda"        },
  { "Moirai"          },
  { "Diku"            },
  { "the fallen"      },
  { "the gods"        },
  { "the Shrike"      },
  { "mystery"         },
};

struct unique_attrib_table unique_table_weapon_suffix[MAX_WEAPON_SUFFIX]    =
{
  { "" },
  { "destruction"       },
  { "sharpness"         },
  { "power"             },
  { "maiming"           },
  { "killing"           },
  { "slaying"           },
  { "havok"             },
  { "crushing"          },
  { "cutting"           },
  { "fear"              },
  { "pillage"           },
  { "slashing"},
  { "annoyance"         },
  { "striking"          },
};

struct unique_attrib_table unique_table_prefix[MAX_PREFIX]      =
{
  { "" },
  { "flashing"       },
  { "dull"           },
  { "well crafted"   },
  { "finely crafted" },
  { "shiny"          },
  { "fine"           },
  { "fantastic"      },
  { "scuffed"        },
  { "brilliant"      },
  { "hewn"           },
  { "scratched"      },
  { "dark"           },
  { "intense"        },
  { "battered"       },
  { "polished"       },
  { "faded"          },
  { "enigmatic"      },
};


void create_unique(void)
{
  int x;
  int i;
  OBJ_DATA *obj;
  char buf[MSL];
  CHAR_DATA *mob;

  if ( (obj = create_object( get_obj_index( OBJ_UNIQUE_DUMMY), 0) ) == NULL)
  {
      log_string( "Bug with OBJ_UNIQUE_DUMMY");
      return;
  }

  free_string(obj->short_descr);
  free_string(obj->description);

  mob = random_mob();

  if ( IS_SET( mob->in_room->area->area_flags , NO_UNIQUE ) )
      return;

  SET_BIT(obj->wear_flags,ITEM_TAKE);
  
  obj->level = mob->level;

  format_obj(obj);

  name_obj(mob,obj);

  SET_BIT( obj->extra2_flags, ITEM_UNIQUE );
  SET_BIT( obj->extra2_flags, ITEM_RELIC );

  obj->xp_tolevel = MIN_XP;

  i = ( (mob->level-10)/10);
  
  if(i ==0)
     i++;

  for(x = 0; x < i; x++)
     apply_good_affect(obj,TRUE);

  if(mob->level > 20)
  {
      i = (mob->level - 20) / 10;
  
      if(i == 0)
 	 i++;
  
      for(x = 0; x < i; x++)
 	 apply_good_affect(obj,FALSE);
  }

  obj_to_char(obj,mob);
  do_wear(mob,obj->name);
  
  sprintf(buf,"The unique object, %s, loaded to %s in room %d\n\r",
	  obj->short_descr,mob->name,mob->in_room->vnum);
  log_string( buf );
  
}

void do_tally(CHAR_DATA *ch, char *argument)
{
  OBJ_DATA *obj;
  int tally = 0;
  bool show = FALSE;
 
  if (!str_cmp(argument, "shadow" ) )
      show = TRUE;

  for(obj = object_list; obj != NULL; obj = obj->next )
  {
      CHAR_DATA *vch;

      if( (vch = obj->carried_by) == NULL)
	continue;

      if(!IS_NPC(vch))
	continue;

      if(IS_SET(obj->extra2_flags,ITEM_UNIQUE) )
      {	 
         tally++; 
                 
         if(show)
         printf_to_char(ch, "{D%d{r){W %s {r({DOn{r:{W %d{r)[{DIn{r:{W %d{r]{x\n\r", tally, obj->name, obj->carried_by && obj->carried_by->pIndexData ? obj->carried_by->pIndexData->vnum : 0, obj->carried_by ? obj->carried_by->in_room->vnum : 0 );
                   
      }
  }
     
  printf_to_char( ch, "{CTheir are currently %d unique items in the wilderness.{x\n\r", tally );
  return;
}


int which_location()
{
   int i;
   int location = 0;

   i = number_range(1,11);
   
   switch(i)
   {
     case 1:
       location = APPLY_STR;
       break;
     case 2:
       location = APPLY_DEX;
       break;
     case 3:
       location = APPLY_INT;
       break;
     case 4:
       location = APPLY_WIS;
       break;
     case 5:
       location = APPLY_CON;
       break;
     case 6:
       location = APPLY_MANA;
       break;
     case 7:
       location = APPLY_HIT;
       break;
     case 8:
       location = APPLY_MOVE;
       break;
     case 9:
       location = APPLY_HITROLL;
       break;
     case 10:
       location = APPLY_DAMROLL;
       break;
     case 11:
       location = APPLY_SAVES;
       break;
   }

   return location;

}

/*Lets apply some nice affects.*/
void apply_good_affect(OBJ_DATA *obj,bool positive)
{
  int location;
  AFFECT_DATA *af;
  int mult;
  int value;
  int max,min;

  location = which_location();
  
  switch(location)
  {
    default:
      mult = 10;
      break;
    case(APPLY_HIT):
      mult = 20;
      break;
    case(APPLY_MOVE):
      mult = 20;
      break;
    case(APPLY_MANA):
      mult = 20;
      break;
  }

  value = (1+(obj->level/10)) * mult;
  max = value*2;
  min = value/2;

  if(min == 0)
    min++;

  /*apply a negative affect*/
  if(!positive)
    {
      value = value*-1;
      max = value/2;
      min = value*2;
    }

  af = new_affect();               
  af->location = location;
  af->modifier = number_range(min,max);
  af->where = 0;
  af->type = -1;
  af->duration = -1;
  af->bitvector = 0;
  af->level = obj->level;
  af->next = obj->affected;
  obj->affected = af;


}

/*the fido's armor of taste*/
void name_obj(CHAR_DATA *mob,OBJ_DATA *obj)
{
  char buf[MSL];
  char buf2[MSL];
  char buf3[MSL];
  int i = number_range(1,MAX_PREFIX-1);
  int x = number_range(1,MAX_WEAPON_SUFFIX-1);
  int y = number_range(1,MAX_ARMOR_SUFFIX-1);


  sprintf(buf,"the %s %s of %s",
	  unique_table_prefix[i].descriptive,
	  obj->item_type == ITEM_WEAPON ? weapon_type_name(obj) :
	  armor_type_name(obj),
	  obj->item_type == ITEM_WEAPON ?
	  unique_table_weapon_suffix[x].descriptive :
	  unique_table_armor_suffix[y].descriptive);
	  
  sprintf(buf2,"%s is laying here on the ground.",buf);

  sprintf(buf3,"%s",buf);

  free_string(obj->name);
  free_string(obj->short_descr);
  free_string(obj->description);
  obj->name = str_dup(buf3);
  obj->short_descr = str_dup(buf);
  obj->description = str_dup(buf2);

}

void format_obj_weapon(OBJ_DATA *obj)
{
  int i;
  int size,dice;
  double avg;

  /*What type of weapon?*/
  i = number_range(0,8);
  obj->value[0] = i;
  
  /*Set it to wield*/
  SET_BIT(obj->wear_flags,ITEM_WIELD);
  
  avg = obj->level;
  dice = (obj->level/10+1);
  size = dice/2;

  for (size=dice/2 ; dice * (size +2)/2 < avg ; size++ )
    { }  

  dice = UMAX(1, dice);
  size = UMAX(2, size);
  
  obj->value[1] = dice;
  obj->value[2] = size;
  /*End autodamage routine.*/

}

char *weapon_type_name(OBJ_DATA *obj)
{
    char *buf;
    buf = '\0';
    
    switch(obj->value[0])
    {
    case(WEAPON_EXOTIC) : buf = str_dup("exotic weapon"); break;
    case(WEAPON_SWORD): buf = str_dup("sword"); break;
    case(WEAPON_DAGGER): buf = str_dup("dagger"); break;
    case(WEAPON_SPEAR): buf = str_dup("spear"); break;
    case(WEAPON_MACE): buf = str_dup("mace"); break;
    case(WEAPON_AXE): buf = str_dup("axe"); break;
    case(WEAPON_FLAIL): buf = str_dup("flail"); break;
    case(WEAPON_WHIP): buf = str_dup("whip"); break;
    case(WEAPON_POLEARM): buf = str_dup("polearm"); break;
    }
 
    return buf; 
}

char *armor_type_name(OBJ_DATA *obj)
{
  int i;

  char *buf;
  buf = '\0';

  switch(obj->wear_loc)
    {
    case 0:
      buf = str_dup("light");
      break;
    case 1:
    case 2:
      buf = str_dup("ring");
      break;
    case 3:
    case 4:
      i = number_range(1,3);
      if(i == 1)
	buf = str_dup("necklace");
      else if(i == 2)
	buf = str_dup("pendant");
      else
	buf = str_dup("neck guard");
      break;
    case 5:
      i = number_range(1,3);
      if(i == 1)
	buf = str_dup("armor");
      else if(i == 2)
	buf = str_dup("breastplate");
      else
	buf = str_dup("chain mail");
      break;
    case 6:
      i = number_range(1,3);
      if(i == 1)
	buf = str_dup("skullcap");
      else if(i == 2)
	buf = str_dup("helmet");
      else
	buf = str_dup("helm");
      break;
    case 7:
      i = number_range(1,3);
      if(i == 1)
	buf = str_dup("leggings");
      else if(i == 2)
	buf = str_dup("leg plates");
      else
	buf = str_dup("pants");
      break;
    case 8:
      i = number_range(1,3);
      if(i == 1)
	buf = str_dup("sandals");
      else if(i == 2)
	buf = str_dup("boots");
      else
	buf = str_dup("clogs");
      break;
    case 9: 
      i = number_range(1,3);
      if(i == 1)
	buf = str_dup("gloves");
      else if(i == 2)
	buf = str_dup("gauntlets");
      else
	buf = str_dup("sap gloves");
      break;
    case 10:
      buf = str_dup("arm plates");
      break;
    case 11:
      buf = str_dup("shield");
      break;
    case 12:
      i = number_range(1,3);
      if(i == 1)
	buf = str_dup("cloak");
      else if(i == 2)
	buf = str_dup("cape");
      else
	buf = str_dup("coat");
      break;
    case 13:
      i = number_range(1,3);
      if( i == 1)
	buf = str_dup("belt");
      else if(i == 2)
	buf = str_dup("girdle");
      else
	buf = str_dup("chain");
      break;
    case 14:
    case 15:
      i = number_range(1,3);
      if( i == 1)
	buf = str_dup("bracelet");
      else if(i == 2)
	buf = str_dup("wrist band");
      else
	buf = str_dup("band");
      break;
    }
  
  return buf;    
}

void format_obj_armor(OBJ_DATA *obj)
{
  /*Objects of ARMOR type can be ring, boots, shield, etc. Lets assign
    a random wear location to decide what this will be.*/

  obj->wear_loc = number_range(0,15);
  
  /*Ok, we have a type now. Lets go through and set a wear bit.*/
  switch(obj->wear_loc)
    {
    case 0:
      obj->item_type = ITEM_LIGHT;
      break;
    case 1:
    case 2:
      SET_BIT(obj->wear_flags,ITEM_WEAR_FINGER);
      break;
    case 3:
    case 4:
      SET_BIT(obj->wear_flags,ITEM_WEAR_NECK);
      break;
    case 5:
      SET_BIT(obj->wear_flags,ITEM_WEAR_BODY);
      break;
    case 6:
      SET_BIT(obj->wear_flags,ITEM_WEAR_HEAD);
      break;
    case 7:
      SET_BIT(obj->wear_flags,ITEM_WEAR_LEGS);
      break;
    case 8:
      SET_BIT(obj->wear_flags,ITEM_WEAR_FEET);
      break;
    case 9:
      SET_BIT(obj->wear_flags,ITEM_WEAR_HANDS);
      break;
    case 10:
      SET_BIT(obj->wear_flags,ITEM_WEAR_ARMS);
      break;
    case 11:
      SET_BIT(obj->wear_flags,ITEM_WEAR_SHIELD);
      break;
    case 12:
      SET_BIT(obj->wear_flags,ITEM_WEAR_ABOUT);
      break;
    case 13:
      SET_BIT(obj->wear_flags,ITEM_WEAR_WAIST);
      break;
    case 14:
    case 15:
      SET_BIT(obj->wear_flags,ITEM_WEAR_WRIST);
      break;
    }				       

  /*Ok, we've determined what type of armor it is, set appropriate wear.*/

  /*Now, lets set it's armor values*/
  obj->value[0] = number_range( (obj->level/2)-1 , (obj->level/2)+2);
  obj->value[1] = number_range( (obj->level/2)-1 , (obj->level/2)+2);
  obj->value[2] = number_range( (obj->level/2)-1 , (obj->level/2)+2);
  obj->value[3] = number_range( (obj->level/2)-1 , (obj->level/2)+2);
}

void format_obj(OBJ_DATA *obj)
{
   int i;
  
   /* Weapon, Armor? */

   i = number_range(0,1);

   switch(i)
   {
      case 0:
       obj->item_type = ITEM_WEAPON;
       format_obj_weapon(obj);
       break;
      case 1:
       obj->item_type = ITEM_ARMOR;
       format_obj_armor(obj);
       break;
   } 
} 

CHAR_DATA *random_mob()
{
  CHAR_DATA *mob;
  CHAR_DATA *vch;
  CHAR_DATA *vch_next;
  char buf[MSL];
  int i,x;

  mob = NULL;

  i = (number_range(1,top_mob_index));
  x = 0;

  for(vch = char_list; vch != NULL; vch = vch_next)
  {
      vch_next = vch->next;

      if(!IS_NPC(vch)
         || (vch->pIndexData == NULL
         || vch->name == NULL
         || vch->short_descr == NULL
         || vch->in_room == NULL )
         || vch->pIndexData->vnum < 100
         || vch->in_room->clan > 0
         || IS_SET( vch->act, ACT_TRAIN | ACT_PRACTICE | ACT_IS_HEALER
            | ACT_PET | ACT_GAIN | ACT_BOUNTY | ACT_MOUNT | ACT_FORGER
            | ACT_IS_CHANGER )
         || IS_SET( vch->imm_flags, IMM_WEAPON | IMM_MAGIC )
         || IS_SET( vch->affected_by, AFF_CHARM )
         || IS_SET( vch->in_room->room_flags, ROOM_PET_SHOP) )
        continue;

      x++;

      if ( i == 0 || x == 0 || vch == NULL )
      {
          sprintf(buf,"RANDOM_MOB: Null mob, i is 0, or x is 0. I: %d, X: %d, Vch: %s", i, x, vch->name );
          log_string(buf);
      }

      if(x == i)
        mob = vch;
      if(x >= top_mob_index)
        break;
  }

  return mob;
}