/* This is my version of weapons and armor advancing level. It makes it so that when you
 * mobs your weapons, and armor will gain levels and will be given stats each time they
 * level up. I really don't like math, so i'm sure the values could be changed around, or
 * be more randomized. If you do something like this please send me a copy of the changes 
 * so i can post them, and benefit from them as well. 
 * (email removed) Comment on MudBytes. If you have any comments for me feel free to email me as well. 
 * Anyway here is the code!
 */

Changes for update.c
********************

Below:
void	char_update	args( ( void ) );

Add:
void    gain_object_exp args( ( CHAR_DATA *ch, OBJ_DATA *obj, int gain ) );
void    advance_level_object args( ( CHAR_DATA *ch, OBJ_DATA *obj ) );


void gain_object_exp( CHAR_DATA *ch, OBJ_DATA *obj, int gain )
{
	int leftover = 0;

    if ( IS_NPC(ch) || obj->plevel >= MOBJLEVEL || IS_WEREWOLF(ch) )
		return;

    printf_to_char( ch, "%s has gained %d exp.\n\r", capitalize( obj->short_descr ), gain );     
    obj->exp += gain;
    obj->xp_tolevel -= gain;

	if(obj->xp_tolevel <= 0 )
	{	obj->exp += obj->xp_tolevel;
		advance_level_object(ch,obj);
		leftover = ( obj->xp_tolevel * 1 );
		obj->plevel++;
		printf_to_char( ch, "%s has raised to level %d. To see your objects stats lore or identify it.\n\r", capitalize( obj->short_descr ), obj->plevel );
		obj->xp_tolevel = 1500 + ( obj->plevel * 150 );
		obj->xp_tolevel -= leftover;
		return;
	}
	return;
}

void advance_level_object( CHAR_DATA *ch, OBJ_DATA *obj )
{
    int pbonus = number_range( 5, 10 );
    int bonus = number_range( 4, 8 );

    pbonus  = pbonus * 9/10;
    bonus =   bonus * 8/10;

    pbonus  = UMAX(  6, pbonus );
    bonus = UMAX( 1, bonus );

    add_apply(obj, APPLY_DAMROLL, pbonus, TO_OBJECT, 0, -1, 0, obj->plevel * 5);
    add_apply(obj, APPLY_HITROLL, pbonus, TO_OBJECT, 0, -1, 0, obj->plevel * 5); 
    add_apply(obj, APPLY_HIT, pbonus, TO_OBJECT, 0, -1, 0, obj->plevel * 5);
    add_apply(obj, APPLY_MANA, pbonus, TO_OBJECT, 0, -1, 0, obj->plevel * 5);
    add_apply(obj, APPLY_MOVE, pbonus, TO_OBJECT, 0, -1, 0, obj->plevel * 5);

    if (obj->item_type == ITEM_WEAPON)
    {
        obj->value[1] += bonus/4;
        obj->value[2] += bonus/5;
    } 

    else if (obj->item_type == ITEM_ARMOR)
    {
        obj->value[0] -= UMAX(1, obj->plevel);
        obj->value[1] -= UMAX(1, obj->plevel);
        obj->value[2] -= UMAX(1, obj->plevel);
        obj->value[3] -= (5 * UMAX(1, obj->plevel)) / 10;
    }
   
    return;
}   


Changes for handler.c
*********************

At the end of the file add this:

void add_apply(OBJ_DATA * obj, int loc, int mod, int where, int type, int dur,int vector, int level)
{
    AFFECT_DATA pAf;

    if (obj == NULL)
	return;

    if (!obj->enchanted)
	affect_enchant(obj);

    pAf.location = loc;
    pAf.modifier = mod;
    pAf.where = where;
    pAf.type = type;
    pAf.duration = dur;
    pAf.bitvector = vector;
    pAf.level = level;
    affect_join_obj(obj, &pAf);

    return;
}

Changes for merc.h
******************

Below:
void    gain_exp        args( ( CHAR_DATA *ch, int gain ) );          

Add:
void    gain_object_exp args( ( CHAR_DATA *ch, OBJ_DATA *obj, int gain ) );    


In struct obj_index_data:

Below:
    sh_int              size;

