/*
  /std/combat/cmutant.c

  Mutant unarmed initialization routines.

  These routines can inherited by all living objects that need
  mutant unarmed combat values of a standardized type.

  For player objects which normally use a locked combat system, ie where
  the hitlocations and attacks can not be added or removed, this file
  is normally inherited for unarmed initialization purposes.

  Revision history:

 */
#pragma save_binary
#pragma strict_types

inherit "/std/combat/unarmed";

#include "/sys/wa_types.h"
#include "/sys/ss_types.h"
#include "/sys/macros.h"
#include "cmutant.h"
#include "/sys/formulas.h"

#define QEXC (this_object()->query_combat_object())

/*
 * Function name: cr_configure
 * Description:   Configures basic values for this humanoid.
 */
public nomask void
cr_configure() 
{
    ::cr_configure();

    if (query_attackuse())
	QEXC->cb_set_attackuse(query_attackuse());
    else
	QEXC->cb_set_attackuse(100);
}

/*
 * Function name: cr_reset_attack
 * Description:   Set the values for a specific attack. These are called from
 *		  the external combat object.
 * Arguments:     aid: The attack id
 */
public  void
cr_reset_attack(int aid)
{
    int wchit, wcpen, uskill, pen;

    ::cr_reset_attack(aid);
    
    if (!sizeof(query_ua_attack(aid)))
    {
	wchit = W_HAND_HIT;
	wcpen = W_HAND_PEN;
	if (uskill = this_object()->query_skill(SS_UNARM_COMBAT))
	{
	    wchit += F_UNARMED_HIT(uskill, this_object()->query_stat(SS_DEX));
	    wcpen += F_UNARMED_PEN(uskill, this_object()->query_stat(SS_STR));
	}
	
	if (uskill < 1)
	   uskill = -1;

	switch(aid)
	{
	case W_RIGHT:
	    QEXC->cb_add_attack(wchit, wcpen, W_BLUDGEON, 25, aid, uskill + 6);
	    break;
	case W_LEFT:
	    QEXC->cb_add_attack(wchit, wcpen, W_BLUDGEON, 25, aid, uskill + 6);
	    break;
	case W_BOTH:
	    /*
             * We use the hands separately in unarmed combat
             */
	    QEXC->cb_add_attack(0, 0, W_BLUDGEON, 0, aid, uskill + 6);
	    break;
	case W_FOOTR:
	    QEXC->cb_add_attack(wchit, wcpen, W_BLUDGEON, 25, aid, uskill);
	    break;
	case W_FOOTL:
	    QEXC->cb_add_attack(wchit, wcpen, W_BLUDGEON, 25, aid, uskill);
	    break;
	}
	}
	else
	{
	if (uskill = this_object()->query_skill(SS_UNARM_COMBAT))
	{
	    wchit += F_UNARMED_HIT(uskill, this_object()->query_stat(SS_DEX));
	    wcpen += F_UNARMED_PEN(uskill, this_object()->query_stat(SS_STR));
	}
	
	if (uskill < 1)
	   uskill = -1;
	switch(aid)
	{
	case W_MACKA1:
		QEXC->cb_add_attack(DANE_MACKA[0][2], DANE_MACKA[0][3],
			DANE_MACKA[0][4], DANE_MACKA[0][5], aid, uskill);
		break;
	case W_MACKA2:
		QEXC->cb_add_attack(DANE_MACKA[1][2], DANE_MACKA[1][3],
			DANE_MACKA[1][4], DANE_MACKA[1][5], aid, uskill);
		break;
	case W_MACKA3:
		QEXC->cb_add_attack(DANE_MACKA[2][2], DANE_MACKA[2][3],
			DANE_MACKA[2][4], DANE_MACKA[2][5], aid, uskill);
		break;
	case W_MACKA4:
		QEXC->cb_add_attack(DANE_MACKA[3][2], DANE_MACKA[3][3],
			DANE_MACKA[3][4], DANE_MACKA[3][5], aid, uskill);
		break;
	case W_MACKA5:
		QEXC->cb_add_attack(DANE_MACKA[4][2], DANE_MACKA[4][3],
			DANE_MACKA[4][4], DANE_MACKA[4][5], aid, uskill);
		break;
	case W_MACKA6:
		QEXC->cb_add_attack(DANE_MACKA[5][2], DANE_MACKA[5][3],
			DANE_MACKA[5][4], DANE_MACKA[5][5], aid, uskill);
		break;
		
		case W_GLOWA1:
		QEXC->cb_add_attack(DANE_GLOWA[0][2], DANE_GLOWA[0][3],
			DANE_GLOWA[0][4], DANE_GLOWA[0][5], aid, uskill);
		break;
	case W_GLOWA2:
		QEXC->cb_add_attack(DANE_GLOWA[1][2], DANE_GLOWA[1][3],
			DANE_GLOWA[1][4], DANE_GLOWA[1][5], aid, uskill);
		break;
	case W_GLOWA3:
		QEXC->cb_add_attack(DANE_GLOWA[2][2], DANE_GLOWA[2][3],
			DANE_GLOWA[2][4], DANE_GLOWA[2][5], aid, uskill);
		break;
	case W_GLOWA4:
		QEXC->cb_add_attack(DANE_GLOWA[3][2], DANE_GLOWA[3][3],
			DANE_GLOWA[3][4], DANE_GLOWA[3][5], aid, uskill);
		break;
	case W_GLOWA5:
		QEXC->cb_add_attack(DANE_GLOWA[4][2], DANE_GLOWA[4][3],
			DANE_GLOWA[4][4], DANE_GLOWA[4][5], aid, uskill);
		break;
		
	case W_TULOW1:
		QEXC->cb_add_attack(DANE_TULOW[0][2], DANE_TULOW[0][3],
			DANE_TULOW[0][4], DANE_TULOW[0][5], aid, uskill);
		break;
	case W_TULOW2:
		QEXC->cb_add_attack(DANE_TULOW[1][2], DANE_TULOW[1][3],
			DANE_TULOW[1][4], DANE_TULOW[1][5], aid, uskill);
		break;
	case W_TULOW3:
		QEXC->cb_add_attack(DANE_TULOW[2][2], DANE_TULOW[2][3],
			DANE_TULOW[2][4], DANE_TULOW[2][5], aid, uskill);
		break;
	case W_TULOW4:
		QEXC->cb_add_attack(DANE_TULOW[3][2], DANE_TULOW[3][3],
			DANE_TULOW[3][4], DANE_TULOW[3][5], aid, uskill);
		break;
	case W_TULOW5:
		QEXC->cb_add_attack(DANE_TULOW[4][2], DANE_TULOW[4][3],
			DANE_TULOW[4][4], DANE_TULOW[4][5], aid, uskill);
		break;
	case W_TULOW6:
		QEXC->cb_add_attack(DANE_TULOW[5][2], DANE_TULOW[5][3],
			DANE_TULOW[5][4], DANE_TULOW[5][5], aid, uskill);
		break;
		
	case W_NOGA1:
		QEXC->cb_add_attack(DANE_NOGA[0][2], DANE_NOGA[0][3],
			DANE_NOGA[0][4], DANE_NOGA[0][5], aid, uskill);
		break;
	case W_NOGA2:
		QEXC->cb_add_attack(DANE_NOGA[1][2], DANE_NOGA[1][3],
			DANE_NOGA[1][4], DANE_NOGA[1][5], aid, uskill);
		break;
	case W_NOGA3:
		QEXC->cb_add_attack(DANE_NOGA[2][2], DANE_NOGA[2][3],
			DANE_NOGA[2][4], DANE_NOGA[2][5], aid, uskill);
		break;
	case W_NOGA4:
		QEXC->cb_add_attack(DANE_NOGA[3][2], DANE_NOGA[3][3],
			DANE_NOGA[3][4], DANE_NOGA[3][5], aid, uskill);
		break;
	case W_NOGA5:
		QEXC->cb_add_attack(DANE_NOGA[4][2], DANE_NOGA[4][3],
			DANE_NOGA[4][4], DANE_NOGA[4][5], aid, uskill);
		break;
	case W_NOGA6:
		QEXC->cb_add_attack(DANE_NOGA[5][2], DANE_NOGA[5][3],
			DANE_NOGA[5][4], DANE_NOGA[5][5], aid, uskill);
		break;
		
	case W_REKA1:
		QEXC->cb_add_attack(DANE_REKA[0][2], DANE_REKA[0][3],
			DANE_REKA[0][4], DANE_REKA[0][5], aid, uskill);
		break;
	case W_REKA2:
		QEXC->cb_add_attack(DANE_REKA[1][2], DANE_REKA[1][3],
			DANE_REKA[1][4], DANE_REKA[1][5], aid, uskill);
		break;
	case W_REKA3:
		QEXC->cb_add_attack(DANE_REKA[2][2], DANE_REKA[2][3],
			DANE_REKA[2][4], DANE_REKA[2][5], aid, uskill);
		break;
	case W_REKA4:
		QEXC->cb_add_attack(DANE_REKA[3][2], DANE_REKA[3][3],
			DANE_REKA[3][4], DANE_REKA[3][5], aid, uskill);
		break;
	case W_REKA5:
		QEXC->cb_add_attack(DANE_REKA[4][2], DANE_REKA[4][3],
			DANE_REKA[4][4], DANE_REKA[4][5], aid, uskill);
		break;
	
	}
    }
}

