/*
 * Glowny obiekt sterujacy gildia Lesnych Elfow
 *  by Tanis - styczen 1999 (wersja 2.0, ale jak zwykle zreszta beta ;-))))
 *
 *  Na podstawie wczesniejszego takiego obiektu.
 *
 */

#pragma no_clone
#pragma no_inherit
#pragma strict_types

inherit "/std/object.c";

#include "ogolne.h"
#include "lelf.h"

/*
 * osoby - przechowuje informacje o wszystkich czlonkach, tych wywalonych i rowniez o radnych.
 *  Kazde wywolanie osoby["imie"] daje w efekcie tablice.
 *  W tej tablicy kolejne elementy to :
 *     - statusik czlonka
 *     - historia /kto przyjal, kto poparl, kto wyrzucil itd./
 *     - czy 'chce' byc radnym - jesli np. zrezygnowal to przy 'dobieraniu' nie bedzie brany pod uwage.
 *        1 - chce, 0 - nie chce
 *     - czy moze brac rzeczy ze skrzyni - wkladac mozna zawsze /1 - moze brac, 0 - nie moze brac/
 *
 * glosowanie
 *   - czas rozpoczecia ostatniego/aktualnego glosowania
 *   - czy teraz jest glosowanie
 *   
 * wynik - wyniki ostatniego/trwajacego glosowania
 *  wynik["imie"] zwraca info o kandydacie. Wartosc imie istnieje tylko wtedy, jesli ten ktos zglosil kandydature.
 *     - tablica z imionami tych, ktorzy na dana osobe glosowali
 *
 * info - specjalne informacje wyswietlane podczas logowania sie
 *  info["imie"] - podaje informacje przeznaczone dla danej osoby
 *  Informacje to tablica stringow, z ktorych kazdy string jest inna informacja - pozniej z tego
 *   jest skladane jedno info w ramce itd.
 *   Info jest jednorazowe i automatycznie kasowane po wyswietleniu.
 *  info["!all"] - nie jest jednorazowe, wyswietlane wszystkim!
 *  info["!all"] - nie jest tablica, to jest jeden string
 * Info jest dodawane komenda dodaj_info(string dla_kogo,string informacja);
 *
 */

mapping osoby;
mapping wynik;
int *glosowanie=({});
mapping info;
mapping do_wywalenia;

/* 
 * Podania sa zapisywane w postaci mappingu:
 * Zmienna, w ktorej jest przechowywane podanie, wczytywane i zapisywane
 *  funkcjami wczytaj_podanie(string imie_kandydata) i zapisz_podanie()
 * Funkcje te przy okazji usuwaja podania tej osoby ze wszystkich kategorii i zapisuja je pod docelowa
 *  czyli podanie moze zostac wczytane /bez wzgledu na to, gdzie sie znajduje/, potem moze mu byc nadana nowa kategoria
 *  i przy zapisywaniu zostanie umieszone w nowej, kasujac przy okazji stara wersje.
 * Funkcja zapisz_... sprawdza, czy w zmiennej podanie nie ma liczby 0, albo pustej tablicy, jesli tak jest, nic nie robi
 *
 *  UWAGA! Tych funkcji nie nalezy stosowac do obslugi archiwum
 *
 *  format podania - to jest tablica o elementach:
 *    - kategoria, w jakiej powinno sie znajdowac to podanie - po wczytaniu, jaka by nie byla,
 *       zostaje zamieniona na wartosc wynikajaca z lokalizacji, 
 *       z ktorej zostalo to podanie wczytane
 *    - imie kandydata
 *    - lista radnych, ktorzy poparli /tablica z imionami/
 *    - lista czlonkow, ktorzy poparli /--||--/
 *    - string bedacy trescia podania
 *    - data napisania podania /w postaci int - zwracane przez time(), ale bez ctime() !/
 *
 * Do obslugi archiwum uzywamy funkcji umiesc_w_archiwum()
 *  Funkcja ta dopisuje do archiwum danej osoby to podanie, i kasuje je z normalnych kategorii, oraz czysci zmienna podanie.
 */

// /*
//  * Tutaj zapisujemy imiona radnych oraz imiona wlascicieli podan, ktore to podania
//  * dostaly wystarczajace popracie do przyjecia kandydata, ale nie zostal on jeszcze przyjety.
//  * Nie zapisujemy tego nigdziebo ulega przedawnieniu przy apokalipsie.
//  * podania_do_skasowania[imie_kandydata] zwraca tablice z imionami radnych, ktorzy wyrazili chec skasowania tego podania.
//  */
//
// mapping podania_do_skasowania;
//
// wycofane, przynajmniej tymczasowo
//

// Tablica z imionami radnych, ktorzy wnioskuja o rozwiazanei rady.
// Apokalipsa ja czysci!

string *chca_rozwiazac_rade=({});

// Mala zmienna wykorzystywana przy logowaniu - nie powtarza sie ostatnich komunikatow w logu.
mixed *ostatni_komunikat=({0,0,0});


void wyczysc_ostatni_wynik();
int jest_radnym(string imie);
string *query_new_rada();
string *lista_osob(int jakie=WSZYSCY);
int stan_glosowania();
void umiesc_w_archiwum(mixed *podanie);
void zaloguj(string co,string imie=0,int czy_to_blad=0);
void zapisz_dane(int ktore=WSZYSTKIE_DAT);
void sprawdz_rade();

void
dodaj_historie(string imie,string hist)
{
    imie=lower_case(imie);
	
	if(!hist) return;
	
	if(!osoby[imie]) return;
	
    if(!osoby[imie][1]) osoby[imie][1]=hist;
	else osoby[imie][1]+=hist;
	
	zapisz_dane(OSOBY_DAT);
}

void
dodaj_info(string dla_kogo,string informacja)
{
   string tekst="";
   string *tab1=({});
   int d,c,k,x;
   string s1,s2;
   
   dla_kogo=lower_case(dla_kogo);
   
   if(dla_kogo=="!all")
   {
       info["!all"]=informacja;
	   return;
   }
   if(!find_player(dla_kogo))
   {
      if(!info[dla_kogo]) info[dla_kogo]=({informacja});
	  else info[dla_kogo]+=({informacja});
	  zapisz_dane(INFO_DAT);
	  return;
   }
   
   
   tekst="\n ************************************************************************ \n";

          tab1=explode(break_string(informacja,68),"\n");
          d=sizeof(tab1);
          
          for(c=0;c<d;c++)
          {
          x=1;
          s1="";
          s2="";
          for(k=0;k<(68-strlen(tab1[c]));k++)
          {
             if(x==1) s1+=" ";
             else s2+=" ";
             
             x+=1;
             if(x==3) x=1;
          }
          tekst+=" * "+s1+tab1[c]+s2+" * \n"; 
          }

   tekst+=" ************************************************************************ \n\n";
   
   set_this_player(find_player(dla_kogo));
   
   (find_player(dla_kogo))->more(tekst);
   return;
}

int
query_prawa(string czyje)
{
   string imie=lower_case(czyje);
   int a;

   if(SPECJALNE_PRAWA_DOSTEPU[imie]>LEV_NIC) return SPECJALNE_PRAWA_DOSTEPU[imie];
   
   if(!osoby[imie]) return LEV_NIC;
   
   a=osoby[imie][0];
   
   if(a==JEST_RADNYM) return LEV_RADNY;
   if(a==JEST_CZLONKIEM) return LEV_CZLONEK;
   if(member_array(a, ZA_CO_WYGNANY)!= -1) return LEV_WYGNANY;

   return LEV_NIC;
}

void
wczytaj_dane(int ktore=WSZYSTKIE_DAT)
{
    if(ktore==OSOBY_DAT || ktore==WSZYSTKIE_DAT) osoby=restore_map(OSOBY);
    if(ktore==GLOSOWANIE_DAT || ktore==WSZYSTKIE_DAT) glosowanie=restore_map(GLOSOWANIE)["glosowanie"];
    if(ktore==WYNIK_DAT || ktore==WSZYSTKIE_DAT)      wynik=restore_map(WYNIK);
    if(ktore==WYWAL_DAT || ktore==WSZYSTKIE_DAT)    do_wywalenia=restore_map(WYWAL);
    if(ktore==INFO_DAT || ktore==WSZYSTKIE_DAT)       info=restore_map(EXTRA_INFO);
}

void
zapisz_dane(int ktore=WSZYSTKIE_DAT)
{
    if(ktore==OSOBY_DAT || ktore==WSZYSTKIE_DAT) save_map(osoby, OSOBY);
    if(ktore==GLOSOWANIE_DAT || ktore==WSZYSTKIE_DAT) save_map((["glosowanie":glosowanie]), GLOSOWANIE);
    if(ktore==WYNIK_DAT || ktore==WSZYSTKIE_DAT)      save_map(wynik, WYNIK);
    if(ktore==WYWAL_DAT || ktore==WSZYSTKIE_DAT)    save_map(do_wywalenia, WYWAL);
    if(ktore==INFO_DAT || ktore==WSZYSTKIE_DAT)       save_map(info, EXTRA_INFO);
}

