#pragma save_binary
#pragma strict_types

inherit "/std/object";

#include <stdproperties.h>
#include <macros.h>
#include <ss_types.h>
#include <cmdparse.h>
#include <language.h>

string	other_room,
	door_id,
    	door_desc,
    	open_desc,
	closed_desc,
	pass_mess,
	fail_pass,
	fail_close;
string	open_mess,	
	close_mess;
string 	*fail_open;
object	other_door;	
string	*pass_commands;
int open_status;
int status_bramy;

void zamknij_brame(int ile);
void create_door();
void set_other_room(string name);
void set_door_id(string id);
void set_door_desc(string desc);
void set_open_desc(string desc);
void set_closed_desc(string desc);
void set_pass_command(mixed command);
void set_pass_mess(string mess);
void set_fail_pass(string mess);
void set_open_mess(string mess);
void set_fail_open(mixed mess);
void set_close_mess(string mess);
void set_fail_close(string mess);
void load_other_door();
static void remove_door_info(object dest);
void do_open_door(string mess);
void do_close_door(string mess);
void set_open(int i);
void set_status(int s);  //0-nic 1-otwieraja sie
int query_status();

/*
 * Function name: create_object
 * Description:   Initialize object.
 */
void 
set_status(int s)
{
  status_bramy=s;
}
int 
query_status()
{
  return status_bramy;
}
void
create_object()
{
  pass_commands = ({});
  add_prop(OBJ_I_WEIGHT, 60000);
  add_prop(OBJ_I_VOLUME, 80000);
  add_prop(DOOR_I_HEIGHT, 200); 
  add_prop(OBJ_I_NO_GET, 1);
  set_no_show();

    /*
     * Default messages.
     */
  set_open_desc("@@standard_open_desc");
  set_closed_desc("@@standard_closed_desc");
  
  set_fail_pass("@@standard_fail_pass");
    
//    set_open_command("otworz");
  set_open_mess("@@standard_open_mess1");
    set_fail_open(({"@@standard_fail_open1", "@@standard_fail_open2" }));
    
    set_close_mess("@@standard_close_mess1");
    set_fail_close("@@standard_fail_close");
    
    set_door_desc("Wyglada mocno.\n");    
    set_pass_mess("@@standard_pass_mess");
    set_open(0);
    create_door();
}

/*
 * Function name: create_door
 * Description:   Sets default names and id
 */
void
create_door()
{
}

/*
 * Function name: reset_door
 * Description:   Reset the door
 */
void
reset_door() 
{
}

void 
zamknij_brame(int ile)
{
call_out("do_close_door",ile,close_mess);
}

/*
 * Function name: reset_object
 * Description:   Reset the object
 */
nomask void
reset_object()
{

    reset_door();
}

int pass_door(string str);
int open_door();

/*
 * Function name: init
 * Description:   Initalize the door actions
 */
void
init()
{
    int i;

    ::init();
    for (i = 0 ; i < sizeof(pass_commands) ; i++)
      add_action(pass_door, check_call(pass_commands[i]));

}

/*
 * Function name: pass_door
 * Description:   Pass the door.
 * Arguments:	  arg - arguments given
 */
int
pass_door(string arg)
{
  int dexh;

  if (!other_door)
    load_other_door();

  /*
   * The times higher a player can be and still get through
   */
  dexh = 2 + (this_player()->query_stat(SS_DEX) / 25);

  if (open_status)
    {
      /* Lets say we arbitrarily can bend as dexh indicates.
       * For something else, inherit and redefine.
       */
      if ((int)this_player()->query_prop(CONT_I_HEIGHT) > 
	    query_prop(DOOR_I_HEIGHT) * dexh) 
	{
	  write("Jestes zbyt duz" + 
	        this_player()->koncowka("y", "a", "y") + 
	        " i za malo zreczn" + 
	        this_player()->koncowka("y", "a", "y") +
	        ", zeby sie przecisnac przez " + short(PL_BIE));
	  return 1;
	}
      else if ((int)this_player()->query_prop(CONT_I_HEIGHT) > 
	       query_prop(DOOR_I_HEIGHT))
	{
	  write("Z wielkim trudem przeciskasz sie przez " + short(PL_BIE) + 
	        ".\n");
	  saybb(QCIMIE(this_player(), PL_MIA) + " z wielkim trudem "
	        + "przeciska sie przez " + this_object()->short(PL_BIE)
	        + ".\n");
	}
      
      this_player()->move_living(check_call(pass_mess), other_room);
    }
  else
    write(check_call(fail_pass));

  return 1;
}

/*
 * Function name: open_door
 * Description:   Open the door.
 * Arguments:	  arg - arguments given
 */
int
open_door()
{
  mixed drzwi_ob;

  if (!other_door)
    load_other_door();

  if (!open_status)
    {
      do_open_door(open_mess);
      other_door->do_open_door(check_call(open_mess));
      call_out("zamknij_brame",15);
      call_other(other_door,"zamknij_brame",15);
    }
  else
    write(check_call(fail_open[0]));

  return 1;
}