/*
 * Function name: cr_reset_hitloc
 * Description:   Set the values for a specific hitlocation
 * Arguments:     hid: The hitlocation (bodypart) id
 */
public void
cr_reset_hitloc(int hid)
{
    ::cr_reset_hitloc(hid);

    if (!sizeof(query_ua_hitloc(hid))) 
    {
	switch(hid)
	{
	case A_HEAD:
	    QEXC->cb_add_hitloc(A_UARM_AC, 15, "glowe", hid);
	    break;
	case A_L_ARM:
	    QEXC->cb_add_hitloc(A_UARM_AC, 10, "lewe ramie", hid);
	    break;
	case A_R_ARM:
	    QEXC->cb_add_hitloc(A_UARM_AC, 10, "prawe ramie", hid);
	    break;
	case A_TORSO:
	    QEXC->cb_add_hitloc(A_UARM_AC, 45, "korpus", hid);
	    break;
	case A_LEGS:
	    QEXC->cb_add_hitloc(A_UARM_AC, 20, "nogi", hid);
	    break;
	    
	case A_MACKA1:
		QEXC->cb_add_hitloc(DANE_MACKA[0][0], DANE_MACKA[0][1],
			OPIS_HL_MACKA[0], hid);
		break;
	case A_MACKA2:
		QEXC->cb_add_hitloc(DANE_MACKA[1][0], DANE_MACKA[1][1],
			OPIS_HL_MACKA[1], hid);
		break;
	case A_MACKA3:
		QEXC->cb_add_hitloc(DANE_MACKA[2][0], DANE_MACKA[2][1],
			OPIS_HL_MACKA[2], hid);
		break;
	case A_MACKA4:
		QEXC->cb_add_hitloc(DANE_MACKA[3][0], DANE_MACKA[3][1],
			OPIS_HL_MACKA[3], hid);
		break;
	case A_MACKA5:
		QEXC->cb_add_hitloc(DANE_MACKA[4][0], DANE_MACKA[4][1],
			OPIS_HL_MACKA[4], hid);
		break;
	case A_MACKA6:
		QEXC->cb_add_hitloc(DANE_MACKA[5][0], DANE_MACKA[5][1],
			OPIS_HL_MACKA[5], hid);
		break;
		
	case A_GLOWA1:
		QEXC->cb_add_hitloc(DANE_GLOWA[0][0], DANE_GLOWA[0][1],
			OPIS_HL_GLOWA[0], hid);
		break;
	case A_GLOWA2:
		QEXC->cb_add_hitloc(DANE_GLOWA[1][0], DANE_GLOWA[1][1],
			OPIS_HL_GLOWA[1], hid);
		break;
	case A_GLOWA3:
		QEXC->cb_add_hitloc(DANE_GLOWA[2][0], DANE_GLOWA[2][1],
			OPIS_HL_GLOWA[2], hid);
		break;
	case A_GLOWA4:
		QEXC->cb_add_hitloc(DANE_GLOWA[3][0], DANE_GLOWA[3][1],
			OPIS_HL_GLOWA[3], hid);
		break;
	case A_GLOWA5:
		QEXC->cb_add_hitloc(DANE_GLOWA[4][0], DANE_GLOWA[4][1],
			OPIS_HL_GLOWA[4], hid);
		break;
	
	case A_TULOW1:
		QEXC->cb_add_hitloc(DANE_TULOW[0][0], DANE_TULOW[0][1],
			OPIS_HL_TULOW[0], hid);
		break;
	case A_TULOW2:
		QEXC->cb_add_hitloc(DANE_TULOW[1][0], DANE_TULOW[1][1],
			OPIS_HL_TULOW[1], hid);
		break;
	case A_TULOW3:
		QEXC->cb_add_hitloc(DANE_TULOW[2][0], DANE_TULOW[2][1],
			OPIS_HL_TULOW[2], hid);
		break;
	case A_TULOW4:
		QEXC->cb_add_hitloc(DANE_TULOW[3][0], DANE_TULOW[3][1],
			OPIS_HL_TULOW[3], hid);
		break;
	case A_TULOW5:
		QEXC->cb_add_hitloc(DANE_TULOW[4][0], DANE_TULOW[4][1],
			OPIS_HL_TULOW[4], hid);
		break;
	case A_TULOW6:
		QEXC->cb_add_hitloc(DANE_TULOW[5][0], DANE_TULOW[5][1],
			OPIS_HL_TULOW[5], hid);
		break;
		
	case A_NOGA1:
		QEXC->cb_add_hitloc(DANE_NOGA[0][0], DANE_NOGA[0][1],
			OPIS_HL_NOGA[0], hid);
		break;
	case A_NOGA2:
		QEXC->cb_add_hitloc(DANE_NOGA[1][0], DANE_NOGA[1][1],
			OPIS_HL_NOGA[1], hid);
		break;
	case A_NOGA3:
		QEXC->cb_add_hitloc(DANE_NOGA[2][0], DANE_NOGA[2][1],
			OPIS_HL_NOGA[2], hid);
		break;
	case A_NOGA4:
		QEXC->cb_add_hitloc(DANE_NOGA[3][0], DANE_NOGA[3][1],
			OPIS_HL_NOGA[3], hid);
		break;
	case A_NOGA5:
		QEXC->cb_add_hitloc(DANE_NOGA[4][0], DANE_NOGA[4][1],
			OPIS_HL_NOGA[4], hid);
		break;
	case A_NOGA6:
		QEXC->cb_add_hitloc(DANE_NOGA[5][0], DANE_NOGA[5][1],
			OPIS_HL_NOGA[5], hid);
		break;
		
	case A_REKA1:
		QEXC->cb_add_hitloc(DANE_REKA[0][0], DANE_REKA[0][1],
			OPIS_HL_REKA[0], hid);
		break;
	case A_REKA2:
		QEXC->cb_add_hitloc(DANE_REKA[1][0], DANE_REKA[1][1],
			OPIS_HL_REKA[1], hid);
		break;
	case A_REKA3:
		QEXC->cb_add_hitloc(DANE_REKA[2][0], DANE_REKA[2][1],
			OPIS_HL_REKA[2], hid);
		break;
	case A_REKA4:
		QEXC->cb_add_hitloc(DANE_REKA[3][0], DANE_REKA[3][1],
			OPIS_HL_REKA[3], hid);
		break;
	case A_REKA5:
		QEXC->cb_add_hitloc(DANE_REKA[4][0], DANE_REKA[4][1],
			OPIS_HL_REKA[4], hid);
		break;
		
	}
    }
}

