#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;

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);

/*
 * Function name: create_object
 * Description:   Initialize object.
 */
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(string str);

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

  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;
}

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; }

/*
 * already in /std/door.c
 */
void
set_other_room(string name) { other_room = name; }

/*
 * already in /std/door.c
 */
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();
}
