sunder2.1/clan/
sunder2.1/class/
sunder2.1/class/bak/
sunder2.1/doc/ideas/
sunder2.1/gods/
sunder2.1/log/
sunder2.1/msgbase/
sunder2.1/src/o/
sunder2.1/time/
/**********************************************************
 *************** S U N D E R M U D *** 2 . 0 **************
 **********************************************************
 * The unique portions of the SunderMud code as well as   *
 * the integration efforts for code from other sources is *
 * based primarily on the efforts of:                     *
 *                                                        *
 * Lotherius <aelfwyne@operamail.com> (Alvin W. Brinson)  *
 *    and many others, see "help sundermud" in the mud.   *
 **********************************************************/

/*
 * Author: Lotherius (aelfwyne@operamail.com)
 * Purpose:
 * Functions in this file provide standard comparisons for various
 * totals used in-game. The functions here will calculate these totals
 * based on rulesets defined in one place - here, not all over the
 * code.
 */

#include "everything.h"

/*
 * int function c_base_ac: 
 * Parameters: 
 * 1. object *obj 
 * 2. actype = AC_PIERCE, AC_BASH, AC_SLASH, AC_EXOTIC
 * Returns:
 * base AC with no modifiers (except condition) for object.
 */

int c_base_ac ( OBJ_DATA *obj, int actype )
{
     int rval;
     int i;

     if ( !obj )
          return 0;
     
     if ( obj->condition <= 0 ) // Useless objects are.. useless.
          return 0;
     
     if ( obj->item_type != ITEM_ARMOR ) // This should've been checked elsewhere, but doublecheck here.
          return 0;
     
     /* Since we can't count on type being same as [i] */
     for ( i = 0 ; material_table[i].type != obj->material; i++ )
          ;         /* nothing */
     
     switch ( actype )
     {
     case AC_PIERCE:
          rval = material_table[i].pierce;
          break;
     case AC_BASH:
          rval = material_table[i].bash;
          break;
     case AC_SLASH:
          rval = material_table[i].slash;
          break;
     case AC_EXOTIC:
          rval = material_table[i].exotic;
          break;
     default:
          bugf ( "Invalid AC_Type: %d in c_base_ac", actype );
          rval = 0;
     }
     
     /* the metals */
     if ( IS_SET ( material_table[i].flags, MAT_METAL ) )
     {
          if ( IS_SET ( obj->vflags, ARMOR_BANDED ) )		/* 10% bonus */
               rval += ( rval *10 / 100 );
          else if ( IS_SET ( obj->vflags, ARMOR_RING ) )        /* 20% bonus exc piercing, which is -10% */
          {
               if ( actype != AC_PIERCE )
                    rval += ( rval * 20 / 100 );
               else
                    rval -= ( rval * 10 / 100 );
          }
          else if ( IS_SET ( obj->vflags, ARMOR_SCALE ) )	/* 20% bonus all around */
               rval += ( rval * 20 / 100 );
          else if ( IS_SET ( obj->vflags, ARMOR_PLATE ) )	/* 45% bonus */
               rval += ( rval * 45 / 100 );
          
          /* Now check for cast / forged */
          /* Default is considered here to be a combination of the two */
          if ( IS_SET ( obj->vflags, ARMOR_CAST ) )
               rval -= ( rval * 15 / 100 );
          else if ( IS_SET ( obj->vflags, ARMOR_FORGED ) )
               rval += ( rval * 15 / 100 );
          
          /* If an armor is tempered, it gets better against pierce and slash */
          if ( IS_SET ( obj->vflags, ARMOR_TEMPERED ) )
          {
               if ( actype == AC_PIERCE || actype == AC_SLASH )
                    rval += ( rval * 15 / 100 );
          }
     }
     /* The leathers */
     else if ( obj->material == MATERIAL_LEATHER )
     {
          if ( IS_SET ( obj->vflags, ARMOR_HARDENED ) )
               rval += ( rval * 25 / 100 );
          else if ( IS_SET ( obj->vflags, ARMOR_SOFTENED ) )
               rval -= ( rval * 25 / 100 );
          if ( IS_SET ( obj->vflags, ARMOR_STUDDED ) )
               rval += ( rval * 20 / 100 );
     }
     
     if ( IS_SET ( obj->vflags, ARMOR_THICKENED ) )	// Thickened
          rval += ( rval * 10 / 100 );

     /* Fudge it for quality. All default items are not modified here */
     if ( IS_SET ( obj->vflags, ARMOR_BAD_QUALITY ) )
          rval = ( rval * 50 / 100 );				/* 50% quality */
     else if ( IS_SET ( obj->vflags, ARMOR_LOW_QUALITY ) )
          rval = ( rval * 75 / 100 );				/* 75% quality */
     else if ( IS_SET ( obj->vflags, ARMOR_HIGH_QUALITY ) )
          rval += ( rval * 25 / 100 );  			/* 25% BETTER quality */

     /* Do some fudging for item level */
     if ( obj->level <= 99 )
     {
          rval -= ( 100 - obj->level ) / 3;
     }
     
     if ( rval < 0 )
          rval = 0;
     
     rval = (rval * obj->condition / 100 ); // Reduce for condition
     rval = (rval/2);
     
     if ( rval > 99 )	/* Drop to 99 */
          rval = 99;

     return ( rval );
}

