#include <files.h>
#include <pl.h>
#include <stdproperties.h>
#include <macros.h>
#include <ss_types.h>
#include <wa_types.h>
#include <formulas.h>
#include "../def.h"
#include "no_attack.h"
#define TP this_player()
#define DT_OGLUSZANIE "rz_i_damage_type_broni_ogluszajacej"



#ifndef W_WARHAMMER

#define W_WARHAMMER 4
#define SS_WEP_WARHAMMER W_WARHAMMER

#endif

#define RZ_SPECJAL "_rz_ktory_alarm_" 
#define RZ_TEMP "temporary prop"

#define OBR_BRAK 0
#define OBR_BLEKKIE 1
#define OBR_LEKKIE 2
#define OBR_SREDNIE 4
#define OBR_CIEZKIE 8
#define OBR_BCIEZKIE 16
#define OBR_SMIERTELNE 32
#define RZ_SPECJAL "_rz_ktory_alarm_" 

#define MINIMALNA_WAGA 5000
#define DOZWOLONE_BRONIE ({W_SWORD,W_AXE,W_WARHAMMER,W_POLEARM})

#define MECZENIE_PRZED       1
#define MECZENIE_PO          1

public void do_boju(object ja, object cel, object bron, object paraliz);
int jakie_obr(int proc);
void wyswietl_opisy(object ja, object cel, int numer_obr);


/* Funkcja wywolywana przez komende 'szarzuj'
 */

mixed 
sila_ciosu(object kto, object kogo, int spec, int lok_zbr)
{
    int str1 = kto->query_stat(SS_STR);
    object bron = (kto->query_weapon(W_RIGHT) || kto->query_weapon(W_BOTH));
    int pen;
    int *dt = allocate(4);
    int dts= 0;
    int specjal = kto->query_skill(spec);
    int con = kogo->query_stat(SS_CON);
    int um = kto->query_skill(bron->query_wt());
    int zbr;
    int temp;
    int sila;
    mixed zbr_ac;
    // Mor: tutaj dorobilem losowy wybor damage type
    temp = bron->query_dt();
    if(temp >= W_CLUB)
    {
	dt[2] = 1;
	dt[3]++;
	temp -= 4;
    }
    if(temp >= W_SLASH)
    {
	dt[1] = 1;
	dt[3]++;
	temp -= 2;
    }
    if(temp >= W_IMPALE)
    {
	dt[0] = 1;
	dt[3]++;
    }
    dt[3] = random(dt[3]) + 1;
    temp = 0;
    while(temp < dt[3])
    {
	if(dt[dts])
	    temp++;
	dts++;
    }
    dts--;
    switch(dts)
    {
    case 0:
	dt[3] = W_IMPALE;
	break;
	
    case 1:
	dt[3] = W_SLASH;
	break;

    case 2:
	dt[3] = W_CLUB;
	break;
	
    default:
	throw("Damage type poza oczekiwana wartoscia.");
    }
    pen = bron->query_modified_pen()[dts];
    // Mor: tutaj dodalem branie ac dla hitlokacji z combat objecta
    // oraz losowy wybor hitlokacji dla niehumanoidow...
    if(kogo->query_humanoid())
    {
	zbr_ac = kogo->query_combat_object()->query_hitloc(lok_zbr)[3];
	if (pointerp(zbr_ac))
	{
		if (sizeof(zbr_ac)<=dts)
			throw("Dts poza oczekiwana wartoscia.");
		zbr=zbr_ac[dts];
	}
	else 
	zbr=zbr_ac;
    }
    else
    {
	int *ids = kogo->query_combat_object()->query_hitloc_id();
	int wyb = random (100) + 1;
	int a;
	temp = 0;

/// Ponizej troche zmienilem bo sie wykrzaczalo (Silvy 3.09.98)
	
	for(a = 0 ; a < sizeof(ids) ; a++)
	{
	    if(temp += kogo->query_combat_object()->query_hitloc(ids[a])[1] > wyb)
	    {
          	zbr = kogo->query_combat_object()->query_hitloc(ids[a])[3][dts];
		break;
	    }
	}
    }
    kto->add_prop(DT_OGLUSZANIE, dts);
    sila=random((F_PENMOD(pen,um) + F_STRENGTH_DAMAGE_MOD(str1) ) - F_AC_MOD(zbr));   
    return (sila>0) ? sila : zbr;
}

public int
trafil_szarza(object kto, object kogo, int czym)
{
    int wynik= kto->resolve_task(TASK_ROUTINE+100, 
		    ({ SKILL_WEIGHT, 70, TS_STR,
		       SKILL_WEIGHT, 150, 100, 
		       SKILL_WEIGHT, 50, czym }), 
		kogo, ({ SKILL_WEIGHT, 40, TS_DEX, 
		       SKILL_WEIGHT, 120, SS_DEFENCE }));
    if (wynik<0) wynik=0;
		       
    return wynik;
}

