/*
 * Maly pliczek, ktory nalezy inheritowac OPROCZ jakiegos standard room-u,
 *  aby korzystac z funkcji mapera.
 * "Uruchomic" go nalezy wywolaniem 'wlacz_mapera(plik_mapera)'.
 *  plik_mapera to plik naszego maperka ktory dziedziczy standardowego :)
 *  Ustawia opisy, wyjscia itd. Jesli chcemy cos zrobic samodzielnie, np
 *  ustawic wlasny opis, ale po dodaniu maperowych wyjsc, to po prostu
 *  opis ustawiamy PO wywolaniu 'wlacz_mapera'.
 *
 *  Lokacja dziedziczaca powinna tez maskowac leave_inv.
 *  Powinno wygladac tak:
 *  void leave_inv(object ob, object to)
 *  {
 *      ::leave_inv(ob,to);
 *      opuszcza_inv(ob,to);
 *  }
 *
 *  Jest tak dlatego, ze ten plik nie dziedziczy juz nic wiecej,
 *   wiec nic nei moze maskowac, w szczegolnosci leave_inv
 *  Jesli nei dodamy tego leave_inv to po prostu puste lokacje
 *   nie beda usuwane.
 * 
 *  Oprocz tego w init() nalezy dodac wywolanie init_zglos()
 *  init_zglos przejmuje obsluge zglaszania bledow.
 *  Jest to po to, aby przy zglaszanych bledach odnotowana byla konfiguracja
 *   danej lokacji (jakich opisow uzywa)
 *
 *  by Tanis - maj 1999
 */

#include <stdproperties.h>
#include <log.h>
#include <pl.h>
#include <cmdparse.h>
#include <language.h>
#include <macros.h>
#include <std.h>

/*
 * Nazwy lokacji to np. lok1.c, lok2.c, lok3.c itd
 * Aby jakas lokacja byla potraktowana jako ogolna, podstawa lokacji wirtualnej,
 *  jej nazwa musi w tym przypadku wygladac tak: lokx.c lub lokX.c
 * To, jaki znak (tutaj x) jest traktowany jako oznaczenie takiej lokacji
 *  jest definiowane tutaj.
 * Moze to byc wiecej znakow niz jeden, nieistotna jest ich wielkosc.
 * Numery lokacji nie moga byc ujemne! (lok-1.c nie moze byc,
 *   bo lokacja zostanie potraktowana jako ogolna).
 */
#define LOKACJA_OGOLNA "x"

#define PLAYER_I_LOG_TYPE   "_player_i_log_type"
#define PLAYER_O_LOG_OBJECT "_player_o_log_object"

/*
 * 0 1 2
 * 7 * 3
 * 6 5 4
 * 
 * Kierunki wyjsc (liczby - indeks ponizszej tablicy).
 */
#define KIERUNKI ({"polnocny-zachod","polnoc","polnocny-wschod", \
                   "wschod","poludniowy-wschod","poludnie", \
                   "poludniowy-zachod","zachod"})

string maper; // Sciezka do mapera;
int numer_lokacji=-1;

/*
 * Funkcja uruchamiana gdy gracz gdzies wychodzi.
 *  Zwraca ZAWSZE 1 (czyli ze nie mozna wyjsc), bo wyjsca kieruja do tej
 *   samej lokacji (obecnej).
 *  Przejmujemy obsluge wychodzenia i sami wszystko zalatwiamy :)
 */
int
wychodzi(int wyjscie)
{
    int zmeczenie;
    int tmp;
    object dokad;

    wyjscie=atoi(wyjscie);
    
    if(numer_lokacji==(-1)) return 1;
    
    zmeczenie=(maper)->zwroc_zmeczenie(numer_lokacji);
    dokad=(maper)->zwroc_obiekt_docelowy(numer_lokacji,wyjscie);
    
// DEBUG    this_player()->catch_msg("Wychodzisz, numer wyjscia:"+wyjscie+"!\n");
	
	/* Players younger than 2 hours or people carrying less than
	 * 20 % of their capability don't get tired from walking around in
	 * the world...
	 */
	if ((this_player()->query_age() > 7200) &&
	    (tmp = this_player()->query_encumberance_weight()) > 20)
	
	{
	    /* Compute the fatigue bonus. Sneaking gives double fatigue and
	     * so does talking with 80% encumberance.
	     */
	    zmeczenie = (this_player()->query_prop(LIVE_I_SNEAK) ?
		(zmeczenie * 2) : zmeczenie);
	    zmeczenie = ((tmp > 80) ? (zmeczenie * 2) : zmeczenie);

	    /* Player is too tired to move. */
	    if (this_player()->query_fatigue() < zmeczenie)
	    {
		this_player()->catch_msg("Jestes tak zmeczon" + 
		   this_player()->koncowka("y", "a") + ", ze nie mozesz " +
		   "isc w tym kierunku.\n");
		return 1;
	    }

	    this_player()->add_fatigue(-zmeczenie);
	}
	
     this_player()->move_living("na "+KIERUNKI[wyjscie], dokad);

    return 1;
}