/*
 * Function name: cr_try_hit
 * Description:   Decide if a certain attack fails because of something
 *                related to the attack itself.
 * Arguments:     aid:   The attack id
 * Returns:       True if hit, otherwise 0.
 */
public nomask int
cr_try_hit(int aid) { return 1; }

/*
 * Function name: cr_attack_desc
 * Description:   Gives the description of a certain unarmed attack slot.
 * Arguments:     aid:   The attack id
 * Returns:       string holding description
 */
public nomask string
cr_attack_desc(int aid)
{
    switch(aid)
    {
    case W_RIGHT:return (random(100)<80 ? "prawa piescia" : "prawym lokciem");
    case W_LEFT:return (random(100)<80 ? "lewa piescia" : "lewym lokciem");
    case W_BOTH:return "joined hands";
    case W_FOOTR:return (random(100)<80 ? "prawa stopa" : "prawym kolanem");
    case W_FOOTL:return (random(100)<80 ? "lewa stopa" : "lewym kolanem");
    
    case W_MACKA1:
    	return OPIS_AT_MACKA[0][random(sizeof(OPIS_AT_MACKA[0]))];
    case W_MACKA2:
    	return OPIS_AT_MACKA[1][random(sizeof(OPIS_AT_MACKA[1]))];
    case W_MACKA3:
    	return OPIS_AT_MACKA[2][random(sizeof(OPIS_AT_MACKA[2]))];
    case W_MACKA4:
    	return OPIS_AT_MACKA[3][random(sizeof(OPIS_AT_MACKA[3]))];
    case W_MACKA5:
    	return OPIS_AT_MACKA[4][random(sizeof(OPIS_AT_MACKA[4]))];
    case W_MACKA6:
    	return OPIS_AT_MACKA[5][random(sizeof(OPIS_AT_MACKA[5]))];
    	
    case W_GLOWA1:
    	return OPIS_AT_GLOWA[0][random(sizeof(OPIS_AT_GLOWA[0]))];
    case W_GLOWA2:
    	return OPIS_AT_GLOWA[1][random(sizeof(OPIS_AT_GLOWA[1]))];
    case W_GLOWA3:
    	return OPIS_AT_GLOWA[2][random(sizeof(OPIS_AT_GLOWA[2]))];
    case W_GLOWA4:
    	return OPIS_AT_GLOWA[3][random(sizeof(OPIS_AT_GLOWA[3]))];
    case W_GLOWA5:
    	return OPIS_AT_GLOWA[4][random(sizeof(OPIS_AT_GLOWA[4]))];
    	
    case W_TULOW1:
    	return OPIS_AT_TULOW[0][random(sizeof(OPIS_AT_TULOW[0]))];
    case W_TULOW2:
    	return OPIS_AT_TULOW[1][random(sizeof(OPIS_AT_TULOW[1]))];
    case W_TULOW3:
    	return OPIS_AT_TULOW[2][random(sizeof(OPIS_AT_TULOW[2]))];
    case W_TULOW4:
    	return OPIS_AT_TULOW[3][random(sizeof(OPIS_AT_TULOW[3]))];
    case W_TULOW5:
    	return OPIS_AT_TULOW[4][random(sizeof(OPIS_AT_TULOW[4]))];
    case W_TULOW6:
    	return OPIS_AT_TULOW[5][random(sizeof(OPIS_AT_TULOW[5]))];
    	
    case W_NOGA1:
    	return OPIS_AT_NOGA[0][random(sizeof(OPIS_AT_NOGA[0]))];
    case W_NOGA2:
    	return OPIS_AT_NOGA[1][random(sizeof(OPIS_AT_NOGA[1]))];
    case W_NOGA3:
    	return OPIS_AT_NOGA[2][random(sizeof(OPIS_AT_NOGA[2]))];
    case W_NOGA4:
    	return OPIS_AT_NOGA[3][random(sizeof(OPIS_AT_NOGA[3]))];
    case W_NOGA5:
    	return OPIS_AT_NOGA[4][random(sizeof(OPIS_AT_NOGA[4]))];
    case W_NOGA6:
    	return OPIS_AT_NOGA[5][random(sizeof(OPIS_AT_NOGA[5]))];
    	
    case W_REKA1:
    	return OPIS_AT_REKA[0][random(sizeof(OPIS_AT_REKA[0]))];
    case W_REKA2:
    	return OPIS_AT_REKA[1][random(sizeof(OPIS_AT_REKA[1]))];
    case W_REKA3:
    	return OPIS_AT_REKA[2][random(sizeof(OPIS_AT_REKA[2]))];
    case W_REKA4:
    	return OPIS_AT_REKA[3][random(sizeof(OPIS_AT_REKA[3]))];
    case W_REKA5:
    	return OPIS_AT_REKA[4][random(sizeof(OPIS_AT_REKA[4]))];
    }  
    return "mind"; /* should never occur */
}

