/* Hi there! To jest obiekt symulujacy cala mechanike mostu. Zajmuje
 * sie jego podnoszeniem, opuszczaniem, opisywaniem wygladu i
 * jeszcze paroma innymi rzeczami. Wykorzystuja go pliki:
 * mosts.c, mostn.c, most.c i wszystkie inne, ktore maja z mostem
 * cokolwiek wspolnego.
 * Pliku tego nie nalezy bron boze inheritowac, nalezy sie do niego odwolywac
 * bezposrednio z innych. Mozna to robic np: MECHANIZM ( z mith.h )->... jak ja
 * lub find_object(OBJPATH+"maszyna.c")->...
 * Autor Mithandir. Reszta informacji na moscie.
 *	Poniewaz zasada dzialania moze byc troche niezrozumiala
 *	( nie ma to jak przejrzyste kodowanie ) postanowilem tutaj troche
 *		wyjasnic:
 *	void komunikat(string opis) wyswietla opis we wszystkich lokacjach 
 *			nalezacych do tablicy *lokacje. Sluzy to do 
 *			wywietlania komunikatow o podnoszeniu i opuszczaniu 
 *			mostu wszystkim, ktorzy to widza.
 *	string opis_lamp() wyswietla opis lamp ( w zaleznosci od dnia/nocy i 
 *			zapalonych/zgaszonych).
 *	void zwal_graczy() zwala graczy most.c do mostn.c kiedy most podnosi
 *			sie ponad 45 st.
 * 	void podnies_most() podnosi most. Wywolywane przez poruszenie dzwigni.
 *               Po uplywie 30 sekund most ponownie zaczyna sie opuszczac.
 *
 *	void opusc_most() opuszcza most. Jw.
 *
 *	string krotki_opis() zwraca zainteresowanym lokacjom krotki opis
 *		mostu i jego aktualnego stanu.
 *	string dlugi_opis() Jw, ale dluzej, z opisem historii i wygladu.
 *	
 *	string opis_dzwigni() zwraca opis dzwigni + mozliwosci jej poruszania
 *
 *	int na_most(int skad, object kto) sprawdza, czy gracz moze wejsc na 
 *		most lub przeskoczyc rzeke. Jesli nie, to coz... Nic sie nie 
 *		dzieje. 0 - moze isc. 1 - nie moze lub skacze.
 *	void rusz_dzwignie(object kto) coz, rusza dzwignie. Chyba, ze Thomas
 *		sie sprzeciwi.
 *	int most_sie_rusza() zwraca, czy most stoi w miejscu i gdzie :
 *		0 - rusza sie, 1 - u gory, 2 - na dole
 * 
 *	Coz, pozostaje tylko zapewnic, ze sam tego tez nie rozumiem :))
 *
 *  Przerobione przez Tanisa, zeby wspolpracowalo z dylizansem Nuln-Loren
 *
 */

#include "mith.h"
inherit "/std/object.c";


int lampy_zapalone=0;
int kat_podniesienia=0;
int jak_sie_rusza=0;
int ile_razy_byl_podnoszony=0;
string *lokacje=({NPATH+"mosts.c",NPATH+"mostn.c",NPATH+"most.c"});

int czy_most_zarezerwowany=0;

void opusc_most();

void
komunikat(string opis)
{
        int i=sizeof(lokacje)-1;
        for (;i!=0;i--) tell_room(find_object(lokacje[i]),opis);
}

void
komunikat1(string opis,object kto)
{
        int i=sizeof(lokacje)-1;
        for (;i!=0;i--) tell_room(find_object(lokacje[i]),opis,kto);
}

string pora_dnia(){return "noc";}

int
zapal_lampy()
{
	if (lampy_zapalone) return 0;
        lampy_zapalone=1;
        return 1;
}

int
zgas_lampy()
{
	if (!lampy_zapalone) return 0;
        lampy_zapalone=0;
        return 1;
}