mixed *wczytaj_podanie(string imie)
{
    string plik;
    int kat;
    mixed *pod;

    imie=lower_case(imie);

    if(file_size(P_NOWE + imie + ".o")>0) kat=NOWE_P;
    else if(file_size(P_AKTUALNE + imie + ".o")>0) kat=AKTUALNE_P;
    else if(file_size(P_ODRZUCONE + imie + ".o")>0) kat=ODRZUCONE_P;
    else if(file_size(P_ZAAKCEPTOWANE + imie + ".o")>0) kat=ZAAKCEPTOWANE_P;
    else return 0;

    switch(kat)
    {
       case NOWE_P: plik=P_NOWE + imie;
                    break;
       case AKTUALNE_P: plik=P_AKTUALNE + imie;
                    break;
       case ODRZUCONE_P: plik=P_ODRZUCONE + imie;
                    break;
       case ZAAKCEPTOWANE_P: plik=P_ZAAKCEPTOWANE + imie;
                    break;
       default: plik=0;
                break;
    }

    pod=restore_map(plik)["podanie"];

    pod[0]=kat;

    return pod;
}

void
usun_podania(string imie)
{
    rm(P_NOWE + imie + ".o");
    rm(P_AKTUALNE + imie + ".o");
    rm(P_ODRZUCONE + imie + ".o");
	rm(P_ZAAKCEPTOWANE + imie + ".o");
}

void
zapisz_podanie(mixed *podanie)
{
    string plik;
    int kat=podanie[0];
    int a,b;

    usun_podania(podanie[1]);

    switch(kat)
    {
       case NOWE_P: plik=P_NOWE + podanie[1];
                    break;
       case AKTUALNE_P: plik=P_AKTUALNE + podanie[1];
                    break;
       case ODRZUCONE_P: plik=P_ODRZUCONE + podanie[1];
                    break;
       case ZAAKCEPTOWANE_P: plik=P_ZAAKCEPTOWANE + podanie[1];
                    break;
       default: plik=0;
                break;
    }

    if(kat=ZAAKCEPTOWANE_P && file_size(plik)>0) umiesc_w_archiwum(wczytaj_podanie(podanie[1]));

    save_map((["podanie":podanie]), plik);
}

/*
 * jakie_poparcie - 1: poparcie radnego
 *                - 2: poparcie zwyklego czlonka
 */
 
void
poprzyj_podanie(object kto,string imie,int jakie_poparcie)
{
    mixed *pod;
    imie=lower_case(imie);
		
	pod=wczytaj_podanie(imie);
	
	if(!pod)
	{
	   kto->catch_msg("Osoba o imieniu " + capitalize(imie)+" nie oczekuje poparcia!\n");
	   return;
	}

	if(pod[0]!=AKTUALNE_P)
	{
	   kto->catch_msg("Osoba o imieniu " + capitalize(imie)+" nie oczekuje poparcia!\n");
	   return;
	}	

	if(jakie_poparcie==1)
	{

	    if(member_array(kto->query_real_name(),pod[2])!=-1)
		{
	       kto->catch_msg("Mozesz tylko raz udzielic poparcia jednej osobie!\n");
		   return;
		}
/*
		if(query_prawa(kto->query_real_name())<LEV_RADNY)
		{
		   kto->catch_msg("Nie jestes radnym, nie masz prawa udzielic takiego poparcia!\n");
		   return;
		}
*/
		pod[2]+=({kto->query_real_name()});
	}
	else
	{
        if(member_array(kto->query_real_name(),pod[3])!=-1)
		{
	       kto->catch_msg("Mozesz tylko raz udzielic poparcia jednej osobie!\n");
		   return;
		}
		if(query_prawa(kto->query_real_name())<LEV_CZLONEK)
		{
		   kto->catch_msg("Nie nie masz prawa nikogo popierac!\n");
		   return;
		}
		pod[3]+=({kto->query_real_name()});	
	}
	
	zapisz_podanie(pod);
	
	kto->catch_msg("Wlasnie " + kto->koncowka("wyraziles","wyrazilas")+" swoje poparcie dla osoby o imieniu " + capitalize(imie)+"!\n");
	
	return;
}

void
umiesc_w_archiwum(mixed *podanie)
{
    string zapis;
    string skad;
    int kat,a,b;

    kat=podanie[0];

    switch(kat)
    {
        case NOWE_P: skad="nowych";
                     break;
        case AKTUALNE_P: skad="aktualnych";
                     break;
        case ODRZUCONE_P: skad="odrzuconych";
                     break;
        case ZAAKCEPTOWANE_P: skad="zaakceptowanych";
                     break;
        default: skad="nieokreslonych";
    }

    zapis= "Podanie - przeniesione z kategorii podan " + skad + " w "+ctime(time(),1)+".\n";

    b=sizeof(podanie[2]);

    if(b>0)
      {
         zapis+="W momencie przeniesienia mialo poparcie nastepujacych radnych:";
         for(a=0;a<b;a++) zapis+=" "+capitalize(podanie[2][a])+",";
         zapis+="\b.\n";
      }

    b=sizeof(podanie[3]);

    if(b>0)
      {
         zapis+="W momencie przeniesienia mialo poparcie nastepujacych czlonkow:";
         for(a=0;a<b;a++) zapis+=" "+capitalize(podanie[3][a])+",";
         zapis+="\b.\n";
      }

    zapis+="Podanie zostalo napisane w " + ctime(podanie[5],1)+".\n";

    zapis+=podanie[4]+"\n\n";

    write_file(P_ARCHIWALNE+podanie[1],zapis);

    rm(P_NOWE + podanie[1] + ".o");
    rm(P_AKTUALNE + podanie[1] + ".o");
    rm(P_ODRZUCONE + podanie[1] + ".o");
    rm(P_ZAAKCEPTOWANE + podanie[1] + ".o");
}

void
wczytaj_z_archiwum(object dla_kogo,string imie)
{
  if(query_prawa(dla_kogo->query_real_name())<LEV_RADNY)
   {
       dla_kogo->catch_msg("Nie masz prawa czytac podan!\n");
       return;
   } 
   if(!imie)
   {
       dla_kogo->catch_msg("Musisz podac jakies imie!\n");
	   return;
   }
    if(file_size(P_ARCHIWALNE+imie)>0)
      {
         dla_kogo->more(read_file(P_ARCHIWALNE+imie));	  
         return;
      }
	  
  dla_kogo->catch_msg("Nie ma takiego podania w archiwum...\n");  
}

void
przeczytaj_podanie(object komu,string kogo)
{
    string tekst;
    string kat;
    mixed *pod;
    int a,b;

   if(query_prawa(komu->query_real_name())<LEV_RADNY)
   {
       komu->catch_msg("Nie masz prawa czytac podan!\n");
       return;
   }

    kogo=lower_case(kogo);

    pod=wczytaj_podanie(kogo);

    if(!pod)
    {
       komu->catch_msg("Nie ma podania osoby o imieniu " + capitalize(kogo) + "!\n");
       return;
    }

    switch(pod[0])
    {
        case NOWE_P: kat="nowe";
                     break;
        case AKTUALNE_P: kat="aktualne";
                     break;
        case ODRZUCONE_P: kat="odrzucone";
                     break;
        case ZAAKCEPTOWANE_P: kat="zaakceptowane";
                     break;
        default: kat="nieokreslone";
    }

    tekst= "\nAutor podania: "+capitalize(kogo)+".\nPodanie znajduje sie w kategorii '"+kat+"'. Zostalo napisane w "+ctime(pod[5])+".\n";

    if(sizeof(pod[2])>0)
       {
          tekst+="Kandydatura autora zostala poparta przez nastepujacych radnych:";
          b=sizeof(pod[2]);
          for(a=0;a<b;a++) tekst+=" "+capitalize(pod[2][a])+",";
          tekst+="\b.\n";
       }
     if(sizeof(pod[3])>0)
       {
          tekst+="Autor podania zostal poparty przez nastepujacych czlonkow:";

          b=sizeof(pod[3]);
          for(a=0;a<b;a++) tekst+=" "+capitalize(pod[3][a])+",";
          tekst+="\b.\n";
       }

    tekst+="Tresc podania:\n";
    tekst+=pod[4]+"\n";

    komu->more(tekst);

    return;
}

