// MorgenGrauen MUDlib
//
// room/doors.c -- new doors, managed by doormaster
//
// $Id: doors.c 9134 2015-02-02 19:26:03Z Zesstra $

#pragma strong_types
#pragma save_types
#pragma range_check
#pragma no_clone

#include <config.h>
#include <properties.h>
#include <defines.h>
#include <language.h>
#include <doorroom.h>
#define NEED_PROTOTYPES
#include <thing/properties.h>
#include <room/exits.h>

protected void create()
{
  if (object_name(this_object()) == __FILE__[0..<3])
  {
    set_next_reset(-1);
    return;
  }
  SetProp(P_DOOR_INFOS,0);
}

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

varargs int NewDoor(string|string* cmds, string dest, string|string* ids,
                    mapping|<int|string|string*>* props)
{
/*
  cmds: Befehl(e), um durch die Tuer zu gehen (String oder Array von Strings)
  dest: Zielraum
  ids:  Id(s) der Tuer, default "tuer" (String, Array von Strings oder 0)
  props: besondere Eigenschaften der Tuer (optional)
  Array mit Paaren Nummer der Eigenschaft, Inhalt
  definierte Properties sind:
  D_FLAGS:  Flags wie bei Sir's Tueren
  default: DOOR_CLOSED | DOOR_RESET_CL
  Bei Schluesseln wird getestet, ob der String, den
  QueryDoorKey zurueckliefert, gleich
  "raumname1:raumname2" ist, wobei raumname1,2 die
  kompletten Filenamen der beiden Raeume in sortierter
  Reihenfolge sind.
  D_LONG:   lange Beschreibung der Tuer
  default: "Eine Tuer.\n"
  D_SHORT:  kurze Beschreibung der Tuer, wird an die Raumbeschreibung
  angefuegt, wobei %s durch geoeffnet bzw. geschlossen
  ersetzt wird.
  default: "Eine %se Tuer. "
  D_NAME:   Name, der beim Oeffnen/Schliessen und bei Fehlermeldungen
  angezeigt wird.
  default: "Tuer"
  D_GENDER: default: FEMALE
  D_FUNC:   Funktion, die im Raum aufgerufen werden soll, wenn die
  Tuer erfolgreich durchschritten wird.
  default: 0
  D_MSGS:   Falls String: ausgegebene Richtung fuer move
  Falls Array: ({direction, textout, textin}) fuer move
  default: 0

  Beispiel:
  NewDoor("norden","/players/rochus/room/test2","portal",
  ({D_NAME,"Portal",
  D_GENDER,NEUTER,
  D_SHORT,"Im Norden siehst Du ein %ses Portal. ",
  D_LONG,"Das Portal ist einfach nur gigantisch.\n"
  }));

*/

  if (!cmds || !dest) return 0;
  return call_other(DOOR_MASTER,"NewDoor",cmds,dest,ids,props);
}

public varargs void init(object origin)
{
  mixed *info;
  string *cmds;
  int i,j;

  if (!pointerp(info=(mixed *)QueryProp(P_DOOR_INFOS))) return;
  add_action("oeffnen","oeffne");
  add_action("schliessen","schliesse");
  add_action("schliessen","schliess");
  for (i=sizeof(info)-1;i>=0;i--) {
    cmds=(string *)(info[i][D_CMDS]);
    for (j=sizeof(cmds)-1;j>=0;j--)
      add_action("go_door",cmds[j]);
    // Befehle IMMER anfuegen, gechecked wird sowieso erst beim Durchgehen.
  }
}

void reset()
{
  if (QueryProp(P_DOOR_INFOS))
    call_other(DOOR_MASTER,"reset_doors");
}

int oeffnen (string str)
{
  if (!str || !QueryProp(P_DOOR_INFOS))
    return 0;
  return (int) call_other(DOOR_MASTER,"oeffnen",str);
}

int schliessen (string str)
{
  if (!str || !QueryProp(P_DOOR_INFOS))
    return 0;
  return (int) call_other(DOOR_MASTER,"schliessen",str);
}

varargs int
go_door (string str)
{
  if (!QueryProp(P_DOOR_INFOS))
    return 0;
  if (call_other(DOOR_MASTER,"go_door",query_verb()))
    return 1;
  return 0;
}

int set_doors(string *cmds,int open)
{
  int j;
  
  if (!previous_object())
    return 0;
  if (object_name(previous_object())!=DOOR_MASTER)
    return 0;
  // Andere sollen nicht rumpfuschen.
  if (!this_player()) return 0;
  if (environment(this_player())!=this_object())
    return 0;
  // Ist sowieso keiner da...
  if (!pointerp(cmds))
    return 0;
  if (open)
    AddSpecialExit(cmds,"go_door");
  else
    RemoveSpecialExit(cmds);
  for (j=sizeof(cmds)-1;j>=0;j--)
    add_action("go_door",cmds[j]);
  return 1;
}

/* Fuer Tueren, die flexible Langbeschreibungen haben, wird ein 
 * SpecialDetail eingefuehrt.
 */

string special_detail_doors(string key){
  return DOOR_MASTER->special_detail_doors(key);
}