int
szarzuj(string str)
{
    float czas;
    object *oblist,p;
    object miecz = TP->query_weapon(W_RIGHT);
    object paraliz;
    oblist = parse_this(str,"'na' %l:"+PL_BIE);
    if (!miecz) miecz=TP->query_weapon(W_BOTH);
    if (!miecz) miecz=TP->query_weapon(W_LEFT);

    if (sizeof(oblist) > 1)
    {
        notify_fail("Na kogo konkretnie chcesz zaszarzowac?\n");
        return 0;
    }
    if (sizeof(oblist) == 0)
    {
        notify_fail("Na kogo chcesz zaszarzowac?\n");
        return 0;
    }

    if (TP->query_prop(OBJ_I_WEIGHT) < MINIMALNA_WAGA) 
    {
        notify_fail("Masz zbyt mala mase, aby skutecznie " +
            "zaszarzowac. Sproboj wiecej jesc lub nosic " +
            "ciezsza zbroje.\n");
        return 0;
    }

    if (!miecz)
    {
        notify_fail("Musisz dzierzyc jakas bron, aby moc zaszarzowac.\n");
        return 0;
    }

    if (member_array(miecz->query_wt(), DOZWOLONE_BRONIE) < 0)
    {
    // Mor: to jak z tymi polearmami? Moga byc czy nie? :)
    // (kod pozwala na ich uzywanie)
          notify_fail("Przy pomocy tej broni raczej nie da sie " +
              "przeprowadzic szarzy.\n");
        return 0;
    }

    if (environment(TP)->query_prop(ROOM_M_NO_ATTACK))
    {
        if (stringp(environment(TP)->query_prop(ROOM_M_NO_ATTACK)))
            write(environment(TP)->query_prop(ROOM_M_NO_ATTACK));
        else
            write("W tym miejscu nie mozesz przeprowadzac szarzy.\n");
        return 0;
    }

    if (TP->query_prop(RZ_SPECJAL))
    {
        write("Musisz odczekac troche czasu, zanim bedziesz mogl" +
            TP->koncowka("","a") + " ponownie zaszarzowac.\n");
        return 1;
    }


    if (obiekt_no_attack(TP, oblist[0]))
        return 0;

    if (TP->query_fatigue() < (MECZENIE_PRZED + MECZENIE_PO))
    {
        write("Jestes zbyt zmeczon" + TP->koncowka("y", "a") + ", by moc " +
            "szarzowac.\n");
        return 1;
    }

    if (TP->query_prop(RZ_TEMP) || TP->query_prop(LIVE_O_SPELL_ATTACK)) return notify_fail("Juz przygotowywujesz jeden cios.\n");


// Najwidoczniej spelnia podstawowe warunki... teraz zrobimy przygotowanie
// do ataku.

/* Czas przygotowania: W zaleznosci od skilla:
 *    6 sekund (skill 0) - 3 sekundy (skill 100)
 */

    setuid();
    seteuid(getuid());
    //paraliz=clone_object("/d/Imperium/Nuln/obj/"+"paraliz_szarza.c");
    //paraliz->move(TP);
    czas = 1.5;
    TP->reveal_me(1);

    write("Przygotowujesz sie do szarzy.\n");
    allbb("przygotowuje sie do szarzy.");

    TP->add_fatigue(-MECZENIE_PRZED);

    TP->add_prop(RZ_TEMP, set_alarm(czas, 0.0, "do_boju", TP, oblist[0], miecz, paraliz));

    return 1;
}