void
przesun_podanie(object kto,string czyje,string gdzie)
{
   mixed *pod;
   int kat=0;
   string nap="W DZIWNYM MIEJSCU!!! ZGLOS BLAD";

   gdzie=lower_case(gdzie);
   czyje=lower_case(czyje);

   if(query_prawa(kto->query_real_name())<LEV_RADNY)
   {
       kto->catch_msg("Nie masz prawa segregowac podan!\n");
       return;
   }

   pod=wczytaj_podanie(czyje);

   if(!pod)
   {
       kto->catch_msg("Nie ma podania osoby o imieniu " + capitalize(czyje)+", wiec nie mozesz go nigdzie umiescic...\n");
       return;
   }

   if(pod[0]!=NOWE_P && pod[0]!=AKTUALNE_P && pod[0]!=ODRZUCONE_P)
   {
       kto->catch_msg("Podania mozesz przenosic jedynie z kategorii podan nowych, aktualnych i odrzuconych!\n");
	   return;
   }
   
   switch(gdzie)
   {
      case "w aktualnych":
      case "w kategorii aktualne":
      case "podanie w aktualnych":
      case "podanie w kategorii aktualne": kat=AKTUALNE_P;
                                           nap="w kategorii podan aktualnych";
           break;
      case "w odrzuconych":
      case "w kategorii odrzucone":
      case "podanie w odrzuconych":
      case "podanie w kategorii odrzucone": kat=ODRZUCONE_P;
                                            nap="w kategorii podan odrzuconych";
           break;      
      default: kat=0;
   }

   if(!kat)
   {
       kto->catch_msg("Mozesz umieszczac podania jedynie w kategoriach 'aktualne' i 'odrzucone'. Aby umiescic podanie w archiwum, nalezy je 'usunac'. W pozostalych kategoriach podania nie moga byc umieszczane w ten sposob.\n");
       return;
   }

   pod[0]=kat;

   zapisz_podanie(pod);

   kto->catch_msg("Podanie osoby o imieniu " + capitalize(czyje)+" zostalo umieszczone " +nap+".\n");

   return;
}

void
usun_podanie(object kto,string imie)
{
   mixed *pod=wczytaj_podanie(lower_case(imie));
   int kat;
   string skad;

   if(query_prawa(kto->query_real_name())<LEV_RADNY)
   {
       kto->catch_msg("Nie masz prawa usuwac podan!\n");
       return;
   }

   if(!pod)
   {
       kto->catch_msg("Nie ma podania osoby o imieniu "+capitalize(lower_case(imie))+"!\n");
       return;
   }

   kat=pod[0];

    switch(kat)
    {
        case NOWE_P: skad="nowych";
                     break;
        case AKTUALNE_P: skad="aktualnych";
                     break;
        case ODRZUCONE_P: skad="odrzuconych";
                     break;
        case ZAAKCEPTOWANE_P: skad="zaakceptowanych";
                     break;
        default: skad="nieokreslonych";
    }

   umiesc_w_archiwum(pod);

   kto->catch_msg("Podanie zostalo usuniete z kategorii podan " + skad+" i umieszczone w archiwum.\n");
   return;
}

int
czas_powstania(string dir, string arg1, string arg2)
{
   if (file_time(dir+arg1)<file_time(dir+arg2)) return -1;
   if (file_time(dir+arg1)==file_time(dir+arg2)) return (arg1<arg2?-1:1);
   if (file_time(dir+arg1)>file_time(dir+arg2)) return 1;
}

void
listuj_podania(object komu, int jakie)
{
    string kat;
    string kats;
    string *lista;
	int a,b;
	string napis;

    switch(jakie)
    {
        case NOWE_P:          kat=P_NOWE;
                              kats="nowe";
                              break;
        case AKTUALNE_P:      kat=P_AKTUALNE;
                              kats="aktualne";
                              break;
        case ODRZUCONE_P:     kat=P_ODRZUCONE;
                              kats="odrzucone";
                              break;
        case ZAAKCEPTOWANE_P: kat=P_ZAAKCEPTOWANE;
                              kats="zaakceptowane";
                              break;
        case ARCHIWALNE_P:    kat=P_ARCHIWALNE;
                              kats="archiwalne";
                              break;
        default:              kat=P_NOWE;
                              kats="nowe";
     }

     lista=get_dir(kat);
     if(!sizeof(lista))
       {
          komu->catch_msg("Nie ma ani jednego podania w kategorii '"+kats+"'.\n");
          return;
       }
     lista=sort_array(lista,&czas_powstania(kat));
	
	 b=sizeof(lista);
	
	napis="W tej chwili w kategorii '"+kats+"' sa podania nastepujacych osob:\n";
	
	if(jakie!=ARCHIWALNE_P) for(a=0;a<b;a++) napis+=(capitalize(lower_case(lista[a])[0..(strlen(lista[a])-3)])+(strlen(lista[a])<=9?"\t":"") +"\t" + ctime(file_time(kat+lista[a]))+"\n");
	else for(a=0;a<b;a++) napis+=(capitalize(lower_case(lista[a]))+(strlen(lista[a])<=9?"\t":"") +"\t" + ctime(file_time(kat+lista[a]))+"\n");

    komu->catch_msg(napis+"\n");
	return;
}

/*
 * Funkcja listuje katalogi podan.
 */

void
przeglada_podania(object kto, string str)
{
   int co=-1;

   if(query_prawa(kto->query_real_name())<LEV_RADNY)
   {
         kto->catch_msg("Nie masz prawa niczego przegladac!\n");
         return;
   }
   if(!str)
   {
       kto->catch_msg("Co chcesz przejrzec? Podania czy archiwum?\n");
       return;
   }
   if(str=="podania")
   {
        kto->catch_msg("Jakie podania chcesz przejrzec? Nowe, aktualne, odrzucone czy zaakceptowane?\n");
        return;
   }
   if(str=="nowe podania") co=NOWE_P;
   else if(str=="aktualne podania") co=AKTUALNE_P;
   else if(str=="odrzucone podania") co=ODRZUCONE_P;
   else if(str=="zaakceptowane podania") co=ZAAKCEPTOWANE_P;
   else if(str=="archiwum") co=ARCHIWALNE_P;

   if(co!=-1)
      {
        listuj_podania(kto,co);
        return;
      }

   kto->catch_msg("Co chcesz przejrzec? Podania czy archiwum?\n");

   return;
}

/*
 * Funkcja zwraca informacje o czlonkach w postaci tablicy
 *  Parametr okresla, jakie osoby maja zostac uwzglednione
 */

string *lista_osob(int jakie=WSZYSCY)
{
    string *tablica=({});
    int a,sz;
    mixed ind, war;
     
	     ind = m_indices(osoby); // Pomiedzy tymi dwoma intrukcjami, nie
	     war = m_values(osoby); // powinno byc zadnych dzialan na mappingu.

   sz=sizeof(ind);

   for(a=0;a<sz;a++)
      {
	    if(osoby[ind[a]][0]==JEST_RADNYM || osoby[ind[a]][0]==JEST_CZLONKIEM)
          if(!SECURE->exist_player(ind[a]))
            {
               osoby[ind[a]][0]=ZOSTAL_SKASOWANY;
			   zaloguj("Gracz zostal skasowany.",capitalize(ind[a]));
			   war[a][0]=ZOSTAL_SKASOWANY;
			   zapisz_dane(OSOBY_DAT);
            }
			
          if(jakie==WSZYSCY || war[a][0]==jakie || (jakie==AKTYWNI && (war[a][0]==JEST_RADNYM || war[a][0]==JEST_CZLONKIEM)) )
           {
              tablica+=({ind[a]});
           }
      }

   return tablica;
}

void
info_logowania(object dla_kogo)
{
    string tekst="";
    string s1="",s2="";
    int a,b,c,d,k,x;
    string *tab=({});
    string *tab1=({});


    if(dla_kogo->query_wiz_level() && dla_kogo->query_real_name()!=OPIEKUN_GILDII) return;
       // Czarodziejom wiesci nie wyswietlamy, no moze poza jednym ;-)

   tekst="\n ************************************************************************ \n";

   tab=info[dla_kogo->query_real_name()];

   b=sizeof(tab);

   for(a=0;a<b;a++)
      {
          tab1=explode(break_string(tab[a],68),"\n");
          d=sizeof(tab1);
          
          for(c=0;c<d;c++)
          {
          x=1;
          s1="";
          s2="";
          for(k=0;k<(68-strlen(tab1[c]));k++)
          {
             if(x==1) s1+=" ";
             else s2+=" ";
             
             x+=1;
             if(x==3) x=1;
          }
          tekst+=" * "+s1+tab1[c]+s2+" * \n"; 
          }
      }

   if(info["!all"]!=0)
   {
          tab1=explode(break_string(info["!all"],68),"\n");
          d=sizeof(tab1);
          
          for(c=0;c<d;c++)
          {
          x=1;
          s1="";
          s2="";
          for(k=0;k<(68-strlen(tab1[c]));k++)
          {
             if(x==1) s1+=" ";
             else s2+=" ";
             
             x+=1;
             if(x==3) x=1;
          }
          tekst+=" * "+s1+tab1[c]+s2+" * \n"; 
          }
   }

   tekst+=" ************************************************************************ \n\n";

   info[dla_kogo->query_real_name()]=0;
   
   if(b>0 || info["!all"]!=0) dla_kogo->more(tekst);
   
   zapisz_dane(INFO_DAT);
}