int
czy_lampy_zapalone()
{
        return lampy_zapalone;
}
string
opis_lamp()
{
        return lampy_zapalone ? "Na moscie wisza zapalone lampy, sluzace "
               +"za sygnal dla nadplywajacych lodzi. " :
               "Wiszace na moscie lampy sa zgaszone. " + pora_dnia()=="noc" ?
               "Cos sie musialo przytrafic Thomasowi, gdyz zapalanie ich na "
              +"noc nalezy do jego obowiazkow. " : "";
}


void
zwal_graczy()
{
        object cos; // przechowuje tymczasowo odnosnik do
                    //obiektu spadajacego.
        object *co_na_moscie=all_inventory(find_object(NPATH+"most.c"));
        object *kto_na_moscie=FILTER_PLAYERS(co_na_moscie);
        int i;
        co_na_moscie-=kto_na_moscie;

        for (i=0;i<sizeof(kto_na_moscie);i++)
        {
                cos=kto_na_moscie[i];
                        komunikat1(QCIMIE(cos,PL_MIA)
                           +" zsuwa sie pod wplywem sily ciezkosci "
                           +"z mostu.\n",cos);
                        cos->catch_msg("Most osiagnal takie nachylenie, "
                             +"ze niezaleznie od swojej woli "
                             +"zsuwasz sie w dol.\n");
                        cos->move_living ("M",NPATH+"mostn.c",1);
        }

        for (i=0;i<sizeof(co_na_moscie);i++)
        {
                cos=co_na_moscie[i];
                        komunikat1(capitalize(cos->query_nonmet_name(PL_MIA))
                              +" spada z mostu.\n",cos);
                        cos->move (NPATH+"mostn.c");
        }
}

int
czy_thomas_ma_cos_przeciwko(object kto)
{
        object *co_przed_mostem=all_inventory(find_object(NPATH+"mostn.c"));
        int i=sizeof(co_przed_mostem)-1;
        object thomas;
        for (;i>=0;i--)
        if (co_przed_mostem[i]->query_real_name()=="thomas")
           thomas = co_przed_mostem[i];
        return thomas->rusza_dzwignie(kto);
}

void
podnies_most()
{
        jak_sie_rusza=1;
        kat_podniesienia+=9;
        if (kat_podniesienia==90)
        {
                komunikat("Most stanal dokladnie w pionie. rzeka jest "
                    +"teraz zeglowna, ale az to nie ma polaczenia z "
                    +"drugim brzegiem.\n");
                set_alarm (120.0,0.0,"sam_opusc_most");
                return;
        }
        if (kat_podniesienia==45)
        {
        komunikat("Most uniosl sie juz do polowy, uniemozliwiajac "
           +"jakakolwiek komunikacje z sasiednim brzegiem.\n");
        zwal_graczy();
        }
        set_alarm (4.0,0.0,"podnies_most");
}

	
void
opusc_most()
{

      {
        jak_sie_rusza=0;
        kat_podniesienia-=9;
        if (kat_podniesienia==0)
        {
                komunikat("Most jest teraz calkowicie spuszczony, "
                    +"blokujac rzeke dla lodzi, ale umozliwiajac pieszym "
                    +"i pojazdom przekroczenie rzeki.\n");
                return;
        }
        if (kat_podniesienia==45)
        {
        komunikat("Most zostal juz spuszczony do polowy, tak ze z "
             +"polnocnego brzegu mozna probowac przeskoczyc na druga "
             +"strone.\n");
        }
        set_alarm (2.0,0.0,"opusc_most");
     }
}

void sam_opusc_most()
{	
    if(jak_sie_rusza)
	opusc_most();
}

string
krotki_opis()
{
        string opis;

        switch (kat_podniesienia)
        {
                case 90 : opis = "Most jest podniesiony pionowo do gory. ";
                   break;
                case 1..45 : opis = jak_sie_rusza ? "Most sie powoli "
                   +" podnosi, ale ciagle jego koniec jest uniesiony "
                   +" niezbyt wysoko. " : " Most sie powoli opuszcza, "
                   +"juz wkrotce dotknie ziemi. ";
                   break;
                case 46..89 : opis = jak_sie_rusza ? "Most podnosi sie "
                   +"coraz wyzej, wkrotce stanie dokladnie w pionie. " :
                    "Most powoli opuszcza sie do ziemi, ale ciagle jest "
                   +"wysoko podniesiony. ";
                   break;
                case 0 : opis =  "Most jest opuszczony, blokujac zegluge "
                       +"rzeka. ";
        }
        return opis;
}

