#include "mith.h"
#include "ryc_zak.h"
#include "funkcje.h"

#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 DOZWOLONE_BRONIE ({W_SWORD,W_AXE,W_WARHAMMER,W_POLEARM})

public void do_boju(object ja, object cel, object bron);
int jakie_obr(int proc);
void wyswietl_opisy(object ja, object cel, int numer_obr);



/* Funkcja wywolywana przez komende 'szarzuj'
 */
int
szarzuj(string str)
{
    float czas;
    object *oblist,p;
    object miecz = TP->query_weapon(W_RIGHT);
    oblist = parse_this(str,"'na' %l:"+PL_BIE);
    if (!miecz) miecz=TP->query_weapon(W_BOTH);
    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;
    }
	 // Mor: Mith musi sie tym zajac to jego kocepcja :)
    if (TP->query_prop(OBJ_I_WEIGHT) < 0) // probnie, potem zwiekszymy.
    {
        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 bron, aby moc zaszarzowac.\n");
        return 0;
    }

    if (!(member_array(miecz->query_wt(),DOZWOLONE_BRONIE)+1))
    {
    // Mor: to jak z tymi polearmami? Moga byc czy nie? :)
    // (kod pozwala na ich uzywanie)
    	  notify_fail("Dobywana przez ciebie bronia nie mozesz"
            +" 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 tej lokacji nie mozesz przeprowadzic szarzy.\n");
        return 0;
    }

        if (TP->query_prop(RZ_SPECJAL))
    {
        write("Musisz odczekac troche czasu, zanim bedziesz mogl"+TP->koncowka("","a")
            +"znowu uzyc specjalnego ciosu.\n");
        return 1; // To jest TA szarza... wiec zwracamy 1.
//A: Rodzaje gramatyczne.. sprawdzac
//M: Zrobione
    }

    if (!TP->query_skill(RZ_SZARZA))
    {
        notify_fail("Musisz poznac przynajmniej podstawy tej techniki walki, "
            +"aby moc skutecznie szarzowac.\n");
        return 0;
    }

    if (TP->query_attack())
    {
    	write("Nie mozesz szarzowac podczas walki.\n");
    	return 1;
    }

//A: Dorob sprawdzenie, czy ja z nim nie walcze, i czy on ze mna nie walczy.
//M: Zrobione

// Najwidoczniej spelnia podstawowe warunki... teraz zrobimy przygotowanie
// do ataku.

/* Czas przygotowania: W zaleznosci od skilla:
 *    3sek (skill 0) - 1sek (skill 100)
 */
    czas=(300.0-2.0*itof(TP->query_skill(RZ_SZARZA)))/100.0;


    write("Przygotowujesz sie do szarzy.\n");
    allbb("przygotowuje sie do szarzy.");
    set_alarmv(czas, 0.0, "do_boju",({this_player(), oblist[0], miecz}));
    //A: TP _NIE ZAWSZE_ dziala w alarmach!
    //M: Byc moze... testowalem, i dzialalo :)
    return 1;
}