void
create_object()
{
    setuid();
    seteuid(getuid());

    ustaw_nazwe(({ "gildia", "gildia", "gildia", "gildia", 
        "gildia", "gildia" }), allocate(6));

    wczytaj_dane();  //Bez parametru=wszystkie dane (bo chcemy odswiezyc wszystkie dane)

    add_name("gildia");
    add_pname("gildia");
    set_long("Ten opis nie powinien Ci sie nigdy pojawic. Skontaktuj sie " +
        "z jakims archem.\n");
    
    set_no_show();
    set_no_show_composite(1);

    add_prop(OBJ_M_NO_DROP,     "Poloz co?\n");
    add_prop(OBJ_M_NO_GIVE,     "Daj co komu?\n");
    add_prop(OBJ_M_NO_TELEPORT, 1);
    add_prop(OBJ_M_NO_STEAL,    1);
    add_prop(OBJ_M_NO_SELL,     1);
    add_prop(OBJ_M_NO_BUY,      1);

    remove_prop(OBJ_I_WEIGHT);
    remove_prop(OBJ_I_VOLUME);
    remove_prop(OBJ_I_VALUE);
	
	sprawdz_rade();
}

void
usun_obiekt_nieobecnego_gracza(object kogo)
{
    kogo->remove_object();
}

object
obiekt_gracza(string imie)
{
   object gracz;

   imie=lower_case(imie);

   if (SECURE->exist_player(imie))
    {
   if (objectp(gracz = find_player(imie)));
   else
    {
        gracz = SECURE->finger_player(imie);

        set_alarm(20.0, 0.0, "usun_obiekt_nieobecnego_gracza", gracz);

        // Skasujemy obiekcik odtworzonego z secura gracza po 20 sekundach - nie za duzo,
        //  ale zeby NA PEWNO wszystko co moze z tego skorzystac skonczylo juz prace na
        //  uzyskanym z tej funkcji obiekcie, ktory przeciez usuniemy.
    }

   return gracz;
   }

   if(osoby[imie]!=0) osoby[imie][0]=10; // To znaczy, ze gracz zostal skasowany...

   return 0;
}

string
konc(string imie,string napM,string napZ)
{
   object gracz;
   string nap=napM; // Chyba lepiej zeby zwracalo dla meskiej niz '0'....

   if(objectp(gracz=obiekt_gracza(imie)))
   {
      if(!gracz->query_gender()) nap=napM;
	  else nap=napZ;
   }

   return nap;
}

void
wyczysc_ostatni_komunikat()
{
    ostatni_komunikat=({0,0,0});
	return;
}

/*
 * Funkcja logujaca.
 * Jesli ostatni /3/ argument to 1, zapis bedzie skierowany do logu bledow.
 * Jesli bedzie to 0, albo go nie bedzie, zostanie toto skierowane do logu ogolnego.
 */

void
zaloguj(string co,string imie=0,int czy_to_blad=0)
{
  string plik;
  string str;

  if(sizeof(ostatni_komunikat)<3) ostatni_komunikat+=({0,0,0});

  if(!czy_to_blad) plik=OGOLNY_LOG;
  else plik=BLEDY;

  str=co;
  if(imie) str+=": "+imie+",";
  str+=" "+ctime(time(),1)+"\n";

  // Nie powtarzamy komunikat jesli sa takie same co chwile, np. przy guildtellu
  if(ostatni_komunikat[0]==co && ostatni_komunikat[1]==imie && ostatni_komunikat[2]==czy_to_blad) return;

  ostatni_komunikat[0]=co;
  ostatni_komunikat[1]=imie;
  ostatni_komunikat[2]=czy_to_blad;

  write_file(plik, str);
  
  // Po 3 sekundach komunikat moze sie powtorzyc...
  set_alarm(3.0, 0.0, "wyczysc_ostatni_komunikat");
}

void
informuj_grupe(string informacja,int kogo=AKTYWNI)
{
   string *lista=lista_osob(kogo);
   int a,b;

   b=sizeof(lista);

   for(a=0;a<b;a++)
   {
       dodaj_info(lista[a],informacja);
   }
}

mixed zwroc_osobe(string imie)
{
     return osoby[imie];
}

/*
 * 1 if OK, 0 if sth wrong!!
 */
 
int
zabron_dostepu(object kto, string imie)
{

       	 if(!osoby[imie])
	   	 {
	   	     kto->catch_msg("Osoba o imieniu " + capitalize(imie)+" nie jest czlonkiem Lesnych Elfow! Nie mozesz zabronic jej dostepu do skrzyni!\n");
	   		 return 0;
	   	 }
	   	 
	   	 if(osoby[imie][0]==JEST_RADNYM)
	   	 {
	   	    kto->catch_msg(capitalize(imie)+" jest czlonkiem rady Lesnych Elfow!\n");
	   		return 0;
	   	 }
	   	 if(osoby[imie][0]!=JEST_CZLONKIEM)
	   	 {
	   	         kto->catch_msg("Osoba o imieniu " + capitalize(imie)+" nie jest czlonkiem Lesnych Elfow! Nie mozesz zabronic jej dostepu do skrzyni!\n");
	   	 		 return 0;
		 }
		 if(osoby[imie][3]==0)
		 {
		        kto->catch_msg(capitalize(imie)+" caly czas nie ma prawa korzystac ze skrzyni!\n");
				return 0;
		 }
		 
		 osoby[imie][3]=0;
		 zapisz_dane(OSOBY_DAT);
		 
		 return 1;
}

int
zezwol_na_dostep(object kto, string imie)
{

       	 if(!osoby[imie])
	   	 {
	   	     kto->catch_msg("Osoba o imieniu " + capitalize(imie)+" nie jest czlonkiem Lesnych Elfow!\n");
	   		 return 0;
	   	 }
	   	 
	   	 if(osoby[imie][0]==JEST_RADNYM)
	   	 {
	   	    kto->catch_msg(capitalize(imie)+" jest czlonkiem rady Lesnych Elfow!\n");
	   		return 0;
	   	 }
	   	 if(osoby[imie][0]!=JEST_CZLONKIEM)
	   	 {
	   	         kto->catch_msg("Osoba o imieniu " + capitalize(imie)+" nie jest czlonkiem Lesnych Elfow!\n");
	   	 		 return 0;
		 }
		 if(osoby[imie][3]!=0)
		 {
		        kto->catch_msg(capitalize(imie)+" moze przeciez korzystac ze skrzyni!\n");
				return 0;
		 }
		 
		 osoby[imie][3]=1;
		 zapisz_dane(OSOBY_DAT);
		 
		 return 1;
}

int
jest_radnym(string imie)
{
    if(!osoby[imie]) return 0;
    if(osoby[imie][0]==JEST_RADNYM) return 1;
    return 0;
}

void
zabierz_expa(object komu,int za_co)
{
      if(member_array(za_co, ZA_CO_WYGNANY)!= -1) return; // !!!!!!!!!!!!!!!! NIE WIEM, CZY ODEJMOWAC CZY NIE.....

      komu->set_exp_combat(ftoi((8.0*itof(komu->query_exp_combat()))/10.0));
      tell_object(komu,"\nOpuszczasz Lesne Elfy i czujesz, ze opuszcza cie czesc sil...\n\n");
}

int 
wyrzuc_gracza_i_zabierz_soula(object kogo,int za_co)
{
    int i;
    object *tab;
    string str;
    string imie=kogo->query_real_name();

    if(!IS_MEMBER_LELF(kogo)) return 1;
    if(member_array(za_co, ZA_CO_WYGNANY)!= -1) // Jesli ktos zostaje wygnany, to mu soula nie usuwamy, tylko zmieniamy start.
    {
         if (kogo->query_default_start_location()== START)
         if (!kogo->set_default_start_location(IMPERIUM_DEFAULT_START))
         {    
             tell_object(kogo,"Wystapil blad zwiazany z przydzieleniem nowej lokacji"
                   +" startowej. Zglos to.\n");
             str = sprintf("Blad przydzialu lokacji startowej u %s :",imie);
             zaloguj(str,0,1);
         }
       return 1;
    }
    
    tab = deep_inventory(kogo);
        for (i=0; i<sizeof(tab); i++)
            if (tab[i]->czy_to_flet_lelfow())
                tab[i]->remove_object();

    if (kogo->query_default_start_location()== START)
         if (!kogo->set_default_start_location(IMPERIUM_DEFAULT_START))
         {    
             tell_object(kogo,"Wystapil blad zwiazany z przydzieleniem nowej lokacji"
                   +" startowej. Zglos to.\n");
             str = sprintf("Blad przydzialu lokacji startowej u %s :",imie);
             zaloguj(str,0,1);
         }

    if (!kogo->clear_guild_stat(SS_RACE))
    {
        str = sprintf("Clear_guild_stat zwrocilo 0 u %s:",imie);
        zaloguj(str,0,1);
    } 

    if (kogo->remove_guild_race())
    {
        kogo->remove_cmdsoul(SOUL);
        kogo->update_hooks();
        return 1;
    }

    tell_object(kogo,"Wystapil jakis blad i nie jestes w stanie opuscic Lesnych Elfow.\n"+
          "Najlepiej skontaktuj sie z kims z czarodziei.\n");

    str = sprintf("Remove_guild_race zwrocilo 0 u %s :",imie);
    zaloguj(str,0,1);
    return 0;
}

