/
area/city/
area/crypts/
area/guilds/
area/psuedowild/
area/religion/
data/documents/MPDocs/
data/html/
data/mobprogs/
data/quest/
data/world/
data/world/_utilities/
data/world/images/
design/html/
notes/
player/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "interp.h"
#include "tables.h"

/* Holds all Defensive skills/commands like
 * dodge/parry/shield block, etc
 */

void cmd_combatconfig (CHAR_DATA * ch, char *argument)
{
    char arg[MSL];
    char buf[MSL];
    
    /* No NPC, thats a BAD NPC! */
    if (IS_NPC (ch))
        return;
    
    argument = one_argument (argument, arg);
    
    if (arg[0] == '\0')
    {
        stc     (    " Current combat configuration options:\n", ch);
        stc     (    "  Option       Status\n", ch);
        stc     (    "---------------------\n", ch);
        sprintf(buf, "  Parry        %s\n",
            (IS_SET (ch->new_config, CONFIG_PARRY)) ? "{YOn{x" : "{ROff{x");
        stc(buf, ch);
        sprintf(buf, "  Dodge        %s\n",
            (IS_SET (ch->new_config, CONFIG_DODGE)) ? "{YOn{x" : "{ROff{x");
        stc(buf, ch);
        sprintf(buf, "  Shield Block %s\n",
            (IS_SET (ch->new_config, CONFIG_SHIELDBLOCK)) ? "{YOn{x" : "{ROff{x");
        stc(buf, ch);
        sprintf(buf, "  Roll         %s\n",
            (IS_SET (ch->new_config, CONFIG_ROLL)) ? "{YOn{x" : "{ROff{x");
        stc(buf, ch);
        sprintf(buf, "  Leap         %s\n",
            (IS_SET (ch->new_config, CONFIG_LEAP)) ? "{YOn{x" : "{ROff{x");
        stc(buf, ch);
        stc("\n", ch);
        return;
    }
    
    if (!str_prefix(arg, "parry"))
    {
        if (IS_SET (ch->new_config, CONFIG_PARRY))
        {
            REMOVE_BIT(ch->new_config, CONFIG_PARRY);
            stc("You will no longer parry incomming attacks.\n", ch);
        }
        else
        {
            SET_BIT(ch->new_config, CONFIG_PARRY);
            stc("You will now attempt to parry incomming attacks.\n", ch);
        }
        return;
    }
    
    if (!str_prefix(arg, "dodge"))
    {
        if (IS_SET (ch->new_config, CONFIG_DODGE))
        {
            REMOVE_BIT(ch->new_config, CONFIG_DODGE);
            stc("You will no longer dodge incomming attacks.\n", ch);
        }
        else
        {
            SET_BIT(ch->new_config, CONFIG_DODGE);
            stc("You will now attempt to dodge incomming attacks.\n", ch);
        }
        return;
    }
    
    if (!str_prefix(arg, "shieldblock"))
    {
        if (IS_SET (ch->new_config, CONFIG_SHIELDBLOCK))
        {
            REMOVE_BIT(ch->new_config, CONFIG_SHIELDBLOCK);
            stc("You will no longer Shield block incomming attacks.\n", ch);
        }
        else
        {
            SET_BIT(ch->new_config, CONFIG_SHIELDBLOCK);
            stc("You will now attempt to Shield block incomming attacks.\n", ch);
        }
        return;
    }
    
    if (!str_prefix(arg, "roll"))
    {
        if (IS_SET (ch->new_config, CONFIG_ROLL))
        {
            REMOVE_BIT(ch->new_config, CONFIG_ROLL);
            stc("You will no longer roll away to avoid incomming attacks.\n", ch);
        }
        else
        {
            SET_BIT(ch->new_config, CONFIG_ROLL);
            stc("You will now attempt to roll awat to avoid incomming attacks.\n", ch);
        }
        return;
    }
    
    if (!str_prefix(arg, "leap"))
    {
        if (IS_SET (ch->new_config, CONFIG_LEAP))
        {
            REMOVE_BIT(ch->new_config, CONFIG_LEAP);
            stc("You will no longer leap to avoid incomming attacks.\n", ch);
        }
        else
        {
            SET_BIT(ch->new_config, CONFIG_LEAP);
            stc("You will now attempt to leap to avoid incomming attacks.\n", ch);
        }
        return;
    }
    
    else
    {
        cmd_combatconfig(ch, "");
        return;
    }
        
        
}

/*
 * Check for parry.
 */
bool check_parry (CHAR_DATA * ch, CHAR_DATA * victim)
{
    int chance;

    if (!IS_AWAKE (victim))
        return FALSE;

    if (!IS_SET (victim->new_config, CONFIG_PARRY))
        return FALSE;
    
    chance = get_skill (victim, gsn_parry) / 2;

    if (get_eq_char (victim, WEAR_WIELD) == NULL)
    {
        if (IS_NPC (victim))
            chance /= 2;
        else
            return FALSE;
    }

    if (!can_see (ch, victim))
        chance /= 2;

    /* Casting Penalty */
    if (ch->action[0] == ACTION_CASTING)
    {
        chance /= 2;
    }
    
    if (number_percent () >= chance)
        return FALSE;

    if (victim->action[0] == ACTION_CASTING)
    {
        act ("You lose your concentration as you parry $n's attack.", ch, NULL, victim, TO_VICT);
        act ("$N parries your attack, and studders on their spell.", ch, NULL, victim, TO_CHAR);
        victim->cast_count += 1;
        victim->spell_vars[3] += 1;
        check_improve (victim, gsn_parry, TRUE, 6);
        return TRUE;
    }
    else
    {
        act ("You parry $n's attack.", ch, NULL, victim, TO_VICT);
        act ("$N parries your attack.", ch, NULL, victim, TO_CHAR);
        check_improve (victim, gsn_parry, TRUE, 6);
        return TRUE;
    }
}

