/*
 *  Carrier pigeon.
 *  This one can bring a message from one player to another. This will
 *  (ofcourse) take a while. Maybe it's a compensation for the loss of
 *  the 'tell' command.                                  Tricky, dec 1991
 *
 *  Slight modifications by Elessar, March 1992.
 *  Nick was here, May 1992. ** Keep on smiling **
 *  Nick again, March
 *  Mercade, September 14 1994. Removed certain confirmation of non-receipt.
 *  Wersja polska - Elvaron.
 *  Alvin - 25 kwietnia 1999; Poprawki jezykowe, uwzglednianie bb,
 *			      duszenie sie golebia w plecaku.
 */

#pragma save_binary

inherit "/d/Imperium/std/zwierze";

#include <wa_types.h>
#include <stdproperties.h>
#include <macros.h>

/* The delay between sending the message and the receiving of it. */
#define SLOWLY random(40) + 40

/* The number of times the pigeon will carry a message. */
#define TIMES   3
#define UNKNOWN "unknown"
#define CZAS_DUSZENIA	300.0	/* Golab dusi sie po 5 minutach */

string gMessage, gWho,dWho, gSender, gLocation;
int gUsage;
int gDuszenieAlarm;

void
create_creature()
{
    ustaw_odmiane_rasy(({"golab","golebia","golebiowi","golebia","golebiem","golebiu"}),
        ({"golebie","golebi","golebiom","golebie","golebiami","golebiach"}),
        PL_MESKI_NOS_ZYW,0);

    dodaj_nazwy(({"golab pocztowy","golebia pocztowego",
                  "golebiowi pocztowemu","golebia pocztowego",
                  "golebiem pocztowym","golebiu pocztowym"}),
        ({"golebie pocztowe","golebi pocztowych",
          "golebiom pocztowym","golebie pocztowe",
          "golebiami pocztowymi","golebiach pocztowych"}),
        PL_MESKI_NOS_ZYW);

   ustaw_shorty(({"bialy golab pocztowy","bialego golebia pocztowego",
                  "bialemu golebiowi pocztowemu","bialego golebia pocztowego",
                  "bialym golebiem pocztowym","bialym golebiu pocztowym"}),
        ({"biale golebie pocztowe","bialych golebi pocztowych",
          "bialym golebiom pocztowym","biale golebie pocztowe",
          "bialymi golebiami pocztowymi","bialych golebiach pocztowych"}),
        PL_MESKI_NOS_ZYW);
    dodaj_przym("pocztowy","pocztowi");
    dodaj_przym("bialy","biali");

    set_long("Spogladasz na bialego golebia pocztowego, siedzacego na twoim " +
        "ramieniu. Poprzez niego mozesz 'wyslac' wiadomosc do dowolnej osoby. "
#if TIMES > 1
        + "Mozesz rowniez 'wyslac odpowiedz'. "
#endif
        + "Jesli golebiowi z jakis powodow nie uda sie dostarczyc wiadomosci"
        + " mozesz zawsze sprobowac 'wyslac go ponownie'.\n");
    gUsage = 0;
    add_prop(CONT_I_WEIGHT, 350);
    add_prop(CONT_I_VOLUME, 350);
    add_prop(OBJ_I_NO_GET, 0);
    add_prop(OBJ_I_NO_DROP, 0);
    add_prop(LIVE_I_NEVERKNOWN, 1);
    add_prop(NPC_M_NO_ACCEPT_GIVE, " nie jest w stanie wziac niczego innego, " +
             " niz tylko wiadomosci.\n");

    set_attack_unarmed(1, 5, 5, W_IMPALE, 100, "dziobem");
    set_hitloc_unarmed(1, ({ 1, 1, 1 }), 100, "korpus");
}

void
init_living()
{
    add_action("do_send", "wyslij");
}

string 
trans_przyp(int poczatkowy, int koncowy, string imie)
{
    object *gracze = users();
    int a = 0;
 
   while(a<sizeof(gracze)) {

    if(gracze[a]->query_real_name(poczatkowy)==imie) 
       return gracze[a]->query_real_name(koncowy);
     a++;
   }
 return "";
}

int
resend()
{
    object target;

    if (!gSender || !gWho || this_player() != find_player(gSender))
    {
        notify_fail("Nie mozesz wyslac ponownie, jezeli pierwej nie wyslesz golebia.\n");
        return 0;
    }

    if (target = find_player(gWho))
    {
        write("Wysylasz golebia aby sprobowal dostarczyc jeszcze raz wiadomosc.\n");
        move("/d/Imperium/obj/golebnik.c");
        set_alarm(itof(SLOWLY), 0.0, "deliver");
        return 1;
    }

    notify_fail("Golab jest zbyt wyczerpany aby dostarczyc te wiadomosc.\n");
    return 0;
}


