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