/*
 * Check for shield block.
 */
bool check_shield_block (CHAR_DATA * ch, CHAR_DATA * victim)
{
    int chance;
    OBJ_DATA * obj;

    if (!IS_AWAKE (victim))
        return FALSE;

    if (!IS_SET (victim->new_config, CONFIG_SHIELDBLOCK))
        return FALSE;
    
    chance = get_skill (victim, gsn_shield_block) / 2 + 35;

    if (get_eq_char (victim, WEAR_SHIELD) == NULL)
        return FALSE;

    if (number_percent () >= chance)
        return FALSE;

    act ("You block $n's attack with your shield.", ch, NULL, victim, TO_VICT);
    act ("$N blocks your attack with a shield.", ch, NULL, victim, TO_CHAR);
    check_improve (victim, gsn_shield_block, TRUE, 6);
    
    /* Shield bash */
    chance = get_skill(victim, gsn_shield_bash) * 2 / 3;
    if (number_percent() >= chance)
    {
        obj = get_eq_char (victim, WEAR_SHIELD);
        if (obj == NULL)
        {
            log_string("shield bash without a shield? boggle");
        }
        else
        {
            act ("You bash into $n with your shield!", ch, NULL, victim, TO_VICT);
            act ("$N bashes into you with their shield!", ch, NULL, victim, TO_CHAR);
            check_improve (victim, gsn_shield_bash, TRUE, 5);
            damage (victim, ch, obj->level * 2 + number_range(1, 100) / 2, gsn_shield_bash, DAM_BASH, TRUE, FALSE);
        }
    }
    
    return TRUE;
}


/*
 * Check for dodge.
 */
bool check_dodge (CHAR_DATA * ch, CHAR_DATA * victim)
{
    int chance;

    if (!IS_AWAKE (victim))
        return FALSE;
    
    if (!IS_SET (victim->new_config, CONFIG_DODGE))
        return FALSE;
    
    chance = get_skill (victim, gsn_dodge) / 2;

    if (!can_see (victim, ch))
        chance /= 2;
    if (victim->action[0] == ACTION_CASTING)
        chance /= 2;
    
    if (number_percent () >= chance)
        return FALSE;
    
    if (victim->action[0] == ACTION_CASTING)
    {
        act ("You stop your spell for a second to dodge $n's attack.", ch, NULL, victim, TO_VICT);
        act ("$N stops their spell for a second to dodge your attack.", ch, NULL, victim, TO_CHAR);
        victim->cast_count += 1;
        victim->spell_vars[3] += 1;
        check_improve (victim, gsn_dodge, TRUE, 6);
        return TRUE;
    }
    else
    {
        act ("You dodge $n's attack.", ch, NULL, victim, TO_VICT);
        act ("$N dodges your attack.", ch, NULL, victim, TO_CHAR);
        check_improve (victim, gsn_dodge, TRUE, 6);
        return TRUE;
    }
}

/*
 * Check for Roll.
 */
bool check_roll (CHAR_DATA * ch, CHAR_DATA * victim)
{
    int chance;

    if (!IS_AWAKE (victim))
        return FALSE;

    if (!IS_SET (victim->new_config, CONFIG_ROLL))
        return FALSE;
    
    chance = get_skill (victim, gsn_roll) / 2;

    if (!can_see (victim, ch))
        chance /= 2;
    if (victim->action[0] == ACTION_CASTING)
        chance /= 2;

    if (number_percent () >= chance)
        return FALSE;

    if (victim->action[0] == ACTION_CASTING)
    {
        act ("You stop your spell for a second to roll away from $n's attack.", ch, NULL, victim, TO_VICT);
        act ("$N stops their spell for a second and rolls away from your attack.", ch, NULL, victim, TO_CHAR);
        victim->cast_count += 1;
        victim->spell_vars[3] += 1;
        check_improve (victim, gsn_roll, TRUE, 6);
        return TRUE;
    }
    else
    {
        act ("You skillfully roll away from $n's attack.", ch, NULL, victim, TO_VICT);
        act ("$N skillfuly rolls their body away from your attack.", ch, NULL, victim, TO_CHAR);
        check_improve (victim, gsn_roll, TRUE, 6);
        return TRUE;
    }
}

/*
 * Check for leap.
 */
bool check_leap (CHAR_DATA * ch, CHAR_DATA * victim)
{
    int chance;

    if (!IS_AWAKE (victim))
        return FALSE;
    
    if (!IS_SET (victim->new_config, CONFIG_LEAP))
        return FALSE;

    chance = get_skill (victim, gsn_leap) / 3;

    if (!can_see (victim, ch))
        chance /= 2;

    if (victim->action[0] == ACTION_CASTING)
        chance /= 2;
    
    if (number_percent () >= chance)
        return FALSE;

    if (victim->action[0] == ACTION_CASTING)
    {
        act ("You quickly leap away $n's attack, and resume your spell.", ch, NULL, victim, TO_VICT);
        act ("$N quickly leaps away from your attack, and resumes their spell.", ch, NULL, victim, TO_CHAR);
        victim->cast_count += 1;
        victim->spell_vars[3] += 1;
        check_improve (victim, gsn_leap, TRUE, 6);
        return TRUE;
    }
    else
    {
        act ("You quickly leap away from $n's attack.", ch, NULL, victim, TO_VICT);
        act ("$N quickly leaps away from your attack.", ch, NULL, victim, TO_CHAR);
        check_improve (victim, gsn_leap, TRUE, 6);
        return TRUE;
    }
}