int
do_send(string str)
{
  string who;
    string known, intro, remem;
    object target, tp;
    

    notify_fail("Wyslij golebia do kogos? Wyslij odpowiedz? Wyslij ponownie?\n");
    
    if (!str)
	return 0;

    if(str == "ponownie")
	return resend();

    sscanf(str,"golebia do %s", who);
 
    if ((!who || who == "") && str != "odpowiedz")
	return 0;

    tp = this_player();
    if (tp != environment())
        return 0;

    if (gUsage >= TIMES)
    {
        write("Golab jest zbyt wyczerpany aby dostarczyc kolejna wiadomosc.\n");
        return 1;
    }

    if (environment(tp)->query_prop(ROOM_I_INSIDE))
    {
        write("Aby wyslac golebia musisz wyjsc na otwarty teren.\n");
        return 1;
    }
    
    dWho = who;
    gWho = trans_przyp(PL_DOP, PL_MIA, dWho);
    if (str == "odpowiedz")
    {
        /* Has a message been written before? */
        if (!gUsage)
        {
            write("Nie otrzymal" + this_player()->koncowka("es", "as") +
		" zadnej wiadomosci, aby moc wyslac odpowiedz.\n");
            return 1;
        }
        gWho = gSender;
    }

 /* If a player knows the name of another player, let him send the pigeon. */
    gSender = lower_case(tp->query_name(PL_MIA));
    target = find_player(gWho);

 /* It is useless to write a message to someone who isn't in the game. */

    /* Save the location of the player. Only if s/he stays, there will be
     * confirmation.
     */
    if (objectp(environment(tp)))
    {
        gLocation = file_name(environment(tp));
    }
    else
    {
        gLocation = UNKNOWN;
    }

    write("Napisz tresc wiadomosci.\nWpisz ~q aby przerwac edycje, lub **, aby " +
	"zakonczyc edycje i wyslac wiadomosc.\n");
    gMessage = "";
    write("-->");
    input_to("write_more");
    return 1;
}

void
send_mail()
{
    if (gMessage == "")
    {
        write("Wpisywanie wiadomosci przerwane.\n");
        return;
    }
    
    write("Zwijasz wiadomosc w rulonik i przyczepiasz do nogi golebia.\n");
    saybb(QCIMIE(this_player(), PL_MIA) + " zwija wiadomosc w rulonik i przyczepia" +
        " do nogi " + QIMIE(this_object(), PL_DOP) + ".\n");

    tell_room(environment(this_player()), QCIMIE(this_object(), PL_MIA) +
        " zaczyna machac skrzydlami, gwaltownie wznosi sie do gory i odlatuje w nieznane.\n");

 /* Move the object to a temporary room */
    move("/d/Imperium/obj/golebnik.c");
    set_alarm(itof(SLOWLY), 0.0, "deliver");
    return;
}

void
write_more(string str)
{
    if (str == "**")
    {
        send_mail();
        return;
    }

    if (str == "~q")
    {
        write("Pisanie wiadomosci przerwane.\n");
        return;
    }   

    gMessage += (str + "\n");
    write("-->");
    input_to("write_more");
    return;
}



void
deliver()
{
    object target, message;

/* Does our initial target still exist? We check for the objectpointer and
 * we also check the room. If the target is inside, he does not exist as
 * far as the pigeon is concerned.
 */
    target = find_player(gWho);
    if (objectp(target) && (environment(target)->query_prop(ROOM_I_INSIDE)))
    {
        target = 0;
    }

/* If the target is not found, the sender is tracked. If s/he moved, the
 * pigeon is not able to re-locate him/her.
 */
    if (!target)
    {
        target = find_player(gSender);
        if ((gLocation == UNKNOWN) ||
            (objectp(target) && (file_name(environment(target)) != gLocation)))
        {
            target = 0;
        }

        if (!objectp(target))
        {
            remove_object();
            return;
        }
    }

 /* Go to the target */
    move(target);
    tell_room(environment(target), "Niespodziewanie, posrod trzepotu " +
	"skrzydel nadlatuje " + QIMIE(this_object(), PL_MIA) + ".\n");
    tell_roombb(environment(target), QCIMIE(this_object(), PL_MIA) +
	" laduje na ramieniu " + QIMIE(target, PL_DOP) + ".\n", target, target);
	
    if (target == find_player(gSender))
    {
	tell_object(target, capitalize(short(target, PL_MIA)) + " laduje na " +
	    "twoim ramieniu - najwyrazniej powrocil nie mogac znalezc " +
	    "adresata.\n");
	return;
    }

    tell_object(target, capitalize(short(target, PL_MIA)) + " laduje na " +
	"twoim ramieniu. Przy jego nodze znajduje sie zwinieta wiadomosc.\n");

    message = clone_object("/d/Imperium/obj/message");
    message->set_message(gMessage);
    message->set_sender(gSender);
    message->move(target);
    gUsage++;
    if (gUsage >= TIMES)
        set_alarm(10.0, 0.0, "return_home");
}

void
return_home()
{
    object room;
    if (living(room = environment()))
        room = environment(room);
    tell_room(room, QCIMIE(this_object(), PL_MIA) +
        " zaczyna machac skrzydlami, gwaltownie wznosi sie do gory i odlatuje w nieznane.\n");
    remove_object();
}

public void
uduszenie()
{
    int closed;
    object env;
    
    env = environment(this_object());
    
    if (env->query_prop(CONT_I_CLOSED))
    {
	closed = 1;
	env->remove_prop(CONT_I_CLOSED);
    }
    
    query_hp();
    set_hp(0);
    do_die(environment(this_object()));
    if (closed)
	env->add_prop(CONT_I_CLOSED, 1);
}

public void
enter_env(object dest, object old)
{
    ::enter_env(dest, old);
    if (!dest->id("plecak", PL_MIA))
	return;

    gDuszenieAlarm = set_alarm(CZAS_DUSZENIA, 0.0, &uduszenie());
}

public void
leave_env(object from, object to)
{
    ::leave_env(from, to);
    if (!gDuszenieAlarm)
	return;
    
    remove_alarm(gDuszenieAlarm);
    gDuszenieAlarm = 0;
}