string
dlugi_opis()
{
        string opis;
        opis = " Jest to potezny, podnoszony most. W tym momencie ";
        switch (kat_podniesienia)
        {
                case 0 : opis += "most jest opuszczony, blokujac zegluge "
                       +"rzeka. ";
                       break;
                case 1..45 : opis += jak_sie_rusza ? "most sie powoli "
                   +" podnosi, ale ciagle jego koniec jest uniesiony "
                   +" niezbyt wyoko." : "most sie powoli opuszcza, "
                   +"juz wkrotce dotknie ziemi. ";
                   break;
                case 46..89 : opis += jak_sie_rusza ? "most podnosi sie "
                   +"coraz wyzej, wkrotce stanie dokladnie w pionie.\n" :
                    "most powoli opuszcza sie do ziemi, ale ciagle jest "
                   +"wysoko podniesiony.";
                   break;
                case 90 : opis += "most jest podniesiony pionowo do gory";
                   break;


        }
        opis +=" Przejscie po moscie jest mozliwe jedynie gdy jest on "
           +"opuszczony, ale od strony polnocnej mozna bez wiekszego "
           +"problemu przeskoczyc, jesli tylko koniec mostu nie jest "
           +"podniesiony zbyt wysoko.\n Most ten zostal zbudowany dawno, "
           +"dawno temu przez genialnego inzyniera, a wymyslony przez "
           +"niego mechanizm ciagle dziala. Podniesienie takiej masy "
           +"drewna i zelaza wymagalo by nadludzkiej sily, ale "
           +"wykorzystano w tym celu ruch przeplywajacej dolem wody. "
           +"Calosc dziala podobnie jak mlyn, i pozwlala jednym ruchem "
           +"znajdujacej sie na polnocnym brzegu dzwigni podniesc lub "
           +"opuscic most. " + opis_lamp() + "\n";
        return opis;
}

string
opis_dzwigni()
{
        string opis="Jest to dluga, metalowa dzwignia uruchamiajaca "
               +"mechanizm podnoszacy i opuszczajacy most.";
        if (kat_podniesienia== 90 || kat_podniesienia==0)
           opis+=" Most stoi w tym momencie nieruchomo, przesuniecie "
                 +"dzwigni spowoduje wiec jego" + (kat_podniesienia=90) ?
                 " opuszczenie." : " podniesienie.";
        else " Most sie w tym momencie rusza, wiec dzwignia jest "
             +"zablokowana i nie bedzie mozna jej uzyc, dopoki sie nie "
             +"zatrzyma.";
        opis+=" Obsluga dzwigni zajmuje sie zazwyczaj Thomas, i moze byc "
             +"bardzo zly, jelis ktos naruszy zakres jego kompetencji. "
             +"Podnosi on most tylko na cas przeplyniecia lodzi, ale "
             +"chyba nie zarabia duzo jako straznik mostu, wiec nie "
             +"pogardzi godziwym zarobkiem.\n";
        return opis;
}