public void
do_boju(object ja, object cel, object bron, object paraliz)
{
   object miecz = (TP->query_weapon(W_RIGHT) ||
                TP->query_weapon(W_BOTH) ||
                TP->query_weapon(W_LEFT));

    object room = environment(ja);
    string konc1=TP->koncowka("", "a");
    string konc2=cel->koncowka("", "a");
    int numer_alarmu;
    int proc_obr;
    int cios, trafienie;
    int numer_obr; // jaki opis, lekki, sredni, ciezki czy zabity
    string obr;
    string konc = miecz->koncowka("tym","ta");
    mixed sila;
    paraliz->remove_object();
    ja->remove_prop(RZ_TEMP);


    ja->catch_msg("Szarzujesz na " + cel->query_imie(ja, PL_BIE) + ".\n");
    cel->catch_msg(ja->query_Imie(cel, PL_MIA) + " szarzuje na ciebie " +
        "z wyciagnie" + konc + " w gore " + miecz->short(cel, PL_NAR) +
        ".\n");
    tell_room(room, QCIMIE(ja, PL_MIA) + " szarzuje z wyciagnie" + konc +
        " w gore " + QSHORT(miecz, PL_NAR) + " na " + QIMIE(cel, PL_BIE) +
        ".\n", ({ ja, cel }));


    ja->add_prop(RZ_SPECJAL, set_alarm(8.0, 0.0, "usun_specjala",ja));

    ja->add_fatigue(-MECZENIE_PO);

    ja->attack_object(cel);
    cel->attack_object(ja);


    sila=sila_ciosu(ja, cel, 5, A_BODY);
    if (objectp(sila)) sila = 0;
    cios = trafienie * 7 + 7*sila;

    if (!cel->query_hp()) proc_obr=100;
    else proc_obr = (cios * 100) / cel->query_hp();

    cel->hit_me(cios,W_BLUDGEON,50,TP,-1,A_BODY);
    numer_obr = jakie_obr(proc_obr);

    if (numer_obr == OBR_SMIERTELNE)
    {
        if (cel->query_hp())
        cel->set_hp(0);
        cel->do_die(ja);
        return;
    }
    wyswietl_opisy(ja, cel, numer_obr);
}

int
jakie_obr(int proc)
{
    switch(proc)
    {
        case 0: return OBR_BRAK;
        case 1..7: return OBR_BLEKKIE;
        case 8..18: return OBR_LEKKIE;
        case 19..32: return OBR_SREDNIE;
        case 33..44: return OBR_CIEZKIE;
        case 45..99: return OBR_BCIEZKIE;
    }
    return OBR_SMIERTELNE;
}