void
sprawdz_rade()
{
     string *radni=({});
     string *rada_new=({});
	 string historia;
     int a,b,sz;

     radni=lista_osob(JEST_RADNYM);

     sz=sizeof(radni);

     if(sz<MIN_LICZBA_RADNYCH) // Jesli radnych jest mniej niz ustawa przewiduje rozpoczynamy nowe glosowanie i kazemy pokoikowi z urna ja wystawic.
       {
           glosowanie[0]=time();
           wyczysc_ostatni_wynik();
           (LPATH+"pokoj_glosowan.c")->sprawdz_czy_wystawic_urne();
           return;
       }

    if(sz<LICZBA_RADNYCH)
    {
	  b=LICZBA_RADNYCH-sz;
	  
      rada_new=query_new_rada()[0..(b-1)];
	
      for(a=0;a<b;a++)
        {
           osoby[rada_new[a]][0]=JEST_RADNYM;
           dodaj_info(rada_new[a],"W wyniku zmniejszenia liczby radnych "+obiekt_gracza(rada_new[a])->koncowka("zostales mianowany","zostalas mianowana") + " czlonkiem Rady Lesnych Elfow.\n");
		   historia="W "+ctime(time(),1)+" w wyniku zmniejszenia liczby radnych "+konc(rada_new[a],"zostal","zostala")+" czlonkiem rady Lesnych Elfow.\n";
		   dodaj_historie(rada_new[a],historia);
        }

      zapisz_dane(OSOBY_DAT);
      return;
   }
}

void
wyrzuc_z_gildii(object kogo,int za_co)
{
     string historia;
	 string hist=0;
     string komentarz,log;
     string imie=kogo->query_real_name();
	 
	 if(!osoby[imie]) return;

     switch(za_co)
     {
         case ZABIL_NPCA : komentarz = "Za zabicie mieszkanca Athel-Loren zostajesz wygnan" + kogo->koncowka("y","a") + " z gildii Lesnych Elfow!\n";
                           log = "Wygnany za zabicie npca z Athel";
						   hist= konc(imie,"zostal wyrzucony","zostala wyrzucona") + " za zabojstwo mieszkanca Athel-Loren.\n";
                           break;
         case ZABIL_LELFA : komentarz = "Za zabojstwo innego Lesnego Elfa zostajesz wygnan" + kogo->koncowka("y","a") + " z gildii Lesnych Elfow!\n";
                           log = "Wygnany za zabicie Lesnego Elfa";
						   hist= konc(imie,"zostal wyrzucony","zostala wyrzucona") + " za zabojstwo innego Lesnego Elfa.\n";
                           break;
         case ZABIL_ZWIERZE : komentarz = "Za zaatakowanie czczonego przez Lesne Elfy zwierzecia zostajesz usuniet" + kogo->koncowka("y","a") + " z gildii Lesnych Elfow!\n";
                           log = "Wygnany za zaatakowanie czczonego zwierzecia";
						   hist= konc(imie,"zostal wyrzucony","zostala wyrzucona") + " za zaatakowanie czczonego przez Lesne Elfy zwierzecia.\n";
                           break;
         case ZOSTAL_WYRZUCONY : komentarz = "Na wniosek rady Lesnych Elfow zostajesz wygnan" + kogo->koncowka("y","a") + " z gildii Lesnych Elfow!\n";
                           log = "Wygnany na wniosek rady";
						   // Tu nie ustawiamy hist, bo odpowiedni wpis jest dodawany w funkcji ktora radny wyrzuca.
                           break;
         case SAM_ODSZEDL : komentarz = "Opuszczasz gildie Lesnych Elfow...\n";
                           log = "Sam opuscil gildie";
						   hist= konc(imie,"sam wyrzekl","sama wyrzekla") + " sie swego pochodzenia, odrzucajac wszelkie zwiazki z Lesnymi Elfami.\n";
                           break;
         case ZMIENIL_RASE : komentarz = "Jako ze juz nie jestes " + kogo->koncowka("elfem","elfka") + ", zostajesz usuniet" + kogo->koncowka("y","a") + " z gildii Lesnych Elfow!\n";
                           log = "Usuniety po zmianie rasy";
						   hist= konc(imie,"zostal wyrzucony","zostala wyrzucona") + " w ramach zmiany rasy.\n";
                           break;
         default : komentarz = "Z niejasnych powodow zostajesz usuniet" + kogo->koncowka("y","a") + " z gildii Lesnych Elfow! Zglos reklamacje!\n";
                   log = "USUNIETY BEZ POWODU!!!!!";
				   hist= konc(imie,"zostal wyrzucony","zostala wyrzucona") + " z niejasnych powodow...\n";
                   break;
     }

     if(za_co==SAM_ODSZEDL && member_array(za_co, ZA_CO_WYGNANY)!= -1)
     {
          komentarz="Wyrzekasz sie swych korzeni zwiazanych z tym miastem i tym lasem...\n";
          log="Wyrzekl sie Loren po wygnaniu";
     }

     if(wyrzuc_gracza_i_zabierz_soula(kogo,za_co))
     {
	        historia="W "+ctime(time(),1)+" "+hist;
	    
            if(hist!=0) dodaj_historie(kogo->query_real_name(),historia);
			
            tell_object(kogo,komentarz);
            zabierz_expa(kogo,za_co);
            zaloguj(log,imie);
            osoby[imie][0]=za_co;
            sprawdz_rade();
            zapisz_dane(OSOBY_DAT);
     }
}

void
morderstwo(object kogo,object kto)
{
    string str;
    
        tell_object(kogo,"\nZabil cie czlonek Lesnych Elfow!!\n\n");
        str = sprintf("%s zabity przez %s :",kogo->query_real_name(), kto->query_real_name());
        zaloguj(str);

        wyrzuc_z_gildii(kto,ZABIL_LELFA);
}

void
nowy_czlonek(object kto)
{
    string imie=kto->query_real_name();
    string historia;
    int a,b;
    mixed *pod=wczytaj_podanie(imie);

    pod[0]=ZAAKCEPTOWANE_P;
    zapisz_podanie(pod);

    if(!osoby[imie]) osoby[imie]=({JEST_CZLONKIEM,"",1,1}); // Dodajemy nowego czlonka ! :-)
    else
    {
       osoby[imie][0]=JEST_CZLONKIEM;
    }

    historia="W "+ctime(time(),1)+" "+kto->koncowka("zostal przyjety","zostala przyjeta")+" na wniosek radnych: ";
    b=sizeof(pod[2]);
    for(a=0;a<b;a++) historia+=capitalize(pod[2][a])+", ";

    b=sizeof(pod[3]);

    if(b>0)
     {
        historia+="\b\b ";
        historia+="i przy poparciu czlonkow: ";
        for(a=0;a<b;a++) historia+=capitalize(pod[3][a])+", ";
     }

     historia+="\b\b.\n";

     dodaj_historie(imie,historia);

    zapisz_dane(OSOBY_DAT);
}

void
logowanie(object kto)
{
    string rasa;
	int statusik;
	string imie=kto->query_real_name();

    if(kto->query_real_name()==OPIEKUN_GILDII)
	{
	    info_logowania(kto);
		return;
	}

    if(!osoby[imie])
      {
          tell_object(kto,"Uwaga !!! Prawdopodobnie zostaly utracone twoje dane zwiazane z gildia Lesnych Elfow !! Natychmiast zglos to !!!\n");
          write_file(BLEDY,sprintf("Blad!! Brak danych dotyczacych tej osoby !! - %s %s\n",imie,ctime(time())));
          return;
      }

    statusik=osoby[imie][0];

    if(statusik==JEST_WIZEM) return;

    if(kto->query_wiz_level())
       {
         write("\n--------------------------------------------------------------\n"
               + "Jako, ze " + kto->koncowka("wstapiles","wstapilas") + " do krainy Niesmiertelnych, "
             + "nie mozesz juz\n"
             + "dluzej byc czlonkiem gildii. Zostajesz " +  kto->koncowka("usuniety","usunieta")
             + "\nz listy czlonkow gildii. Pomimo skreslenia z listy, nadal masz"
             + "\ndostep do gildiowych emocji.\n"
               + "--------------------------------------------------------------\n\n");
         osoby[imie][0]=JEST_WIZEM;
		 dodaj_historie(imie,"W "+ctime(time(),1)+" "+konc(imie,"wstapil","wstapila")+" do krainy Niesmiertelnych.\n");
         zaloguj("Zostal wizem",imie);
         return;
       }

    rasa = kto->query_race_name();
    if ( (rasa != "elf") && (rasa != "elfka"))
    {
        osoby[imie][0]=ZMIENIL_RASE;
        wyrzuc_z_gildii(kto, ZMIENIL_RASE);
	return;
    }

    if(do_wywalenia[imie]!=0)
	{
	    wyrzuc_z_gildii(kto, do_wywalenia[imie]);
		do_wywalenia[imie]=0;
		zapisz_dane(WYWAL_DAT);
		return;
    }

   // if(statusik!=JEST_CZLONKIEM && statusik!=JEST_RADNYM) wyrzuc_z_gildii(kto, statusik);
   if(statusik!=JEST_CZLONKIEM && statusik!=JEST_RADNYM) return;

    (LPATH+"pokoj_glosowan.c")->sprawdz_czy_wystawic_urne();
	
	info_logowania(kto);
}

