// 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";

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

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;

  // if there are any items we have produced ourselfes check them
  mixed itema = QueryProp(P_ITEMS);
  if(pointerp(itema))
  {
    mixed names;
    int i;
    i = sizeof(names = all_inventory(this_object()));
    while(i--)
    {
      if (query_once_interactive(names[i]))
      {
        Set(" clean counter ",2);
        return 1;
      }
      if(objectp(names[i])) names[i] = explode(object_name(names[i]),"#")[0];
    }

    for(i = sizeof(itema)-1; i >= 0; i--)
    {
      // Semantik:
      // 1. Wenn RITEM_OBJECT ein array ist, kann evtl ge'clean'ed werden.
      // 2. Wenn es 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)
      // 3. Wenn es ein REFRESH_DESTRUCT ist und noch existiert, aber nicht
      //    hier ist, KEIN clean_up.
      if (!pointerp(itema[i][RITEM_OBJECT]) 
          && ((itema[i][RITEM_REFRESH] == REFRESH_NONE 
              && (!itema[i][RITEM_OBJECT] 
                || environment(itema[i][RITEM_OBJECT])!=this_object())) 
            || (itema[i][RITEM_REFRESH] == REFRESH_DESTRUCT 
              && itema[i][RITEM_OBJECT] 
              && environment(itema[i][RITEM_OBJECT]) != this_object())))
          return 1;
      names -= (pointerp(itema[i][RITEM_FILE]) ?
          itema[i][RITEM_FILE] : ({ itema[i][RITEM_FILE] }));
    }
    // if there are objects left in the room do not clean up but try again later
    if(sizeof(names) && !check_clean_count()) return 1;
  }
  else
    // is there any object lying around?
    if(first_inventory(this_object()) && !check_clean_count()) return 2;

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