void
wyswietl_opisy(object ja, object cel, int numer_obr)
{
    object miecz = this_player()->query_weapon(W_RIGHT) || this_player()->query_weapon(W_BOTH);
    string opis = miecz->short(this_player(),PL_NAR);
    object room = environment(ja);
    string obr;
    string konc1 = cel->koncowka(" mu "," jej ");
    string konc2 = cel->koncowka(" go"," ja");

    if (miecz->query_wt() == W_WARHAMMER)
    {
        switch(numer_obr)
        {
            case OBR_BRAK: obr = "nie wyrzadzajac" + konc1 +
                "jednak zadnej szkody.";
                break;
            case OBR_BLEKKIE: obr = "ledwie" + konc2 + " jednak muskajac.";
                break;
            case OBR_LEKKIE: obr = "lekko"+konc2+" raniac.";
                break;
            case OBR_SREDNIE: obr = "raniac"+konc2+".";
                    break;
            case OBR_CIEZKIE: obr = "ciezko"+konc2+" raniac.";
                break;
            case OBR_BCIEZKIE: obr = "miazdzac"+konc1+"kilka kosci.";
                break;
            case OBR_SMIERTELNE: obr = "miazdzac"+konc1+"kosci. Przeciwni"+cel->koncowka("k","czka")
                +" pada na ziemie "+cel->koncowka("martwy.","martwa.");
        }


        tell_room(room,"Umiejetnie wykorzystujac energie rozpedzonej "
            +"masy, uderza " +QIMIE(cel,PL_BIE)+", "+obr+" \n",({cel,ja}));
        ja->catch_msg("Umiejetnie wykorzystujac energie swojej "
            +"rozpedzonej masy, uderzasz "+ QIMIE(cel,PL_BIE)+ ", "
            + obr +"\n");

        switch(numer_obr)
        {
            case OBR_BRAK: obr = "nie wyrzadzajac ci jednak zadnej szkody.";
                break;
            case OBR_BLEKKIE: obr = "ledwie cie jednak muskajac.";
                break;
            case OBR_LEKKIE: obr = "lekko cie raniac.";
                break;
            case OBR_SREDNIE: obr = "raniac cie.";
                break;
            case OBR_CIEZKIE: obr = "ciezko cie raniac.";
                break;
            case OBR_BCIEZKIE: obr = "miazdzac ci kilka kosci.";
                break;
            case OBR_SMIERTELNE: obr = "miazdzac ci kosci. Padasz "
                +"na ziemie "+cel->koncowka("martwy.","martwa.");
        }

        cel->catch_msg( "Umiejetnie wykorzystujac energie rozpedzonej "
            +"masy, uderza cie, "+obr+ "\n");
        ja->catch_msg("Umiejetnie wykorzystujac energie swojej "
            +"rozpedzonej masy, tniesz "+ QCIMIE(cel,PL_BIE)+ ", "
            + obr +"\n");

    }
    else if (miecz->query_wt()==W_AXE || miecz->query_wt()==W_SWORD)
    {
        switch(numer_obr)
        {
            case OBR_BRAK: obr = "nie wyrzadzajac"+konc1+"jednak zadnej szkody.";
                break;
            case OBR_BLEKKIE: obr = "ledwie"+konc2+" jednak muskajac.";
                break;
            case OBR_LEKKIE: obr = "lekko"+konc2+" raniac.";
                break;
            case OBR_SREDNIE: obr = "raniac"+konc2+".";
                break;
            case OBR_CIEZKIE: obr = "wbijajac"+konc1+"ostrze broni gleboko w cialo.";
                break;
            case OBR_BCIEZKIE: obr = "bardzo gleboko wbijajac ostrze swej broni "
                +"w cialo przeciwnika.";
                break;
            case OBR_SMIERTELNE: obr = "przecinajac"+konc2+" na pol. Przeciwni"+
            cel->koncowka("k","czka")+" pada na ziemie "+cel->koncowka("martwy.","martwa.");
        }


        tell_room(room," Umiejetnie wykorzystujac energie rozpedzonej "
            +"masy, tnie " +QCIMIE(cel,PL_BIE)+", " +obr+ " \n",({cel,ja}));
        ja->catch_msg("Umiejetnie wykorzystujac energie swojej "
            +"rozpedzonej masy, tniesz "+ QCIMIE(cel,PL_BIE)+ ", "
            + obr +"\n");
        switch(numer_obr)
        {
            case OBR_BRAK: obr = "nie wyrzadzajac ci jednak zadnej szkody.";
                break;
            case OBR_BLEKKIE: obr = "ledwie cie jednak muskajac.";
                break;
            case OBR_LEKKIE: obr = "lekko cie raniac.";
                break;
            case OBR_SREDNIE: obr = "raniac cie.";
                break;
            case OBR_CIEZKIE: obr = "wbijajac ci ostrze broni gleboko w cialo.";
                break;
            case OBR_BCIEZKIE: obr = "bardzo gleboko wbijajac ostrze swej broni "
                +"w twoje cialo.";
                break;
            case OBR_SMIERTELNE: obr = "przecinajac cie na pol. Padasz na ziemie "
                +cel->koncowka("martwy.","martwa.");
        }

        cel->catch_msg( "Umiejetnie wykorzystujac energie rozpedzonej "
            +"masy, tnie cie, " + obr + "\n");
    }
    else if (miecz->query_wt()==W_POLEARM) // Mor: odzielenie polearma od
    {                                      // sworda i axa wydaje mi sie
        switch(numer_obr)                  // zagadkowe, ale coz... :)
        {
            case OBR_BRAK: obr = "nie wyrzadzajac"+konc1+"jednak zadnej szkody.";
                break;
            case OBR_BLEKKIE: obr = "ledwie"+konc2+" jednak muskajac.";
                break;
            case OBR_LEKKIE: obr = "lekko"+konc2+" raniac.";
                break;
            case OBR_SREDNIE: obr = "raniac"+konc2+".";
                break;
            case OBR_CIEZKIE: obr = "wbijajac"+konc1+"ostrze broni gleboko w cialo.";
                break;
            case OBR_BCIEZKIE: obr = "bardzo gleboko wbijajac ostrze swej broni "
                +"w cialo przeciwnika.";
                break;
            case OBR_SMIERTELNE: obr = "przebijajac"+konc2+" na wylot. Przeciwni"+cel->koncowka("k","czka")
                +" pada na ziemie "+cel->koncowka("martwy.","martwa.");
        }


        tell_room(room," Umiejetnie wykorzystujac energie rozpedzonej "
            +"masy, atakuje " +QCIMIE(cel,PL_BIE)+", " +obr+ " \n",({cel,ja}));
        ja->catch_msg("Umiejetnie wykorzystujac energie swojej "
            +"rozpedzonej masy, atakuje "+ QCIMIE(cel,PL_BIE)+ ", "
            + obr +"\n");
        switch(numer_obr)
        {
            case OBR_BRAK: obr = "nie wyrzadzajac ci jednak zadnej szkody.";
                break;
            case OBR_BLEKKIE: obr = "ledwie cie jednak muskajac.";
                break;
            case OBR_LEKKIE: obr = "lekko cie raniac.";
                break;
            case OBR_SREDNIE: obr = "raniac cie.";
                break;
            case OBR_CIEZKIE: obr = "wbijajac ci ostrze broni gleboko w cialo.";
                break;
            case OBR_BCIEZKIE: obr = "bardzo gleboko wbijajac ostrze swej broni "
                +"w twoje cialo.";
                break;
            case OBR_SMIERTELNE: obr = "przebijajac cie na wylot. Padasz na ziemie "
                +cel->koncowka("martwy.","martwa.");
        }

        cel->catch_msg( "Umiejetnie wykorzystujac energie rozpedzonej "
            +"masy, atakuje cie, " + obr + "\n");
    }
}