void
do_open_door(string mess)
{
  object env;

  env = environment(this_object());
  env->change_my_desc(check_call(open_desc));
  if (strlen(mess))
    tell_roombb(env, mess);
  
  open_status = 1;
}

/*
 * Function name: close_door
 * Description:   Close the door.
 * Arguments:	  arg - arguments given
 */

void
do_close_door(string mess)
{
    object env;

    env = environment(this_object());
    env->change_my_desc(check_call(closed_desc));
    if (strlen(mess))
	tell_roombb(env, mess);
    open_status = 0;
    set_status(0);
}
void
set_open(int i)	{ open_status = i; }

/*
 * Function name: query_open
 * Description:   Query the open status of the door.
 */
int
query_open() { return open_status; }



/*
 * Function name: set_door_desc
 * Description:   Set the long description of the door
 */
void
set_door_desc(string desc) { door_desc = desc; }

/*
 * Function name: query_door_desc
 * Description:   Query the long description of the door
 */
string
query_door_desc() { return door_desc; }

/*
 * Function name: set_open_desc
 * Description:   Set the description of the door when open
 */
void
set_open_desc(string desc) { open_desc = desc; }

/*
 * Function name: query_open_desc
 * Description:   Query the open description of the door
 */
string
query_open_desc() { return open_desc; }

/*
 * Function name: set_closed_desc
 * Description:   Set the description of the door when closed
 */
void
set_closed_desc(string desc) { closed_desc = desc; }

/*
 * Function name: query_closed_desc
 * Description:   Query the description of the door when closed
 */
string
query_closed_desc() { return closed_desc; }

/*
 * Function name: set_pass_command
 * Description:   Set which command is needed to pass the door
 */
void
set_pass_command(mixed command)
{
    if (pointerp(command))
	pass_commands = command;
    else
	pass_commands = ({ command });
}

void
set_pass_mess(string mess)
{
    pass_mess = mess;
}

/*
 * Function name: query_pass_command
 * Description:   Query what command lets you pass the door
 */
string *
query_pass_command() { return pass_commands; }

/*
 * Function name: set_fail_pass
 * Description:   Set messaged when failing to pass the door.
 */
void
set_fail_pass(string mess) { fail_pass = mess; }

/*
 * Function name: query_fail_pass
 * Description:   Query message when failing to pass the door
 */
string
query_fail_pass()		{ return fail_pass; }





void
set_open_mess(string mess) { open_mess = mess; }


string query_open_mess() { return open_mess; }

void	
set_fail_open(mixed mess)	
{ 
    if (pointerp(mess))
	fail_open = mess;
    else
	fail_open = ({ mess });
}

string	*
query_fail_open() { return fail_open; }


void
set_close_mess(string mess) { close_mess = mess; }


string query_close_mess()		{ return close_mess; }


void
set_fail_close(string mess) { fail_close = mess; }


string
query_fail_close() { return fail_close; }


void
set_other_room(string name) { other_room = name; }


string
query_other_room() { return other_room; }











void	
set_door_id(string id) 		
{ 
    id = "--" + id + "--";
    door_id = id; 

}
string
query_door_id()	{ return door_id; }


object
query_other_door()
{
    if (!other_door)
	load_other_door();

    return other_door;
}


void
load_other_door()
{
    string *door_ids;
    object *doors;
    int pos;

    seteuid(getuid());


    if (!strlen(other_room) || other_door)
	return;


    if (!find_object(other_room))
    {
    other_room->teleledningsanka();
	if (!find_object(other_room))
	{
	    write("Blad w ladowaniu drugiej strony drzwi: " + other_room + ".\n");
	    remove_door_info(environment(this_object()));
	    remove_object();
	    return;
	}
    }

    door_ids = (string *)other_room->query_prop(ROOM_AS_DOORID);
    doors = (object *)other_room->query_prop(ROOM_AO_DOOROB);
    pos = member_array(door_id, door_ids);
    if (pos < 0)
    {
	write("Po drugiej stronie, po zaladowaniu pokoju nie ma drzwi: " + 
		other_room + ".\n");
	remove_door_info(environment(this_object()));
	remove_object();
	return;
    }

    other_door = doors[pos];
}


static void
add_door_info(object dest)
{
    string *door_ids;
    object *doors;

    door_ids = (string *)dest->query_prop(ROOM_AS_DOORID);
    doors = (object *)dest->query_prop(ROOM_AO_DOOROB);
    if (!pointerp(door_ids))
    {
	door_ids = ({});
	doors = ({});
    }
    

    if (member_array(door_id, door_ids) >= 0)
    {
	write("Jedne drzwi wystarcza.\n");
	remove_object();
	return;
    }

    door_ids += ({ door_id });
    doors += ({ this_object() });

    dest->add_prop(ROOM_AS_DOORID, door_ids);
    dest->add_prop(ROOM_AO_DOOROB, doors);
}