/*
 * Funkcja zwraca numer lokacji, a jesli to lokacja ogolna, zwraca -1
 */
int
zwroc_numer_lokacji()
{
    string *tablica;
    string plik;
    int dlugosc_poczatku=0;

    if(numer_lokacji!=(-1)) return numer_lokacji; // Wczesniej ustwilismy...

    tablica=explode(file_name(),"/");

    plik=(explode(tablica[sizeof(tablica)-1],"#"))[0]; // Odcedzamy numer klonu (lokacja#345354)

    dlugosc_poczatku=strlen((maper)->query_poczatek_nazw_plikow());
    
// DEBUG    write("Numer lokacji:"+plik[dlugosc_poczatku..]+"!\n");
// DEBUG    write("Numer wirtualnej:"+LOKACJA_OGOLNA+"!\n");
    if(lower_case(plik[dlugosc_poczatku..])==lower_case(LOKACJA_OGOLNA)) return -1;
    
    return atoi(plik[dlugosc_poczatku..]);
}

void
konfiguruj_lokacje(int numer)
{
    int a,b;
    string *wyjscia;
    mixed *itemy; 
    int kierunek;

    numer_lokacji=numer;
    
    if(numer_lokacji==(-1)) return;
    
    this_object()->set_short((maper)->zwroc_shorta(numer_lokacji));
    this_object()->set_long("@@dlugi_opis");    
    
    wyjscia=(maper)->zwroc_liste_wyjsc(numer_lokacji);
    
    b=sizeof(wyjscia);
    
    for(a=0;a<b;a++)
    {
        kierunek=member_array(wyjscia[a],KIERUNKI);
        if(kierunek>=0 && kierunek<=7) this_object()->add_exit(file_name(),lower_case(wyjscia[a]),"@@wychodzi|"+kierunek+"",0);
    }
    
    itemy=(maper)->zwroc_liste_itemow(numer_lokacji);
    
    b=sizeof(itemy);
    
    for(a=1;a<b;a+=2) this_object()->add_item(itemy[a-1],itemy[a]);
    
    /*
     * Funkcja wlacz dodatki nie jest wykorzystywana standardowo.
     * Sluzy do dodawania np. npc-y.
     * Nalezy ja umeiscic w maperze dziedziczacym standard mapera.
     * Oczywiscie nie musza to byc akurat npc-e, moze to byc cokolwiek...
     */
    (maper)->wlacz_dodatki(numer_lokacji);
}

void
wlacz_mapera(string plik_mapera)
{
    int numer;
    
    maper=plik_mapera;
    
    numer=zwroc_numer_lokacji();
    
    /*
     * Jesli nie jest to lokacja ogolna, to ja konfigurujemy.
     * Jesli nie jest, to nic nie robimy - maper zrobi to za chwile za nas.
     * (nie znamy jej faktycznego numeru, maper go 'zna' ;))
     */
// DEBUG    write("Wlaczamy mapera, numerek:"+numer+"!\n");
    if(numer!=(-1)) konfiguruj_lokacje(numer);
}

/*
 * PONIZSZE FUNKCJE:
 * Funkcja dlugi_opis() zwracajaca dlugi opis lokacji.
 * Mozna ja zamaskowac, dodajac tam np. opis pogody (wywolanie zwracajace
 *  opis pogody) lub cokolwiek innego.
 * Wtedy po prostu nasza funkcja dlugi_opis (juz w samej lokacji)
 * zwraca long_opis()+opis_pogody() - oczywiscie to przyklad.
 * Funkcja long_opis() zwraca opis generowany przez mapera, i ja nalezy
 *  wykorzystac we wlasnej funkcji dlugi_opis (oczywiscie jesli korzystamy
 *  z opisow mapera).
 */
string
long_opis()
{
    if(numer_lokacji==(-1)) return "";
    return (maper)->zwroc_dlugi_opis(numer_lokacji);
}
 
string
dlugi_opis()
{
    return long_opis();
}

void
opuszcza_inv(object ob, object to)
{
    if(sizeof(all_inventory())==0) (maper)->usun_lokacje(numer_lokacji);
	return;
}

int
query_numer_lokacji()
{
    return numer_lokacji;
}

string
nazwa_pliku_lokacji() // Z zewnatrz nei wywolamy efunkcji...
{
   return file_name();
}
   

/*
 * Function name: done_reporting
 * Descripiton  : This function is called from the editor when the player
 *                has finished the report he or she was writing. If any
 *                text was entered it is logged and the player is thanked.
 * Arguments    : string str - the text entered into the editor.
 */