int
czy_mozna_wyrzucic(object kto,string imie)
{
   int statusik;
   
   if(query_prawa(kto->query_real_name())<LEV_RADNY)
   {
       kto->catch_msg("Nie masz prawa nikogo wyrzucac!\n");
       return 0;
   }

   imie=lower_case(imie);

   if(!osoby[imie])
     {
        kto->catch_msg("Osoba o imieniu " + capitalize(imie) + " nigdy nie byla, ani nie jest, czlonkiem Lesnych Elfow, wiec nie mozesz jej wyrzucic!\n");
        return 0;
     }

   statusik=osoby[imie][0];

   switch(statusik)
    {
       case JEST_CZLONKIEM : kto->catch_msg(capitalize(imie) + " jest naszym czlonkiem.\n");
                             return 1;
       case JEST_RADNYM    : kto->catch_msg(capitalize(imie) + " jest czlonkiem rady! Nie mozesz " + konc(imie,"go","jej") + " wyrzucic!\n");
                             return 0;
       default : kto->catch_msg(capitalize(imie) + " nie jest w tej chwili czlonkiem Lesnych Elfow, wiec nie mozesz " + konc(imie,"go","jej") +" wyrzucic!\n");
                 return 0;
    }

  return 0;
}

string
sprawdz_osobe(string imie)
{
   string str;
   mixed *pod;
   string kat;
   string co=0;
   object ktos;
   string tekst;

   imie=lower_case(imie);
   pod=wczytaj_podanie(imie);

   if(!osoby[imie] && !pod && file_size(P_ARCHIWALNE+imie)<=0) return "\nOsoba o imieniu " + capitalize(imie)+" nigdy nie byla czlonkiem Lesnych Elfow, ani nie skladala nigdy podan.\n\n";
   if(!osoby[imie] && !pod) return "\nOsoba o imieniu "+capitalize(imie)+" nigdy nie byla czlonkiem Lesnych Elfow, ale jej podanie znajduje sie w archiwum.\n\n";
   
  if(sizeof(pod)>0)
  {
   switch(pod[0])
    {
        case NOWE_P: kat="nowe";
                     break;
        case AKTUALNE_P: kat="aktualne";
                     break;
        case ODRZUCONE_P: kat="odrzucone";
                     break;
        case ZAAKCEPTOWANE_P: kat="zaakceptowane";
                     break;
        default: kat="nieokreslone";
    }

   if(!osoby[imie] && file_size(P_ARCHIWALNE+imie)<=0) return "\nOsoba o imieniu " + capitalize(imie)+" nigdy nie byla czlonkiem Lesnych Elfow, ale zlozyla podanie, ktore teraz znajduje sie w czesci '"+kat+"'.\n\n";
   if(!osoby[imie]) return "\nOsoba o imieniu " + capitalize(imie)+" nigdy nie byla czlonkiem Lesnych Elfow, ale zlozyla podania, ktore teraz znajduja sie w czesci '"+kat+"' oraz w archiwum.\n\n";

   }
   
   switch(osoby[imie][0])
   {
       case JEST_CZLONKIEM: co="jest naszym czlonkiem.";
                            break;
       case JEST_RADNYM   : co="jest czlonkiem Rady Lesnych Elfow.";
                            break;
       case JEST_WIZEM    : co=konc(imie,"byl czlonkiem Lesnych Elfow, jednak wstapil do krainy Niesmiertelnych i juz nim nie jest.","byla czlonkiem Lesnych Elfow, jednak wstapila do krainy Niesmiertelnych i juz nim nie jest.");
                            break;
       case ZABIL_NPCA    : co=konc(imie,"byl czlonkiem Lesnych Elfow, lecz zostal wyrzucony za zabojstwo mieszkanca Athel-Loren. Jest elfim renegatem.","byla czlonkiem Lesnych Elfow, lecz zostala wyrzucona za zabojstwo mieszkanca Athel-Loren. Jest elfia renegatka.");
                            break;
       case ZABIL_LELFA   : co=konc(imie,"byl czlonkiem Lesnych Elfow, lecz zostal wyrzucony za zabojstwo innego Lesnego Elfa. Jest elfim renegatem.","byla czlonkiem Lesnych Elfow, lecz zostala wyrzucona za zabojstwo innego Lesnego Elfa. Jest elfia renegatka.");
                            break;
       case ZABIL_ZWIERZE : co=konc(imie,"byl czlonkiem Lesnych Elfow, lecz zostal wyrzucony za zaatakowanie czczonego przez Lesne Elfy zwierzecia. Jest elfim renegatem.","byla czlonkiem Lesnych Elfow, lecz zostala wyrzucona za zaatakowanie czczonego przez Lesne Elfy zwierzecia. Jest elfia renegatka."); 
                            break;
       case ZOSTAL_WYRZUCONY : co=konc(imie,"byl naszym czlonkiem, jednak zostal wyrzucony na wniosek rady. Jest elfim renegatem.","byla naszym czlonkiem, jednak zostala wyrzucona na wniosek rady. Jest elfia renegatka.");
                            break;
       case SAM_ODSZEDL   : co=konc(imie,"byl Lesnym Elfem, lecz dobrowolnie wyrzekl sie swego pochodzenia.","byla Lesnym Elfem, lecz dobrowolnie wyrzekla sie swego pochodzenia.");
                            break;
       case ZMIENIL_RASE  : co=konc(imie,"byl czlonkiem Lesnych Elfow, jednak zmienil rase i musial na opuscic.","byla czlonkiem Lesnych Elfow, jednak zmienila rase i musiala nas opuscic.");
                            break;
       case ZOSTAL_SKASOWANY : co="zostal skasowany.";
                            break;
    }

  if(osoby[imie][0]==JEST_CZLONKIEM || osoby[imie][0]==JEST_RADNYM)
  {

    ktos=obiekt_gracza(imie);

    str = jaki_tytul(ktos);


   if(jest_radnym(imie))
   {
     if(ktos->query_gender()) str += ", Starsza Rady Lesnych Elfow";
      else str += ", Starszy Rady Lesnych Elfow";
   }

   tekst="\n"+capitalize(imie)+", "+str+".\n"; // Nie mowimy, ze jest w gildii/radzie, bo widac po tytule.

   if(osoby[imie][3]==1) tekst+="W tej chwili moze "+konc(imie,"on","ona")+" korzystac ze skrzyni w normalny sposob.\n";
   else tekst+="W tej chwili ma "+konc(imie,"on","ona")+" zabroniony pelny dostep do skrzyni.\n";
  }
  else tekst="\n"+capitalize(imie)+" "+co+"\n";
   if(!pod && !(file_size(P_ARCHIWALNE+imie)>0)) tekst+="Nie ma zadnych podan napisanych przez "+konc(imie,"niego","nia")+".\n";
   else if(sizeof(pod)>0 && !(file_size(P_ARCHIWALNE+imie)>0)) tekst+=konc(imie,"Jego","Jej")+" podanie znajduje sie teraz w kategorii '"+kat+"'.\n";
   else if(!pod) tekst+=konc(imie,"Jego","Jej")+" podanie znajduje sie w tej chwili w archiwum.\n";
   else tekst+=konc(imie,"Jego","Jej")+" podania znajduja sie w tej chwili w kategorii '"+kat+"' oraz w archiwum.\n";

   tekst+=osoby[imie][1]+"\n";

   return tekst;
}

string
czlonkowie_rady()
{
  string s;
  string *rada=lista_osob(JEST_RADNYM);
  int i,a;
  
  i=sizeof(rada);

  s="Aktualni czlonkowie rady to :\n";
  
  if(i==0) s="W tej chwili nie ma zadnych czlonkow rady Lesnych Elfow!\n";
  
  for(a=0;a<i;a++) s+=rada[a]+", ";

  s+="\b\b.\n";

  if(i!=0) s=s+".\nWszelkie prosby i pytania nalezy kierowac do czlonkow rady listownie, podania o przyjecie do gildii nalezy zas skladac u Yandela.\n";

  return s;
}