static void
remove_door_info(object dest)
{
    string *door_ids;
    object *doors;
    int pos;

    door_ids = (string *)dest->query_prop(ROOM_AS_DOORID);
    doors = (object *)dest->query_prop(ROOM_AO_DOOROB);
    if (!sizeof(door_ids))
	return;

    pos = member_array(door_id, door_ids);
    if (pos < 0)
	return;

    door_ids = exclude_array(door_ids, pos, pos);
    doors = exclude_array(doors, pos, pos);

    dest->add_prop(ROOM_AS_DOORID, door_ids);
    dest->add_prop(ROOM_AO_DOOROB, doors);
}



void
enter_env(object dest, object old)
{
    string *itemy;
    int x;
    
    add_door_info(dest); 
    if (open_status)
        dest->change_my_desc(check_call(open_desc), this_object());
    else
        dest->change_my_desc(check_call(closed_desc), this_object());
    if (strlen(door_desc))
    {
        itemy = ({ query_nazwa(PL_BIE) });
        
        
        for (x = 0; x < sizeof(query_przym(1, PL_BIE)); x++)
        {
            itemy = itemy + ({ query_przym(1, PL_BIE)[x] + " " +
                query_nazwa(PL_BIE) });
        }
	dest->add_item(itemy, door_desc);
    }

}


void
leave_env(object old, object dest)
{
    if (!old)
	return;

    old->remove_my_desc(this_object());
    if (strlen(door_desc))
	old->remove_item(query_nazwa(PL_BIE), door_desc);

    remove_door_info(old);
}


string
standard_open_desc() 
{
  string temp_desc;
  
  temp_desc = "Widzisz otwart" + koncowka("ego", "a", "e", "ych", "e") + 
      " " + short(PL_BIE);
  if (strlen(pass_commands[0]) <= 2)
    temp_desc = temp_desc + " prowadzace na " + pass_commands[1] + ".\n";
  else
    temp_desc = temp_desc + ".\n";
  return temp_desc;
}



string
standard_closed_desc()
{
  string temp_desc;
  temp_desc = "Widzisz zamkniet" + koncowka("ego", "a", "e", "ych", "e") + " "
            + short(PL_BIE);
  if (strlen(pass_commands[0]) <= 2)
   temp_desc = temp_desc + " prowadzace na " + pass_commands[1] + ".\n";
  else
    temp_desc = temp_desc + ".\n";
  return temp_desc;
}

/*
 * Function name: standard_open_mess1
 */
string
standard_open_mess1()
{
    return "otwiera " + short(PL_BIE) + ".\n";
}

/*
 * Function name: standard_open_mess2
 */
string
standard_open_mess2()
{
    return capitalize(short(PL_MIA)) + " otwiera" +
        (query_tylko_mn() ? "ja" : "") + " sie.\n";
}

/*
 * Function name: standard_open_mess3
 */
string
standard_open_mess3()
{
    return "Otwierasz " + short(this_player(), PL_BIE) + ".\n";
}

/*
 * Function name: standard_fail_open1
 */
string
standard_fail_open1()
{
    return capitalize(short(PL_MIA)) + 
        (query_tylko_mn() ? " sa" : " jest") + " juz otwar" +
        koncowka("ty", "ta", "te", "ci", "te") + ".\n";
}

/*
 * Function name: standard_fail_open2
 */
string
standard_fail_open2()
{
    return capitalize(short(PL_MIA)) + " nie chc" +
        (query_tylko_mn() ? "a" : "e") + " sie ruszyc.\n";
}

/*
 * Function name: standard_close_mess1
 */
string
standard_close_mess1()
{
    return "zamyka " + short(PL_BIE) + ".\n";
}

/*
 * Function name: standard_close_mess2
 */
string
standard_close_mess2()
{ 
    return capitalize(short(PL_MIA)) + " zamyka" +
        (query_tylko_mn() ? "ja" : "") + " sie.\n";
}

/*
 * Function name: standard_close_mess3
 */
string
standard_close_mess3()
{
    return "Zamykasz " + short(this_player(), PL_BIE) + ".\n";
}

/*
 * Function name: standard_lock_mess1
 */


string
standard_door_desc()
{
    return "Mocno wygladajac" + koncowka("y", "a", "e", "y", "e") + 
        short(PL_MIA) + ".\n";
}


string
standard_fail_pass()
{
    return capitalize(short(PL_MIA)) + " " + 
        (query_tylko_mn() ? "sa" : "jest") + " zamknie" + 
        koncowka("ty", "ta", "te", "ci", "te") + ".\n";
}

/*
 * Function name: standard_fail_close
 */
string
standard_fail_close()
{
     return capitalize(short(PL_MIA)) + " juz " +
         (query_tylko_mn() ? "sa" : "jest") + " zamknie" +
         koncowka("ty", "ta", "te", "ci", "te") + ".\n";
}

/*
 * Function name: standard_fail_unlock
 */


string
standard_pass_mess()
{
    return query_verb();
}


