// MorgenGrauen MUDlib
//
// room.c -- room base object
//
// $Id: room.c 9475 2016-02-19 21:16:17Z Zesstra $
#pragma strong_types
#pragma save_types
#pragma range_check
#pragma no_clone

inherit "/std/thing/properties";
inherit "/std/thing/language";
inherit "/std/hook_provider";
inherit "/std/room/light";
inherit "/std/container/inventory";
inherit "/std/room/moving";
inherit "/std/room/restrictions";
inherit "/std/room/description";
inherit "/std/room/exits";
inherit "/std/room/commands";
inherit "/std/room/items";
inherit "/std/container/vitems";
inherit "/std/room/doors";
inherit "/std/room/comm";

#include <thing/properties.h>
#include <config.h>
#include <properties.h>
#include <rooms.h>
#include <language.h>
#include <wizlevels.h>
#include <moving.h>
#include <defines.h>
#include <doorroom.h>
#include <functionlist.h>
#include <hook.h>

void reset()
{
  items::reset();
  vitems::reset();
  exits::reset();
  doors::reset();
}

static int
_query_noget()
{
  return 1;
}

void maybe_replace_program()
{
  string *list, first;
  object first_ob;

  if (object_name(this_object())=="/std/room" ||
      !(first_ob=find_object(first=(list=inherit_list(this_object()))[1])) ||
      (sizeof(list)!=1+sizeof(inherit_list(first_ob))) ||
      (1!=sizeof(list=functionlist(this_object(),
           RETURN_FUNCTION_NAME|NAME_INHERITED))) ||
      list[0]!="create")
    return;
  replace_program(first);
}

protected void create()
{
  maybe_replace_program();
  /* Set effective userid to userid */
  /* so that we may clone other things */
  seteuid(getuid(this_object()));
  properties::create();
  restrictions::create();
  commands::create();
  light::create();
  description::create();
  exits::create();
  items::create();
  doors::create();
  offerHook(H_HOOK_INIT, 1);

  SetProp(P_NAME,0);
  SetProp(P_NAME_ADJ,({}));
  Set(P_SHORT,0);
  Set(P_LONG,0);
  Set(P_TRANSPARENT,0);
  Set(P_ADJECTIVES,({}));
  Set(P_IDS,({}));
  Set(P_WEIGHT,PROTECTED,F_MODE);
  Set(P_TOTAL_WEIGHT,PROTECTED,F_MODE);
  Set(" clean counter ",2);
}

protected void create_super() {
  set_next_reset(-1);
}

private int
check_clean_count()
{
  int cc;

  cc=Query(" clean counter ");
  if (--cc<=0)
    return 1;
  Set(" clean counter ",cc);
  return 0;
}

public int clean_up(int arg)
{
  // Never try again when P_NEVER_CLEAN is set.
  if (Query(P_NEVER_CLEAN)) return 0;

  // do not cleanup, if this room is used as blueprint for clones or inherited
  // (arg>1) or if there are valid hook consumers waiting for something to
  // happen here. This is temporary and could change, so return 1;
  if (arg>1 || HHasConsumers())
      return 1;

  // Pruefen ob Spieler (auch netztote) anwesend sind.
  // Es fuehrt leider kein Weg dran vorbei einmal über das inventar und einmal
  // ueber P_ITEMS zu iterieren.
  object* inv = all_inventory();
  foreach(object ob : inv)
  {
    if(query_once_interactive(ob))
    {
      Set(" clean counter ",2);
      return 1;
    }
  }

  // Auf Objekte aus P_ITEMS pruefen
  foreach(<object|<string|string*>|int|mapping>* item : QueryProp(P_ITEMS))
  {
    // Semantik:
    // 1. Wenn RITEM_OBJECT ein REFRESH_NONE Item ist und es entweder nicht mehr 
    //    existiert oder nicht in diesem Raum ist, kein clean_up (es wuerde
    //    beim neuladen des Raumes ja wieder erzeugt;
    //    falls es aber hier ist, wird es mitvernichtet, dann ists ok)
    // 2. Wenn es ein REFRESH_DESTRUCT ist und noch existiert, aber nicht
    //    hier ist, KEIN clean_up.
    // Hier heisst fuer beide Faelle direkt in diesem Raum, befindet es sich in
    // einem Container koennte es beim Zerstoeren woanders hin bewegt werden und
    // damit nach dem neuladen doppelt existieren.
    if( (item[RITEM_REFRESH] == REFRESH_NONE &&
        (!item[RITEM_OBJECT] ||
        environment(item[RITEM_OBJECT]) != ME)) ||
        (item[RITEM_REFRESH] == REFRESH_DESTRUCT &&
        item[RITEM_OBJECT] &&
        environment(item[RITEM_OBJECT]) != ME))
    {
      return 1;
    }
    inv -= ({item[RITEM_OBJECT]});
  }
  // if there are objects left in the room do not clean up but try again later
  if(sizeof(inv) && !check_clean_count())
    return 1;

  // do clean_up
  //log_file("clean_up_log",sprintf(
  //        "%s:%s: %O\n",ctime(time())[11..18],__HOST_NAME__,this_object()));

  remove();
  // wenn der Raum sich im remove() nicht zerstoert, hat er dafuer vermutlich
  // nen Grund. Evtl. klappts ja naechstes Mal.

  return(1);
}

/* Instead of printing the exits with the long description, we implement */
/* the command "exits" to show them. */
int
show_exits() {
  mixed ex;
  if( this_player()->CannotSee() ) return 1;
  if ((ex=QueryProp(P_HIDE_EXITS)) && intp(ex)) return 1;
  if (ex = GetExits(this_player())) write(ex);
  return 1;
}

int
toggle_exits(string str)
{
  int ex;

  /* Nur das aktuelle Environment des Spielers ist zustaendig fuer die
     Auflistung der Ausgaenge. Anderenfalls wird das Kommando von Raeumen
     im Raum (z.B. Transportern) abgefangen und es werden dessen Ausgaenge
     aufgelistet.
     Sprich: keine Auflistung von Aussen. */
  if (environment(this_player()) != this_object()) return 0;
  if (!str) return show_exits();
  if (str!="auto") return 0;
  ex = this_player()->QueryProp(P_SHOW_EXITS);
  this_player()->SetProp(P_SHOW_EXITS, !ex);
  if (ex) write("Ausgaenge werden nicht mehr automatisch angezeigt.\n");
  else write("Ausgaenge werden automatisch angezeigt.\n");
  return 1;
}

public varargs void init(object origin)
{
  if (HookFlow(H_HOOK_INIT, 0)[H_RETCODE] == H_CANCELLED)
      return;
  Set(" clean counter ",2);
  exits::init(origin);
  commands::init(origin);
  description::init(origin);
  doors::init(origin);

  add_action("toggle_exits", "exits");
  add_action("toggle_exits", "ausgang");
  add_action("toggle_exits", "ausgaenge");
  add_action("toggle_exits", "aus");
}

int _query_para(){
  int re;
  if(re=Query(P_PARA))return re;
  if(sizeof(regexp(({object_name(this_object())}),".*\\^0$")))
      return -1;
  return to_int(
    regreplace(object_name(this_object()),".*\\^\([1-9][0-9]*\)$","\\1",1));
}

//dies ist ein Raum, war gewuenscht von mehreren Leuten.
status IsRoom() {return(1);}