public void
done_reporting(string str)
{
    mixed *tmp;
    int a,b;
    
    int type = this_player()->query_prop(PLAYER_I_LOG_TYPE);

    if (!strlen(str))
    {
	write(LOG_ABORT_MSG(LOG_MSG(type)));
	return;
    }

    str+="\nMAPER IMPERIALNY:\n"+maper+"\n";

    tmp=(maper)->query_dane(1,numer_lokacji);
    b=sizeof(tmp);
    for(a=0;a<b;a++) str+=tmp[a]+", ";
    str+="\b\b:";
//    tmp=(maper)->query_dane(2,numer_lokacji);
//    b=sizeof(tmp);
//    for(a=0;a<b;a++) str+=tmp[a]+", ";
//    str+="\b\b:";
    tmp=(maper)->query_dane(3,numer_lokacji);
    b=sizeof(tmp);
    for(a=0;a<b;a++) str+=tmp[a]+", ";
    str+="\b\b:";
    tmp=(maper)->query_dane(4,numer_lokacji);
    b=sizeof(tmp);
    for(a=0;a<b;a++) str+=tmp[a]+", ";
    str+="\b\b.\n";

    /* Log the note, thank the player and then clean up after ourselves. */
    SECURITY->note_something(str, type,
        this_player()->query_prop(PLAYER_O_LOG_OBJECT));
    write(LOG_THANK_MSG(LOG_MSG(type)));

    this_player()->remove_prop(PLAYER_I_LOG_TYPE);
    this_player()->remove_prop(PLAYER_O_LOG_OBJECT);
}

/*
 * Zglos - zglos jakis raport, o byku, itp.
 */
int
zglos(string str)
{
    object *oblist;
    object target;
    int type = 0,
        przyp;
    string *slowa, slowo, przyimek, parse_string;
    
    notify_fail(
        "Prawidlowa skladnia: 'zglos [globalny] blad [w <obiekcie>]'\n" +
        "                     'zglos [globalny] pomysl [do <obiekt>]'\n" +
        "                     'zglos [globalna] pochwale [za <obiekt>]'\n");

    if (!strlen(str))
        return 0;

    slowa = explode(str, " ");
    
    if (slowa[0][0..6] == "globaln" && sizeof(slowa) > 1)
    {
        type = LOG_SYSBUG_ID - 1;
        slowo = slowa[1]; str = implode(slowa[2..], " ");
    }
    else
    {
        type = LOG_BUG_ID - 1;
        slowo = slowa[0]; str = implode(slowa[1..], " ");
    }

    if (!LOG_TYPES[slowo])
    {
        return 0;
    }
    
    type += LOG_TYPES[slowo];
    
    /* Player may describe the object to make a report about. */
    if (strlen(str))
    {
        switch(type)
        {
            case LOG_PRAISE_ID:
            case LOG_SYSPRAISE_ID: parse_string = "'za' %i:" + PL_BIE;
            			   przyimek = "za"; przyp = PL_BIE;
            			 break;
            case LOG_IDEA_ID:
            case LOG_SYSIDEA_ID:   parse_string = "'do' %i:" + PL_DOP;
            			   przyimek = "do"; przyp = PL_DOP;
            			 break;
            default:		   parse_string = "'w' / 'we' %i:" + PL_MIE;
            			   przyimek = "w"; przyp = PL_MIE;
            			 break;
        }
	/* Find the target. */
	if (!parse_command(str, environment(this_player()), parse_string,
			   oblist) ||
	    (!sizeof(oblist = NORMAL_ACCESS(oblist, 0, 0))))
	{
	    return 0;
	}

	/* One target at a time. */
	if (sizeof(oblist) > 1)
	{
	    notify_fail("Sprecyzuj, o ktory konkretnie obiekt ci chodzi.\n");
	    return 0;
	}

        this_player()->set_obiekty_zaimkow(oblist);
	target = oblist[0];
	write("Zglaszasz " + (type >= LOG_SYSBUG_ID ? slowa[0][0..7] : "")
	    + slowo + " " + przyimek + " " + 
	    target->short(this_player(), przyp) + ".\n");
    }
    else
    {
	target = environment(this_player());
	write("Zglaszasz " + slowo + " " + (type >= LOG_SYSBUG_ID ?
	    "odnoszac" + slowa[0][7..7] + " sie do calej Arkadii" :
	    "w pomieszczeniu, w ktorym stoisz") + ".\n");
    }

    /* Add the relevant data to the player. */
    this_player()->add_prop(PLAYER_I_LOG_TYPE, type);
    this_player()->add_prop(PLAYER_O_LOG_OBJECT, target);

    setuid();
    seteuid(getuid());

    clone_object(EDITOR_OBJECT)->edit("done_reporting", "");
    return 1;
}

void
init_zglos()
{
    add_action(zglos,"zglos");
}

int
mapka(string str="")
{
  write((maper)->wyswietl_mape());
  return 1;
}

int
init_mapa()
{
  if (this_player()->query_wiz_level())
    {
     add_action(mapka,"mapka");
    }
}