public void
do_boju(object ja, object cel, object bron)
{
    object miecz = (TP->query_weapon(W_RIGHT) || TP->query_weapon(W_BOTH));
    // Lub nie sprawdza drugiego wyrazenia, jesli pierwsze jest prawdziwe.
    // Mozna zrobic tez (miecz=TP->... || miecz=TP->query...)
    string opis = miecz->short(this_player(),PL_NAR);
    object room = environment(ja);
    string konc1=TP->koncowka("", "a");
    string konc2=cel->koncowka("", "a");
    int numer_alarmu;
    int proc_obr;
    int cios;
    int numer_obr; // jaki opis, lekki, sredni, ciezki czy zabity
    string obr;
    string konc = miecz->koncowka("tym","ta");
//A: Dorob sprawdzenie czy wciaz ma miecz w rece.
//M: Zrobione
    if (miecz!=bron)
    {
    	write("Nie mozesz zmieniac broni podczas przygotowan do szarzy.\n");
    	return;
    }

    if (!present(cel,room))
    {
        actor(({cel}),PL_MIA, " zdazyl"+konc2+" ci uciec.");
        allbb("wyglada, jakby sie rozmyslil"+konc1+" i juz nie mial"+konc1+
        	" zamiaru szarzowac.");
//A: Sprawdzenie rodzajow gram...
//M: Zrobione

        return;
    }

//A: Sprawdzenie na walke tutaj jest swinskie dla rycerzy, bo jak ktos
// zobaczy, ze rycerz na niego szarzuje, to go zaatakuje w czasie przygotowania,
// a rycerz nie bedzie mogl szrrzy do konczyc. To trzeba bedzie jeszcze omowic.
//M: Swinskie... Ale po to to jest...
    if (ja->query_attack())
    {
        write("Nie mozesz szarzowac podczas walki.\n");
        return;
    }
    actor("Szarzujesz na", ({cel}),PL_BIE, ".");
    all2act("szarzuje z wyciagnie" + konc + " w gore " + opis + " na",
        ({ cel }), PL_BIE, ".");
    target("szarzuje na ciebie z wyciagnie" + konc + " w gore " +
        opis + ".", ({ cel }));

    ja->add_prop(RZ_SPECJAL, set_alarm(PRZERWA, 0.0, "usun_specjala", ja));
//A: Przerwa pomiedzy specjalami nbiie uzalezniona od niczego. Moze to dobzre, moze zle?
//M: Wydaje mi sie, ze to dobrze... Mozna by zrobic zaleznosc od Con, ale to
// sie liczy: jak wiecej con, to silniej wali, ale meczy sie tak samo.
// Mor: no nie do konca... mozna by to uzaleznic od obciazenia i voluma
// czekam na
    if (!trafil(ja, cel, miecz->query_wt(),RZ_SZARZA))
    {
        tell_room(room,QCIMIE(cel,PL_MIA)+" zrecznie unika "
            +"zbyt wolno zadanego ciosu. "+ QCIMIE(ja,PL_MIA)+
            " traci na krotka chwile "
            +"rownowage. Po chwili odzyskuje ja i kontynuuje "
            +"tak niefortunnie rozpoczeta walke.\n", ({cel,ja}));
        cel->catch_msg("Zrecznie unikasz zbyt wolno zadanego "
            +"ciosu.\n");
        ja->catch_msg(QCIMIE(cel,PL_MIA)+" zrecznie unika "
            +"zbyt wolno zadanego przez ciebie ciosu.\n");


//        cel->catch_msg( QCIMIE(ja,PL_MIA) + " traci lekko "
//            +"rownowage, zanim jednak zdazysz cos zrobic "
//            +"odzysuje ja i walka toczy sie dalej normalnie.\n");
//        ja->catch_msg("Tracisz na moment rownowage, szybko jednak "
//            +"odzysujesz ja i walka z " + QCIMIE(cel,PL_NAR) +
//            " toczy sie dalej normalnie.\n");
        ja->attack_object(cel);
        return;

//A: To troche glupio wyglada z zewnatrz, dla trzeciej osoby. Lepiej
// Jak by powiazac te dwie informacje ze soba. O uniknieciu ciosu i stracie
// rownowagi.
//M: Zrobione
    }
    // Mor: czy ja dobrze widze? sila szarzy mnozona jest przez 1,2 lub 3?
    // zwieksze tu rozdzielczosc (teraz jest 1.00-3.00 z dokl do .01)
    cios = ((100+random(201))*sila_ciosu(ja, cel, RZ_SZARZA, A_BODY)) / 100;
    proc_obr = (cios * 100) / cel->query_hp();

//A: Nie lepiej to zgrac w jedna funkcje ?
// Od razu dac heal_hp (-obrazenia) i spradzac czy query_hp == 0
// Zamiast peiprzyc sie z numerami obrazen. A podzial na nie zostawic
// wewnetrznie funkcji wysietl_opisy.. tam tez wyliczac rodzaj.
//M: Tak jest troszke przejrzysciej... Tak sadze

    numer_obr = jakie_obr(proc_obr);
    wyswietl_opisy(ja, cel, numer_obr);
    cel->heal_hp(-cios);
    if (numer_obr == OBR_SMIERTELNE)
    {
        cel->do_die(ja);
        return;
    }
//    tell_room(room, "Dalej walka toczy sie normalnie.\n",({}));
    ja->attack_object(cel);
}

int
jakie_obr(int proc)
{
    switch(proc)
    {
        case 0: return OBR_BRAK;
        case 1..7: return OBR_BLEKKIE;
        case 8..14: return OBR_LEKKIE;
        case 15..25: return OBR_SREDNIE;
        case 36..44: return OBR_CIEZKIE;
        case 45..99: return OBR_BCIEZKIE;
    }
    return OBR_SMIERTELNE;

    //A: Nie wiem czy tego rozgraniczenia nie mozna by robic w samym
    // wyswietl opisy()... bez sensu osobno. Tylko tam to jest potrzebne.
    // mam watpliwosci co do rozdzialu tego na lekki i ciezkie
    // Jak z pierwszego ciosu zabierzesz czlowiekowi polowe zdrowia, to juz
    // sa raczej bardzo ciezkie obrazenia, nie ?
    //M: Jakbym to robil w wyswietl_opisy, to i tak bym dal osobna
    // funkcje... uczono mnie, ze im wiecej funkcji tym lepiej..
    // A wartosci sa jak zwykle strzelane...
}

void
wyswietl_opisy(object ja, object cel, int numer_obr)
{
    object miecz = this_player()->query_weapon(W_RIGHT) || this_player()->query_weapon(W_BOTH);
    // Mor: kurcze albo jestem slepy albo potem nie ma nigdzie opisow
    // zaleznych od broni
    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 " +QCIMIE(cel,PL_BIE)+", "+obr+" \n",({cel,ja}));
        ja->catch_msg("Umiejetnie wykorzystujac energie swojej "
            +"rozpedzonej masy, uderzasz "+ 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 = "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");
    }
    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");
    }
}