int
na_most(int skad,object kto)
{
        if (kat_podniesienia==0) return 0;
        if (!skad)
        {
                kto->catch_msg("Niestety, od poludniowej strony mozna sie "
                     +"na most dostac tylko kiedy jest calkowicie "
                     +"opuszczony.\n");
                return 1;
        }
        if (kat_podniesienia<=45)
        {
                kto->catch_msg("Most jest juz podniesiony, ale jego "
                    +"koniec znajduje sie dostatecznie nisko, aby udal ci "
                    +"sie skok. Nabierasz rozpedu i ladujesz bezpiecznie "
                    +"po poludniowej stronie mostu.\n");
                tell_room(NPATH+"mostn.c", QCIMIE(kto,PL_MIA) + " Nabiera "
                    +"rozpedu i pewnie przeskakuje przerwe miedzy koncem "
                    +"mostu i poludniowym brzegiem rzeki.\n",kto);
                kto->move_living("M",NPATH+"mosts.c",0);
		tell_room(find_object(NPATH+"mosts.c"), QCIMIE(kto,PL_MIA)+
		    " bierze rozbieg i przeskakuje z mostu na te strone"
                    +"rzeki.\n",kto);
		return 1;
        }
        kto->catch_msg("Niestety most jest podniesiony zbyt wysoko, zebys "
            +"mogl go przeskoczyc. Zeby przedostac sie na druga strone "
            +"rzeki musisz poczekac, az zostanie opuszczony.\n");
        return 1;
}

void
rusz_dzwignie(object kto)
{
	if (kto->query_real_name()!="thomas" && czy_thomas_ma_cos_przeciwko(kto))
        {
        return;
        }
        if(czy_most_zarezerwowany)
        {
               kto->catch_msg("Naciskasz mocno na dzwignie, lecz ta ani drgnie. "
                   + "W tej chwili most jest czyms zablokowany, "
                   + "poczekaj chwile, a moze most sie odblokuje.\n");
               return;
        }
        if (kat_podniesienia!=90 && kat_podniesienia!=0)
        {
                kto->catch_msg("Most sie w tym momencie rusza, wiec "
                     +"dzwignia jest zablokowana. Musisz poczekac az most "
                     +"sie zatrzyma.\n");
                return;
        }
        if (kat_podniesienia==0)
        {
                kto->catch_msg("Pod naciskiem twoich rak dzwignia zmienia "
                    +"swoje polozenie.\n");
                tell_room(NPATH+"mostn.c", QCIMIE(kto, PL_MIA) + " rusza "
                    +"dzwignia.\n",kto);
                komunikat("Most zaczyna sie powoli i majestatycznie "
                    +"podnosic.\n");
                podnies_most();
                return;
        }
        else
        {
                kto->catch_msg("Powoli naciskasz stawiajaca lekki opor "
                     +"dzwignie.\n");
                tell_room(NPATH+"mostn.c", QCIMIE(kto, PL_MIA) + " rusza "
                     +"dzwignia.\n",kto);
                komunikat("Most zaczyna sie powoli opuszczac.\n");
                opusc_most();
                return;
        }
}

int
most_sie_rusza()
{
        // zwraca: 1 - most na ziemi 0 - most sie rusza
        // 2 - most podniesiony
        switch (kat_podniesienia)
        {
                case 90: return 2;
                         break;
                case 0 : return 1;
                         break;
                default: return 0;
        }
}

int
pokaz_kat()
{
        write(""+kat_podniesienia);
        return 1;
}

void
odblokuj_most()
{
  czy_most_zarezerwowany=0;
}

int
dylizans_czeka_przy_moscie()
{
  int ile;

  czy_most_zarezerwowany=1;

  if(kat_podniesienia==0 && jak_sie_rusza==0)
    {
      opusc_most();
      set_alarm(10.0, 0.0, "odblokuj_most");
      return 1;
    }
  if(jak_sie_rusza==1)
    {
       ile=21; // czas na opuszczenie mostu od 90 do 0 stopni
       ile=ile+((90-kat_podniesienia)/9*4); // stopnie pozostale do podniesienia * 4 sekund na kazde 9 stopni
       set_alarm((itof(ile-21)+ 0.1), 0.0, "opusc_most");
       set_alarm(itof(ile+11), 0.0, "odblokuj_most");
       return (ile+1);      
    }
  if(jak_sie_rusza==0)
    {
       ile=((90-kat_podniesienia)/9*2);
       set_alarm(itof(ile+11), 0.0, "odblokuj_most");
       return (ile+1);
    }
  set_alarm(90.0, 0.0, "odblokuj_most");
  return 75;
}

int
moze_most_zarezerwowany()
{
  return czy_most_zarezerwowany;
}