/*
 * int fuction c_current_ac
 * Parameters:
 * 1. CHAR_DATA ch : obvious.
 * 2. int where    : body location via wear_info
 * 3. int actype   : = AC_PIERCE, AC_BASH, AC_SLASH, AC_EXOTIC
 * Returns:
 * AC of location with any applicable modifiers ( spells, etc )
 */

int c_current_ac ( CHAR_DATA *ch, int where, int actype )
{
     OBJ_DATA    *obj = NULL;
     OBJ_DATA	 *sobj = NULL;
     int	  k, j;
     
     if ( where == -1 )
          return 0;
     if ( wear_info[where].has_ac == FALSE )
          return 0;

     obj = get_eq_char ( ch, where );
     if ( wear_info[where].supercede > 0 )
          sobj = get_eq_char ( ch, wear_info[where].supercede );

     if ( ch->armor > 0 )
          k = ( ch->armor / 10 );	// 1/10th of magical bonus goes to this location.
     else
          k = 0;

     /* NPC's get some free armor, but less if the actually have armor */
     
     if ( IS_NPC ( ch ) )
          j = ch->level / 3;
     else
          j = 0;

     if ( obj && sobj )	// Got both
     {
          if ( IS_NPC ( ch ) )
               return ( ( c_base_ac ( obj, actype ) ) + ( c_base_ac ( sobj, actype ) / 2 ) + k + ( j/3 ) );
          else
               return ( ( c_base_ac ( obj, actype ) ) + ( c_base_ac ( sobj, actype ) / 2 ) + k );
     }
     else if ( obj && !sobj )	// Got primary only
     {
          if ( IS_NPC ( ch ) )
               return ( c_base_ac ( obj, actype ) + k + ( j / 2 ) );
          else               
               return ( c_base_ac ( obj, actype ) + k );
     }
     else if ( !obj && sobj )	// Got supercede only
     {
          if ( IS_NPC ( ch ) )
               return ( ( c_base_ac ( obj, actype ) / 2 ) + k + ( j / 2 ) );
          else
               return ( ( c_base_ac ( sobj, actype ) / 2 ) + k );
     }
     else			// Got neither
     {
          if ( IS_NPC ( ch ) )
               return ( k+j );
          else
               return ( k );
     }
}

/*
 * int function c_rollweapon:
 * Parameters:
 * 1. object *obj
 * 2. Boolean, return roll ( FALSE ), or return Average ( TRUE )
 * Returns:
 * A rolled damage for the weapon if average is FALSE,
 * An average damage for the weapon if average is TRUE.
 * Adds no modifiers.
 */

//int c_rollweapon ( OBJ_DATA *obj, bool average )
//{
//     
//}