/*
 * Function name: cr_got_hit
 * Description:   Tells us that we got hit. It can be used to reduce the ac
 *                for a given hitlocation for each hit.
 * Arguments:     hid:   The hitloc id
 *                ph:    The %hurt
 *                att:   Attacker
 *		  aid:   The attack id
 *                dt:    The damagetype
 *		  dam:   The damage in hit points
 */
public void
cr_got_hit(int hid, int ph, object att, int aid, int dt, int dam)
{
    /* We do not tell if we get hit in any special way
    */
}

/*
 * Function name: set_all_attack_unarmed
 * Description:   Set up all unarmed attack basics
 * Arguments:     hit - the hit value
 * 		  pen - the pen value
 */
public nomask void
set_all_attack_unarmed(int hit, int pen)
{
    set_attack_unarmed(W_RIGHT, hit, pen, W_BLUDGEON, 25, "");
    set_attack_unarmed(W_LEFT, hit, pen, W_BLUDGEON, 25, "");
    set_attack_unarmed(W_FOOTR, hit, pen, W_BLUDGEON, 25, "");
    set_attack_unarmed(W_FOOTL, hit, pen, W_BLUDGEON, 25, "");
}

/*
 * Function name: set_all_hitloc_unarmed
 * Description:   Set up all unarmed hit location basics
 * Arguments:     ac - an int or an array to modify the ac....
 */
public nomask void
set_all_hitloc_unarmed(mixed ac)
{
    set_hitloc_unarmed(A_BODY, ac, 45, "korpus");
    set_hitloc_unarmed(A_HEAD, ac, 15, "glowe");
    set_hitloc_unarmed(A_LEGS, ac, 20, "nogi");
    set_hitloc_unarmed(A_R_ARM, ac, 10, "lewe ramie");
    set_hitloc_unarmed(A_L_ARM, ac, 10, "prawe ramie");
}

/*
 * Function name: update_procuse()
 * Description:   use this to update the percent usage of attacks
 */
public nomask void
update_procuse()
{
    QEXC->cb_modify_procuse();
}