Add:
    sh_int              plevel;
    int                 xp_tolevel;
    int                 exp;  


In struct obj_data:

Below:
    sh_int              level; 

Add:
    int                 exp;
    sh_int              plevel;
    int                 xp_tolevel;    
   

At the end of the file add this:

void    add_apply args((OBJ_DATA * obj, int loc, int mod, int where, int type, int dur, int vector, int level));    


Add this to your item defines with a free bitvector:

#define ITEM_RELIC              (XXX)


Changes for act_wiz.c
*********************

void do_mrelic (CHAR_DATA *ch, char *argument)
{
    OBJ_DATA *obj;
    int i = 1500;

    if ( argument[0] == '\0' )
    {
        send_to_char( "Make a relic item of what?\n\r", ch );
        return;
    }

    if ( ( obj = get_obj_carry( ch, argument, ch ) ) == NULL )
    {
        send_to_char( "You do not have that item.\n\r", ch );
        return;
    }                                  

    if (IS_OBJ2_STAT(obj,ITEM_RELIC))
    {
        REMOVE_BIT(obj->extra_flags,ITEM_RELIC);
        act("$p is no longer a relic item.",ch,obj,NULL,TO_CHAR);
    }

    else
    {
        SET_BIT(obj->extra_flags,ITEM_RELIC);
        if ( obj->xp_tolevel <= 0 )
        obj->xp_tolevel = i;
        act("$p is now a relic item.",ch,obj,NULL,TO_CHAR);
    }

    return;
}           

in do_ostat add this somewhere with the other values:

  
 	if ( IS_OBJ_STAT(obj, ITEM_RELIC))
        {	   
             printf_to_char(ch, "Exp TNL: %d\n\r", obj->xp_tolevel );
	     printf_to_char(ch, "Exp: %d\n\r", obj->exp );
	}

Changes for db.c
****************

In OBJ_DATA * create_object

Below:

obj->condition      = pObjIndex->condition;  

Add:

   if(IS_OBJ_STAT(obj, ITEM_RELIC) )
      obj->xp_tolevel = 1500;         


Changes for save.c
******************

in void fwrite_obj

Below:
    fprintf( fp, "Wear %d\n",   obj->wear_loc                );

Add:

    if ( obj->plevel > 0 )
        fprintf( fp, "Plev %d\n", obj->plevel );
    if ( obj->exp > 0 )
        fprintf( fp, "Exp %d\n", obj->exp );
    if ( obj->xp_tolevel > 0 )
        fprintf( fp, "Xptolevel %d\n", obj->xp_tolevel );   


in fread_obj

make a case 'P' like this:

   case 'P':
            KEY("Plevel",       obj->plevel,            fread_number( fp ) );
            break;     

In case 'E':

Above:
            KEY( "ExtraFlags",  obj->extra_flags,       fread_number( fp ) );  

Add:
     KEY( "Exp",         obj->exp,               fread_number( fp ) );


make a case 'X' like this:


        case 'X':
            KEY( "Xptolevel",   obj->xp_tolevel,        fread_number( fp ) );
            break;
                        

in file handler.c
*****************

below:
 if ( extra_flags & ITEM_ROT_DEATH    ) strcat( buf, " rot_death"    );
 
add:
 if ( extra_flags & ITEM_RELIC        ) strcat( buf, " relic" );  


in file tables.c
****************

below:
   {   "rotdeath",             ITEM_ROT_DEATH,         TRUE    },         

add:
   {   "relic",                ITEM_RELIC,             TRUE    },         


in file interp.h
****************

at the bottom of the file add:
DECLARE_DO_FUN( do_mrelic       );     


in file interp.c
****************

in the immortal commands add:
{"mrelic",      do_mrelic,  POS_DEAD, L3, LOG_NORMAL, 1}, 


in file fight.c
***************

in void group_gain

Below:
 obj_next = obj->next_content;
            
 if ( obj->wear_loc == WEAR_NONE )
     continue; 

Add:
   if ( IS_OBJ_STAT(obj, ITEM_RELIC) && obj->xp_tolevel > 0 )
   {

       gain_object_exp( ch, obj, xp );
   }        


Ok that should be it. If I left out anything then be sure and let me know. Just make clean,
compile and copyover and you should be good to go.