void
wywal(object kto,string czy_tak, string imie)
{
   object kogo;
   string historia;

   imie=lower_case(imie);
   czy_tak=lower_case(czy_tak);

   if(czy_tak!="tak")
   {
      kto->catch_msg("Zaniechano.\n");
      return;
   }

   if(!osoby[imie])
   {
      kto->catch_msg("Nie moge usunac osoby o imieniu " + capitalize(imie)+"!! Jest to prawdopodobnie BLAD i nalezy go zglosic!\n");
      return;
   }

   kogo=find_player(imie);

   if(kogo!=0)
     {
        wyrzuc_z_gildii(kogo,ZOSTAL_WYRZUCONY);
     }
   else
     {
         do_wywalenia[imie]=ZOSTAL_WYRZUCONY; //Zostanie wywalony po nastepnym zalogowaniu sie
     }

   kto->catch_msg(capitalize(imie)+" nie jest juz czlonkiem Lesnych Elfow!\n");

   historia="W "+ctime(time(),1)+" "+konc(imie,"zostal wyrzucony","zostala wyrzucona")+" przez "+kto->query_name(PL_BIE)+".\n";
   
  dodaj_historie(imie,historia);
   
   zapisz_dane(OSOBY_DAT);
   
   return;
}

string kto_rozwiazuje()
{
   string s="W tej chwili nastepujacy radni wnioskowali o rozwiazanie rady: ";
   int a,b=sizeof(chca_rozwiazac_rade);

   if(b>0)
   {      
      for(a=0;a<b;a++) s+=capitalize(chca_rozwiazac_rade[a])+", ";
      s+="\b\b.\n";
      return s;
    }
   
   return "W tej chwili nie ma nikogo, kto wnioskowalby o rozwiazanie rady.\n";
}

void
rozwiaz_rade(object kto,string czy_tak)
{
   string imie=kto->query_real_name();
   int a,b;
   string nap;

   czy_tak=lower_case(czy_tak);

   if(query_prawa(imie)<LEV_RADNY)
   {
       kto->catch_msg("Nie masz do tego prawa!!\n");
       return;
   }

   if(stan_glosowania()!=0)
   {
       kto->catch_msg("Nie mozesz tego uczynic podczas glosowania!!\n");
	   return;
   }

   if(czy_tak!="tak")
   {
       kto->catch_msg("Zaniechano.\n");
       return;
   }

   if(member_array(imie, chca_rozwiazac_rade)!= -1)
   {
       kto->catch_msg("Juz raz " + kto->koncowka("wnioskowales","wnioskowalas")+" o rozwiazanie rady. Nie mozesz tego uczynic ponownie!\n");
       return;
   }

   chca_rozwiazac_rade+=({imie});
   
   kto->catch_msg(kto_rozwiazuje());

   if(sizeof(chca_rozwiazac_rade) >= MIN_RADNYCH_ROZWIAZUJE)
   {
     kto->catch_msg("Rada zostaje rozwiazana!\n");
     nap="Rozwiazali rade: ";
     b=sizeof(chca_rozwiazac_rade);
     for(a=0;a<b;a++) nap+=chca_rozwiazac_rade[a]+" ";
     zaloguj(nap);
     
     informuj_grupe("Rada zostala rozwiazana i w zwiazku z tym rozpoczynaja sie kolejne wybory!",AKTYWNI);
     zapisz_dane(INFO_DAT);
   }

}

void
zrezygnuj(object kto,string czy_tak)
{
   string historia;
   czy_tak=lower_case(czy_tak);

    // To tak jakby wiz o wyzszych niz radni uprawnieniach probowal 'zrezygnowac'
	// Wywala sie a to nieladnie chociaz nic nei szkodzi ;-))
	// tzn. wywalal sie, a dzieki temu tu ponizej sie nei wywala..
   if(query_prawa(kto->query_real_name())!=LEV_RADNY)
   {
       kto->catch_msg("Alez ty nie jestes czlonkiem Rady Lesnych Elfow!\n");
       return;
   }
   if(osoby[kto->query_real_name()][0]!=JEST_RADNYM)
   {
       kto->catch_msg("Alez ty nie jestes czlonkiem Rady Lesnych Elfow!\n");
       return;
   }

   if((sizeof(lista_osob(JEST_RADNYM))-1)<MIN_LICZBA_RADNYCH)
   {
        kto->catch_msg("Nie mozesz odejsc z rady gildii, gdyz zostaloby w niej zbyt malo radnych...\n");
        return;
   }

   if(czy_tak!="tak")
   {
          kto->catch_msg("Zaniechano. Nadal jestes czlonkiem Rady Lesnych Elfow.\n");
          return;
   }

   osoby[kto->query_real_name()][0]=JEST_CZLONKIEM;
   osoby[kto->query_real_name()][2]=0; //Ze nie chce zostawac radnym przy rozpatrywaniu zastepcy teraz, jak i w przyszlosci, przed nastepnymi wyborami.

   historia="W "+ctime(time(),1)+" "+kto->koncowka("ustapil","ustapila")+" ze stanowiska radnego Lesnych Elfow.\n";
   
   dodaj_historie(kto->query_real_name(),historia);
   
   zapisz_dane(OSOBY_DAT);

   kto->catch_msg("Nie jestes juz czlonkiem Rady Lesnych Elfow...\n");

   sprawdz_rade();

   return;
}

void
dodaj_nowe_podanie(string text,object autor)
{
    mixed *podanko;
	mixed *pod2;

    podanko=({NOWE_P,autor->query_real_name(),({}),({}),text,time()});
    pod2=wczytaj_podanie(autor->query_real_name());
	
	if(!pod2)
	{
	}
	else umiesc_w_archiwum(pod2);

    zapisz_podanie(podanko);
}

void
wyczysc_ostatni_wynik()
{
    wynik=([]); // Teoretycznie czysci mapping...

    zapisz_dane(WYNIK_DAT);
}

void
zglos_kandydature(object kto)
{
    string imie=kto->query_real_name();


    if(query_prawa(kto->query_real_name())<LEV_CZLONEK)
      {
         write("Nie masz prawa kandydowac do rady!\n");
         return 0;
      }

    if(kto->query_wiz_level()>0)
      {
         write("Jako Czarodziej nie mozesz kandydowac.\n");
         return;
      }
    if(!osoby[imie])
      {
         write("Nie nalezysz przeciez do gildii Lesnych Elfow, wiec jak chcesz kandydowac na radnego?\n");
         return;
      }
    if(osoby[imie][0]!=JEST_CZLONKIEM && osoby[imie][0]!=JEST_RADNYM)
      {
         write("Nie nalezysz przeciez do gildii Lesnych Elfow, wiec jak chcesz kandydowac na radnego?\n");
         return;
      }
    if(wynik[imie]!=0)
      {
         write("Przeciez juz " + kto->koncowka("zglosiles","zglosilas")+" swoja kandydature w tych wyborach!\n");
         return;
      }

   wynik[imie]=({"!"}); // Ten wykrzyknik jest po to, zeby tablica nie byla pusta ;-)

   zapisz_dane(WYNIK_DAT);
   
   write("Zglaszasz swoja kandydature do glosowania na nowa Rade Lesnych Elfow.\n");

   return;
}

int
czy_moge_glosowac(object kto)
{
    int a,sz;
    string imie=kto->query_real_name();
    mixed ind, war;

    if(query_prawa(kto->query_real_name())<LEV_CZLONEK)
      {
         write("Nie masz prawa glosowac!\n");
         return 0;
      }

    war = m_values(wynik);

    sz=sizeof(war);

   for(a=0;a<sz;a++)
      {
          if(member_array(imie, war[a])!=-1)
            {
               write("Mozesz oddac tylko jeden glos!\n");
               return 0;
            }
      }

   return 1;
}

void
oddaj_glos(object kto,string na_kogo)
{
    string imie=kto->query_real_name();
    object osoba;

    na_kogo=lower_case(na_kogo);

    if(query_prawa(kto->query_real_name())<LEV_CZLONEK)
      {
         write("Nie masz prawa glosowac!\n");
         return;
      }
    if(imie==na_kogo)
      {
           write("Nie mozesz glosowac na siebie!\n");
           return;
      }
    if(!osoby[na_kogo])
      {
           write(capitalize(na_kogo)+" nie nalezy do gildii Lesnych Elfow!\n");
           return;
      }
    if(osoby[na_kogo][0]!=JEST_CZLONKIEM && osoby[na_kogo][0]!=JEST_RADNYM)
       {
           write(capitalize(imie)+" nie jest pelnoprawnym czlonkiem gildii!\n");
           return;
       }
    if(!wynik[na_kogo])
       {
           osoba=obiekt_gracza(na_kogo);

           write(capitalize(na_kogo)+" nie " + konc(na_kogo,"zglosil","zglosila")+" swej kandydatury, wiec nie mozesz oddac na " + konc(na_kogo,"niego","nia")+" glosu...\n");
           return;
       }

//    osoba=obiekt_gracza(na_kogo);

    wynik[na_kogo]+=({imie});

    zapisz_dane(WYNIK_DAT);

    write("Wlasnie " + kto->koncowka("oddales","oddalas")+" glos na osobe o imieniu " + capitalize(na_kogo)+".\n");

    return;
}

/*
 * Ta funkcja pobiera tablice ktora wyglada mniej wiecej tak:
 *    ({ ({"adam",3}), ({"kasia",20}), ({"bartek",1}), ({"jas",20}) })
 *  segreguje ja i oddaje w takiej postaci:
 *    ({ ({"kasia","jas"}), ({"adam"}), ({"bartek"}) })
 * - pokopane, ale takie cos mi bylo potrzebne ;-)))
 * A! Jeszcze uwzglednia, czy ten ktos ma min glosow /tutaj zwykle nie ziesci sie "bartek" z przykladu ;-)/
 *    oraz to, czy dany osobnik zyczy sobie byc radnym....
 */

mixed *segreguj_dane(mixed *stat)
{
     mixed *tab=({});
     mixed *tab1=({});
     int a,b,max=0;

     b=sizeof(stat);
     for(a=0;a<b;a++)
     {
        if(max<stat[a][1]) max=stat[a][1];
     }

     tab=allocate(max+1);  // Olewamy komorke numer 0 - numer komorki=liczba glosow

     for(a=0;a<b;a++)
     {
       if(osoby[stat[a][0]][2]==1)  //czy na pewno dana osoba chce byc radnym?
       {
        if(!tab[stat[a][1]]) tab[stat[a][1]]=({stat[a][0]});
        else tab[stat[a][1]]+=({stat[a][0]});
       }
     }

     for(a=(sizeof(tab)-1);a>(MIN_GLOSOW-1);a--)
     {
        if(tab[a]!=0) tab1+=({ tab[a] });
     }

     return tab1;
}

/*
 * Funkcja pobiera tablice zwracana przez f-kcje segreguj_dane i przerabia ja tak, ze najpierw
 * w kazdej podtablicy przelosowuje kolejnosc imion, a potem wstawia je wszystkie po kolei do 1 wymiarowej tablicy
 */

string *przelosuj_i_polacz(mixed *tab0)
{
     string *tablica=({});
     int a,b,rnd;
     int powtorz;
     string imie;

     b=sizeof(tab0);

     for(a=0;a<b;a++)
     {
        powtorz=1;

        while(powtorz)
        {
           if(sizeof(tab0[a])>0)
             {
                rnd=random(sizeof(tab0[a]));
                imie=tab0[a][rnd];
                tablica+=({imie});
                tab0[a]-=({imie});
             }
           else powtorz=0;
        }
      }

      return tablica;
}

mapping
query_wynik()
{
    return wynik;
}

string *query_new_rada()
{
    mixed *stat=({});
    mixed ind, war;
	int sz;
	int a;
     
	     ind = m_indices(wynik); // Pomiedzy tymi dwoma intrukcjami, nie
	     war = m_values(wynik); // powinno byc zadnych dzialan na mappingu.

   sz=sizeof(ind);

   for(a=0;a<sz;a++)
      {
	    if(osoby[ind[a]][0]==JEST_CZLONKIEM)
		{
          if(!SECURE->exist_player(ind[a]))
            {
               osoby[ind[a]][0]=ZOSTAL_SKASOWANY;
			   zaloguj("Gracz zostal skasowany.",capitalize(ind[a]));
			   zapisz_dane(OSOBY_DAT);
            }
		}
          // Tutaj dodajemy tylko tych, ktorzy chca byc radnymi i tylko tych, ktorzy nie sa rada w tej chwili (sa zwyklymi czlonkami)
          // jest to po to, zeby funkcja obslugiwala rowniez uzupelnianie rady
          // przy calkowitej zmienie rady to statusik radnego oraz chcenie/niechcenie bycia w radzie
          // jest czyszczona przed wywolaniem tej funkcji...
        if(osoby[ind[a]][2]==1 && osoby[ind[a]][0]==JEST_CZLONKIEM) stat+=({ ({ind[a],(sizeof(war[a])-1)}) }); //Tutaj odejmujemy 1, bo przy zglaszaniu kandydata dostal jeden glos gratisowy, zgloszony jakby przez osobe o mieniu "!" bodajze ;-)
      }

   return przelosuj_i_polacz(segreguj_dane(stat));
}

string *make_rada(string *new,string *old)
{
   string *tab;

   old-=new; //Odejmujemy te glosy, ktore sa w nowej i byly w starej radzie, zeby 2 miejsca nie byly zajete przez 1 osobe.

   tab=new+old;

   if(sizeof(tab)>LICZBA_RADNYCH) return tab[0..(LICZBA_RADNYCH-1)];
   return tab;
}

void
zakoncz_glosowanie()
{
    string *rada_old=lista_osob(JEST_RADNYM);
    string *rada_new=({});
    string *wszyscy=lista_osob(AKTYWNI);
    string *rada=({});
	string historia;
    int a,b;

    b=sizeof(wszyscy);        

    for(a=0;a<b;a++)
    {
        osoby[wszyscy[a]][2]=1; // Tu ustawiamy, ze kazdy chce byc radnym (1-chce, 0 - nie chce)
    }

    b=sizeof(rada_old);

    for(a=0;a<b;a++)
       {
          osoby[rada_old[a]][0]=JEST_CZLONKIEM;
       }

    rada_new=query_new_rada();

    rada=make_rada(rada_new, rada_old);

    b=sizeof(rada);

    for(a=0;a<b;a++)
       {
          osoby[rada[a]][0]=JEST_RADNYM;
          dodaj_info(rada[a],"W wyniku ostatniego glosowania na Rade Lesnych Elfow "+konc(rada_new[a],"zostales mianowany","zostalas mianowana") + " jej czlonkiem.\n");
		  historia="W "+ctime(time(),1)+" "+konc(rada[a],"zostal wybrany","zostala wybrana")+" na czlonka rady Lesnych Elfow.\n";
		  dodaj_historie(rada[a],historia);    
       }

     zapisz_dane(WSZYSTKIE_DAT); // Zapisujemu... wszystko, bo duzo sie zmienilo...           
}

/*
 * Funkcja zwraca 0, jesli to nie jest okres wyborow, 1 jesli to pora zglaszania kandydatur
 *  i 2 jesli to pora oddawania glosow.
 */

int
stan_glosowania()
{
    mixed ind;
 	int sz;

     if((time()-glosowanie[0])>(CO_ILE_GLOSOWANIE*24*60*60))
       {
           glosowanie[0]=time();
           wyczysc_ostatni_wynik();
       }

     if((time()-glosowanie[0])>((DLUGOSC_ZGLASZANIA + DLUGOSC_WYBIERANIA)*24*60*60) && glosowanie[1])
       {
           glosowanie[1]=0;
           zapisz_dane(GLOSOWANIE_DAT);
           zapisz_dane(WYNIK_DAT);
           zakoncz_glosowanie();
           info["!all"]=0;
           zapisz_dane(INFO_DAT);
           return 0;
       }

     if((time()-glosowanie[0])<(DLUGOSC_ZGLASZANIA*24*60*60))
     {
         info["!all"]="UWAGA! Rozpoczelo sie wielkie glosowanie na czlonkow nowej Rady Lesnych Elfow. W tej chwili przyjmowane sa jeszcze kandydatury, ktore nalezy zglaszac przy urnie w gildii Lesnych Elfow!";
         return 1;
     }
 
     if((time()-glosowanie[0])<((DLUGOSC_ZGLASZANIA + DLUGOSC_WYBIERANIA)*24*60*60))
       {
           if(!glosowanie[1])
             {
			    ind = m_indices(wynik);
				sz=sizeof(ind);
				
			 	  if(!sz) // Tutaj male zabezpieczenie - jesli nikt sie nie zglosil, to przedluzamy etap zglaszania tak, jakby dopiero teraz sie zaczal.
			 		{
					    glosowanie[0]=time();
						return 1;
					}
					
                 glosowanie[1]=1;
                 zapisz_dane(GLOSOWANIE_DAT);
             }
            info["!all"]="UWAGA! Zglaszanie kandydatur dobieglo konca i przebiega teraz najwazniejsza czesc wyborow. Glosy mozna oddawac do urny w gildii Lesnych Elfow!";
            return 2;
        }

      info["!all"]=0;
      return 0;
}

void
remove_object()
{
   zapisz_dane(WSZYSTKIE_DAT);
   ::remove_object();
}

void
usun_skasowanych_graczy(string imie=0)
{
   int a,sz;
   mixed ind;
     
  if(stringp(imie))
  {
        imie=lower_case(imie);
    
	    if(!(sizeof(osoby[imie])>0))
		{
		    return;
		}
		if(osoby[imie][0]!=JEST_CZLONKIEM && osoby[imie][0]!=JEST_RADNYM) return;
         if(!SECURE->exist_player(imie))
              {
                   osoby[imie][0]=ZOSTAL_SKASOWANY;
				   zaloguj("Gracz zostal skasowany.",capitalize(imie));
              }
  }
  else
  {
  	ind = m_indices(osoby);
  
     sz=sizeof(ind);
  
     for(a=0;a<sz;a++)
        {
            if(!SECURE->exist_player(ind[a]) && (osoby[ind[a]][0]==JEST_CZLONKIEM || osoby[ind[a]][0]==JEST_RADNYM))
              {
                 osoby[ind[a]][0]=ZOSTAL_SKASOWANY;
				 zaloguj("Gracz zostal skasowany.",capitalize(imie));
              }
        }
  }
  zapisz_dane(OSOBY_DAT);
  return;
}