diff --git a/secure/questmaster.c b/secure/questmaster.c
new file mode 100644
index 0000000..314a97b
--- /dev/null
+++ b/secure/questmaster.c
@@ -0,0 +1,1174 @@
+// MorgenGrauen MUDlib
+//
+// questmaster.c -- Questmaster, verwaltet die normalen Quests und
+//                  die MiniQuests
+//
+// $Id: questmaster.c 9136 2015-02-03 21:39:10Z Zesstra $
+//
+#pragma strict_types
+#pragma no_clone
+#pragma no_shadow
+#pragma no_inherit
+#pragma verbose_errors
+#pragma combine_strings
+//#pragma pedantic
+//#pragma range_check
+#pragma warn_deprecated
+
+#include <config.h>
+#include "/secure/wizlevels.h"
+#include "/secure/questmaster.h"
+#include "/secure/lepmaster.h"
+#include "/secure/telnetneg.h" // P_TTY
+#include <living/description.h> // P_LEVEL
+#include <player/base.h> // P_TESTPLAYER
+#include <daemon.h>
+#include <ansi.h>
+#include <events.h>
+
+#define DEBUG(x) if (funcall(symbol_function('find_player),"arathorn"))\
+          tell_object(funcall(symbol_function('find_player),"arathorn"),\
+                      "QM: "+x+"\n")
+
+#define ME this_object()
+#define PL this_player()
+
+#define MQ_DATA_POINTS 0
+#define MQ_DATA_QUESTNO 1
+#define MQ_DATA_TASKDESC 2
+#define MQ_DATA_VISIBLE 3
+#define MQ_DATA_ACTIVE 4
+#define MQ_DATA_TITLE 5
+#define MQ_DATA_DIARYTEXT 6
+#define MQ_DATA_RESTRICTIONS 7
+#define MQ_DATA_ASSIGNED_DOMAIN 8
+#define MQ_DATA_QUERY_PERMITTED 9
+
+private int max_QP = 0;
+private int opt_QP = 0;
+// Die Questliste mit allen Daten
+private mapping quests = ([]);
+
+// Das Mapping mit der MQ-Liste an sich und alle zugehoerigen Daten
+private mapping miniquests = ([]);
+// Nach MQ-Nummern indizierter Cache:
+// Struktur ([int num : ({ int stupse, string mq-object }) ])
+private nosave mapping by_num = ([]);
+// Cache der Objekte, die die MQ-Listen der Regionen abfragen duerfen
+// Struktur ([string path : ({ string mq_object }) ])
+private nosave mapping mq_query_permitted = ([]);
+// Cache fuer die MQ-Punkte von Spielern, wird fuer den jeweiligen Spieler
+// beim Abfragen von dessen MQ-Punkten gefuellt. Spielername wird bei
+// Aenderungen an seinen MQ-Punkten (Bestehen einer MQ, manuelles Setzen
+// oder Loeschen einer seiner MQs) aus dem Cache ausgetragen
+private nosave mapping users_mq = ([]);
+// letzte vergebene MQ-Indexnummer. Es darf niemals eine MQ eine Indexnummer
+// kriegen, die eine andere MQ schonmal hatte, auch wenn die geloescht wurde.
+// (Zumindest nicht, ohne die entsprechenden Bits im Spieler zu loeschen, was
+// zZ nicht passiert.
+private int last_num = 0;
+
+
+void save_info() {
+  save_object(QUESTS);
+}
+
+// Caches aufbauen.
+static void make_num(string mqob_name, int stupse, int index,
+                     string taskdesc, int vis, int active, string title,
+                     string donedesc, mapping restr, string domain, 
+                     string *permitted_objs) {
+  by_num += ([ index : ({stupse, mqob_name})]);
+  foreach ( string obj: permitted_objs ) {
+    if ( member(mq_query_permitted, obj) )
+      mq_query_permitted[obj] += ({mqob_name});
+    else
+      mq_query_permitted[obj] = ({mqob_name});
+  }
+}
+
+void create() {
+  seteuid(getuid(ME));
+  if (!restore_object(QUESTS)) {
+    save_info();
+  }
+
+  walk_mapping(miniquests, #'make_num /*'*/ );
+  set_next_reset(43200); // Reset alle 12 Stunden.
+  EVENTD->RegisterEvent(EVT_LIB_QUEST_SOLVED,"HandleQuestSolved",
+      ME);
+}
+
+public int remove(int silent) {
+  save_info();
+  EVENTD->UnregisterEvent(EVT_LIB_QUEST_SOLVED, ME);
+  destruct(ME);
+  return 1;
+}
+
+// Schreibzugriff nur fuer interaktive EMs und ARCH_SECURITY.
+private int allowed_write_access() {
+  if (process_call())
+    return 0;
+  if (ARCH_SECURITY)  // prueft auch this_interactive() mit.
+    return 1;
+  return 0;
+}
+
+void reset() {
+  by_num = ([]);
+  mq_query_permitted = ([]);
+  walk_mapping(miniquests, #'make_num /*'*/ );
+  set_next_reset(43200);
+}
+
+/*
+ * (1) ABSCHNITT "NORMALE QUESTS"
+ */
+
+/* Die Quests werden in einem Mapping gespeichert. Der Schluessel ist dabei der
+   Quest-Name, die Eintraege sind Arrays der folgenden Form:
+
+   1. Element ist die Zahl der durch diese Quest zu erwerbenden Questpunkte.
+   2. Element ist die Zahl der Erfahrungspunkte, die der Spieler bekommt,
+      wenn er diese Quest loest.
+   3. Element ist ein Array mit den Filenamen der Objekte, denen es gestattet
+      ist, diese Quest beim Player als geloest zu markieren (Erzmagier duerfen
+      das aber sowieso immer).
+   4. Element ist ein String, der die Quest kurz beschreibt. Dieser String wird
+      dem Spieler vom Orakel als Hinweis gegeben.
+   5. Element ist eine Zahl zwischen -1 und 100, die den Schwierigkeitsgrad der
+      Quest angibt, nach Einschaetzung des EM fuer Quests. Das Orakel kann dann
+      evtl. sinnige Saetze wie "Diese Quest erscheint mir aber noch recht
+      schwer fuer Dich.", oder "Hm, die haettest Du ja schon viel eher loesen
+      koennen." absondern. :)
+
+      Ein Wert von -1 bedeutet eine Seherquest. Diese zaehlt nicht zu den
+      Maximalen Questpunkten, sondern zaehlt als optionale Quest
+   6. Element ist ein Integer von 0 bis 5 und gibt die "Klasse" an;
+      ausgegeben werden dort Sternchen
+   7. Element ist ein Integer, 0 oder 1.
+      0: Quest voruebergehend deaktiviert (suspendiert)
+      1: Quest aktiviert
+   8. Element ist ein String und enthaelt den Namen des Magiers, der die
+      Quest "verbrochen" hat.
+   9. Element ist ein String, der den Namen eines Magiers enthaelt, der
+      evtl. fuer die Wartung der Quest zustaendig ist.
+  10. Element ist eine Zahl von 0 bis 4, die der Quest ein Attribut
+      gibt (0 fuer keines)
+*/
+
+// geaendert:
+// 5  == diff geht nun von -1 bis 100
+// 6  == klasse geht nun von 0 bis 5
+// 10 == attribut geht nun von 0 bis 4
+
+private int RecalculateQP() {
+  int i;
+  mixed q,n;
+
+  if (!allowed_write_access())
+    return -1;
+
+  max_QP=0;
+  opt_QP=0;
+
+  n=m_indices(quests);
+  q=m_values(quests);
+    for (i=sizeof(q)-1;i>=0;i--)
+      if (q[i][Q_ACTIVE]) {
+        if (q[i][Q_DIFF]>=0)
+          max_QP+=q[i][Q_QP];
+        if (q[i][Q_DIFF]==-1)
+          opt_QP+=q[i][Q_QP];
+      }
+
+  return max_QP+opt_QP;
+}
+
+int AddQuest(string name, int questpoints, int experience,
+      string *allowedobj, string hint, int difficulty, int questclass,
+      int active, string wiz, string scndwiz, int questattribute)
+{
+  mixed *quest;
+  int i;
+
+  if (!allowed_write_access()) return 0;
+  if (!stringp(name) || sizeof(name)<5) return -1;
+  if (questpoints<1) return -2;
+  if (!intp(experience)) return -3;
+  if (!pointerp(allowedobj)) return -4;
+  for (i=sizeof(allowedobj)-1;i>=0;i--)
+    {
+      if (!stringp(allowedobj[i]) || allowedobj[i]=="") return -4;
+      allowedobj[i]=(string)"/secure/master"->_get_path(allowedobj[i],0);
+    }
+  if (!stringp(hint) || hint=="") return -5;
+  if (difficulty<-1 || difficulty>100) return -6;
+  if (questclass<0 || questclass>5) return -11;
+  if (active<0 || active>1) return -7;
+  if (!stringp(wiz) || wiz=="" ||
+      file_size("/players/"+(wiz=lower_case(wiz))) != -2) return -8;
+  if (!stringp(scndwiz))
+    scndwiz="";
+  else if (file_size("/players/"+(scndwiz=lower_case(scndwiz))) != -2)
+    return -9;
+  if (questattribute<0 || questattribute>4)
+    return -10;
+
+  if(quests[name]&&(quests[name][5]==0||quests[name][5]==1)&&quests[name][6])
+    max_QP-=quests[name][0];
+
+  quests+=([name: ({questpoints,experience,allowedobj,hint,difficulty,
+                    questclass,active,wiz, scndwiz,questattribute,
+                    ({0.0,0}) }) ]);
+  RecalculateQP();
+  save_info();
+  QMLOG(sprintf("add: %s %O (%s)",name,quests[name],
+                getuid(this_interactive())));
+  return 1;
+}
+
+int RemoveQuest(string name) {
+  mixed *quest;
+
+  if (!allowed_write_access()) return 0;
+  if (!quests[name]) return -1;
+  QMLOG(sprintf("remove: %s %O (%s)",name,quests[name],
+                getuid(this_interactive())));
+  m_delete(quests,name);
+  RecalculateQP();
+  save_info();
+  return 1;
+}
+
+int QueryNeededQP() {
+  return REQ_QP;
+}
+
+int QueryMaxQP() {
+  return max_QP;
+}
+
+int QueryOptQP() {
+  return opt_QP;
+}
+
+int QueryTotalQP() {
+  return max_QP+opt_QP;
+}
+
+mixed *QueryGroupedKeys() {
+  string *qliste;
+  mixed  *qgliste;
+  int i, j;
+
+  qgliste = allocate(sizeof(QGROUPS)+1); // letzte Gruppe sind die Seherquests
+  qliste = m_indices(quests);
+
+  for (i=sizeof(qgliste)-1;i>=0;i--)
+    qgliste[i]=({});
+
+  for (i=sizeof(qliste)-1;i>=0;i--)
+    {
+      // inaktive quest?
+      if (!quests[qliste[i]][Q_ACTIVE])
+        continue;
+      // optionale quest? also Seherquest
+        if (quests[qliste[i]][Q_DIFF]==-1)
+          qgliste[sizeof(QGROUPS)] += ({qliste[i]});
+        else {
+          // dann haben wir also eine normale Quest und daher Einordnung
+          // nach dem Schwierigkeitswert
+          for (j=sizeof(QGROUPS)-1;
+               j>=0 && QGROUPS[j]>=quests[qliste[i]][Q_DIFF];j--)
+            ;
+          qgliste[j] += ({qliste[i]});
+        }
+    }
+  return qgliste;
+}
+
+
+// folgende funk brauch ich glaube ich nicht mehr:
+int QueryDontneed(object pl) {
+  raise_error("Ich glaub, die Func QueryDontneed() braucht kein Mensch mehr. "
+  "(Zook)");
+}
+
+// Die folgende Func braucht man nicht mehr
+int QueryReadyForWiz(object player) {
+  raise_error("Die Func QueryReadyForWiz() braucht keiner mehr. (Zook)");
+}
+
+mixed *QueryQuest(string name) {
+  if(!quests[name])
+    return ({});
+  if( extern_call() )
+    return deep_copy( quests[name] );
+  return quests[name];
+}
+
+int QueryQuestPoints(string name) {
+  if( !quests[name] )
+    return -1;
+
+  return quests[name][Q_QP];
+}
+
+mixed *QueryQuests() {
+  if( extern_call() )
+    return ({m_indices(quests),map(m_values(quests),#'deep_copy /*'*/)});
+  return ({ m_indices(quests), m_values(quests) });
+}
+
+string *QueryAllKeys() {
+  return m_indices(quests);
+}
+
+int SetActive(string name, int flag) {
+  mixed *quest;
+
+  if (!allowed_write_access()) return 0;
+  if (!(quest=quests[name])) return -1;
+  switch(flag)
+    {
+    case 0:
+      if (quest[Q_ACTIVE] == flag)
+        return -2;
+      quest[Q_ACTIVE] = flag;
+      break;
+    case 1:
+      if (quest[Q_ACTIVE] == flag)
+        return -2;
+      quest[Q_ACTIVE] = flag;
+      break;
+    default:
+      return -3;
+    }
+  quests[name]=quest;
+  RecalculateQP();
+  save_info();
+  QMLOG(sprintf("%s: %s (%s)",(flag?"activate":"deactivate"),name,
+                getuid(this_interactive())));
+  return 1;
+}
+
+string name() {
+  return "<Quest>";
+}
+string Name() {
+  return "<Quest>";
+}
+
+void Channel(string msg) {
+  if(!interactive(previous_object()))
+    return;
+  catch(CHMASTER->send("Abenteuer", ME, msg);publish);
+}
+
+ /* quoted from /sys/mail.h: */
+#define MSG_FROM 0
+#define MSG_SENDER 1
+#define MSG_RECIPIENT 2
+#define MSG_CC 3
+#define MSG_BCC 4
+#define MSG_SUBJECT 5
+#define MSG_DATE 6
+#define MSG_ID 7
+#define MSG_BODY 8
+
+void SendMail(string questname, mixed *quest, object player) {
+  mixed* mail;
+  string text;
+
+  mail = allocate(9);
+
+  text =
+    "Hallo "+capitalize(getuid(player))+",\n\n"+
+    break_string("Nachdem Du gerade eben das Abenteuer '"+
+                 questname +"' ("+quest[Q_QP]+" Punkte), das "+
+                 capitalize(quest[Q_WIZ])+" fuer das "MUDNAME" entworfen hat, "
+                 "mit Erfolg bestanden hast, sind "
+                 "wir nun an Deiner Meinung dazu interessiert:", 78)+
+    "\n  Hat Dir das Abenteuer gefallen und wieso bzw. wieso nicht?\n"
+    "  Ist die Einstufung Deiner Meinung nach richtig? (AP und Stufe)\n"
+    "  Gab es Probleme oder gar Fehler?\n"
+    "  Hast Du Verbesserungsvorschlaege?\n\n";
+
+  text += break_string("Diese Nachricht wurde automatisch verschickt, "
+        "wenn Du mit dem 'r' Kommando darauf antwortest, geht die Antwort "
+        "direkt an Ark als zustaendigem Erzmagier fuer Abenteuer.\n",78);
+
+  if (quest[Q_SCNDWIZ]!="") {
+    text += break_string(
+        "Falls Du mit dem Magier sprechen willst, der zur Zeit das "
+        "Abenteuer technisch betreut, kannst Du Dich an "
+        +capitalize(quest[Q_SCNDWIZ])+ " wenden.",78);
+  }
+
+  mail[MSG_FROM] = "Ark";
+  mail[MSG_SENDER] = "Ark";
+  mail[MSG_RECIPIENT] = getuid(player);
+  mail[MSG_CC]=0;
+  mail[MSG_BCC]=0;
+  mail[MSG_SUBJECT]="Das Abenteuer: "+questname;
+  mail[MSG_DATE]=dtime(time());
+  mail[MSG_ID]=MUDNAME":"+time();
+  mail[MSG_BODY]=text;
+
+  "/secure/mailer"->DeliverMail(mail,0);
+  return;
+}
+
+static int compare (mixed *i, mixed *j) {
+  if (i[4] == j[4])
+    return i[1] > j[1];
+  else
+    return i[4] > j[4];
+}
+
+varargs string liste(mixed pl) {
+  int qgroups, i, j, qrfw;
+  mixed *qlists, *qgrouped, *qtmp;
+  string str;
+  string ja, nein, format, ueberschrift;
+
+  if(!objectp(pl))
+    if(stringp(pl))
+      pl=find_player(pl) || find_netdead(pl);
+  if(!objectp(pl))
+    pl=PL;
+  if(!objectp(pl))
+    return "Ohne Spielernamen/Spielerobjekt gibt es auch keine Liste.\n";
+
+  if ( ((string)pl->QueryProp(P_TTY)) == "ansi")
+  {
+      ja = ANSI_GREEN + "ja" + ANSI_NORMAL;
+      nein = ANSI_RED + "nein" + ANSI_NORMAL;
+  }
+  else
+  {
+      ja = "ja";
+      nein = "nein";
+  }
+
+  str = "";
+  // Festlegen des Ausgabeformates
+  format = "%=-:30s %:3d %-:6s  %-:9s %:2s/%-:3s  %-:12s %-s\n";
+  ueberschrift = sprintf("%-:30s %:3s %-:6s  %-:9s %-:6s  %-:12s %-:4s\n",
+                 "Abenteuer", "AP", "Klasse", "Attribut",
+                 "Stufe", "Autor", "Gel?");
+
+  qgroups = sizeof(QGROUPS);
+  qlists = allocate( qgroups+1 );
+  for( i=qgroups; i>=0; i-- )
+    qlists[i] = ({});
+
+  qgrouped = QueryGroupedKeys();
+
+  for (i=sizeof(qgrouped)-1;i>=0; i--)
+    for (j=sizeof(qgrouped[i])-1;j>=0; j--) {
+      qtmp = QueryQuest(qgrouped[i][j]);
+      qlists[i] += ({ ({
+        qgrouped[i][j],
+        qtmp[Q_QP],
+        QCLASS_STARS(qtmp[Q_CLASS]),
+        capitalize(QATTR_STRINGS[qtmp[Q_ATTR]]),
+        qtmp[Q_DIFF],
+        (qtmp[Q_AVERAGE][1]>10 /*&& IS_ARCH(this_player())*/
+                  ? to_string(to_int(qtmp[Q_AVERAGE][0]))
+                  : "-"),
+        capitalize(qtmp[Q_WIZ]),
+        (int)pl->QueryQuest(qgrouped[i][j]) == OK ? ja : nein
+      }) });
+    }
+
+  for( i=0; i<qgroups; i++ )
+  {
+    if (sizeof(qlists[i])) {
+      str += "\n" + ueberschrift;
+      str += sprintf("Stufen %d%s:\n",
+                     QGROUPS[i]+1,
+                     i==qgroups-1?"+":sprintf("-%d", QGROUPS[i+1]));
+      qlists[i] = sort_array( qlists[i], "compare", ME );
+      for( j=0; j<sizeof(qlists[i]); j++ ) {
+        if(qlists[i][j][Q_DIFF]>=0)
+          str += sprintf( format,
+                          qlists[i][j][0], qlists[i][j][1], qlists[i][j][2],
+                          qlists[i][j][3], sprintf("%d",qlists[i][j][4]),
+                          qlists[i][j][5],
+                          qlists[i][j][6], qlists[i][j][7]);
+      }
+      str += "\n\n";
+    }
+  }
+
+  qlists[qgroups] = sort_array(qlists[qgroups], "compare", ME);
+  i = qgroups;
+  if (sizeof(qlists[i])) {
+    str += "\n" + ueberschrift;
+    str += "Nur fuer Seher:\n";
+    for( j=0; j<sizeof(qlists[qgroups]); j++ )  {
+      if(qlists[i][j][Q_DIFF]==-1)
+        str += sprintf( format,
+                        qlists[i][j][0], qlists[i][j][1], qlists[i][j][2],
+                        qlists[i][j][3], "S", qlists[i][j][5],
+                        qlists[i][j][6],
+                        qlists[i][j][7]);
+    }
+  }
+
+  str +=
+    "\nEine Erklaerung der einzelnen Spalten findest Du unter "
+    "\"hilfe abenteuerliste\".\n";
+
+  return str;
+}
+
+
+// mitloggen, mit welchen durchschnittlichen Leveln Quests so geloest
+// werden...
+void HandleQuestSolved(string eid, object trigob, mixed data) {
+  string qname = data[E_QUESTNAME];
+
+  if (!quests[qname] || !objectp(trigob)
+      || trigob->QueryProp(P_TESTPLAYER) || IS_LEARNER(trigob))
+    return;
+
+  int lvl = (int)trigob->QueryProp(P_LEVEL);
+
+  if (lvl <= 0)
+    return;
+
+  // neuen Durchschnitt berechen.
+  mixed tmp = quests[qname][Q_AVERAGE];
+  float avg = tmp[0];
+  int count = tmp[1];
+  avg *= count;
+  avg += to_float(lvl);
+  tmp[1] = ++count;
+  tmp[0] = avg / count;
+
+  DEBUG(sprintf("%s: %f (%d)\n",qname,
+        quests[qname][Q_AVERAGE][0],
+        quests[qname][Q_AVERAGE][1]));
+}
+
+/*
+ * (2) ABSCHNITT "MINI" QUESTS
+ */
+
+int ClearUsersMQCache() {
+  if (!allowed_write_access())
+    return 0;
+
+  users_mq = ([]);
+
+  return 1;
+}
+
+mixed QueryUsersMQCache() {
+  if (!allowed_write_access())
+    return 0;
+
+  return users_mq;
+}
+
+/* Beschreibung
+ *
+ * Die MiniQuests werden in einem Mapping gespeichert.
+ *
+ * Der Key ist dabei der Name des Objektes, das die Quest im Spieler
+ * markieren darf. Die Daten zu den Miniquests stehen in den Value-Spalten
+ * des Mappings.
+ *
+ * 1. Spalte ist die Zahl der durch diese Quest zu erwerbenden Stufenpunkte
+ * 2. Spalte ist die Nummer unter der die MiniQuest gefuehrt wird.
+ * 3. Spalte ist ein String, der die Quest(aufgabe) kurz beschreibt.
+ * 4. Spalte ist ein Integer, 0 oder 1:
+ *     0 : Quest ist fuer Spieler nicht sichtbar
+ *     1 : Quest ist fuer Spieler z.B. bei einer Anschlagtafel sichtbar
+ *     Fuer Spieler unsichtbare MQs sollte es aber nicht mehr geben!
+ * 5. Spalte ist ein Integer, 0 oder 1:
+ *     0 : Quest voruebergehend deaktiviert
+ *     1 : Quest aktiviert
+ * 6. Spalte ist ein String, der den Kurztitel der Miniquest enthaelt
+ * 7. Spalte ist ein String, der eine kurze Beschreibung dessen enthaelt,
+ *     was der Spieler im Verlauf der Miniquest erlebt hat.
+ * 8. Spalte ist ein Mapping, dessen Eintraege analog zu P_RESTRICTIONS
+ *     gesetzt werden koennen, um anzugeben, welche Voraussetzungen erfuellt
+ *     sein muessen, bevor ein Spieler diese Quest beginnen kann.
+ * 9. Spalte ist die Zuordnung der MQ zu den Regionen
+ *10. Spalte ist ein Array aus Strings, das die Objekte enthaelt, die
+ *    die Daten dieser Quest abfragen duerfen, um sie an Spieler auszugeben.
+ */
+
+int DumpMiniQuests(object who) {
+  int sum_points;
+
+  if (extern_call() && !allowed_write_access())
+    return 0;
+
+  if ( !objectp(who) || !query_once_interactive(who))
+    who = this_interactive();
+
+  MQMLOG(sprintf("DumpMiniQuests: PO: %O, TI: %O", previous_object(), who));
+  rm(MQ_DUMP_FILE);
+
+  write_file(MQ_DUMP_FILE, "MINIQUESTS: ("+dtime(time())+")\n\n"+
+    "  Nr  Pkt  vis akt vergebendes Objekt\n");
+  string *msg = ({});
+
+  foreach(string obname, int stupse, int nummer, mixed descr, int vis,
+      int active /*, string title, string donedesc, mapping restrictions,
+      string domain, string *permitted_objs*/: miniquests)
+  {
+    msg += ({ sprintf("%4d %4d %4d %4d %s",
+      nummer, stupse, vis, active, obname)});
+    sum_points += stupse;
+  }
+
+  write_file(MQ_DUMP_FILE, implode(sort_array(msg, #'> /*'*/), "\n"));
+  write_file(MQ_DUMP_FILE, sprintf("\n\n"
+             "============================================================\n"
+             +"MiniQuests: %d Miniquests mit %d Punkten.\n\n",
+              sizeof(miniquests), sum_points));
+  return 1;
+}
+
+public int AddMiniQuest(int mquestpoints, string allowedobj, string descr,
+            int active, string title, string donedesc, mapping restrictions,
+            string domain, string *permitted_objs) {
+
+  if (!allowed_write_access())
+    return 0;
+
+  // Parameterpruefung: Questgeber, Restrictions, Region, Titel und
+  // zugelassene Abfrageobjekte muessen gueltig angegeben werden, alles
+  // weitere wird unten ggf. ausgenullt/korrigiert.
+  if (!stringp(allowedobj) || !sizeof(allowedobj) || !mappingp(restrictions)
+      || !stringp(domain) || !stringp(title) || !pointerp(permitted_objs))
+    return -1;
+
+  // Miniquest mit weniger als 1 Stups einzutragen ist wohl unsinnig.
+  if (mquestpoints<1)
+    return -2;
+
+  // Mindestens ein Objekt muss eingetragen werden, das Spielern Informationen
+  // ueber die Aufgabenstellung der MQ geben darf.
+  if ( !sizeof(permitted_objs) )
+    return -3;
+
+  // Pruefen, ob die als Questgeber angegebene Datei existiert.
+  if (allowedobj[<2..] == ".c")
+    allowedobj = allowedobj[0..<3];
+  allowedobj = explode(allowedobj, "#")[0];
+  allowedobj = (string)MASTER->_get_path(allowedobj,0);
+  if (file_size(allowedobj+".c") <=0)
+    return -3;
+
+  // Vergibt das angegebene Objekt schon eine MQ? Dann abbrechen.
+  if (member(miniquests,allowedobj))
+    return -4;
+
+  if (!stringp(descr) || !sizeof(descr))
+    descr = 0;
+  if (!stringp(donedesc) || !sizeof(donedesc))
+    donedesc = 0;
+
+  // Eintrag hinzufuegen, visible ist per Default immer 1.
+  // MQ-Nummer hochzaehlen
+  int nummer = last_num + 1;
+  m_add(miniquests, allowedobj, mquestpoints, nummer, descr, 1, active,
+    title, donedesc, restrictions, domain, permitted_objs);
+  // und nummer als last_num merken.
+  last_num = nummer;
+  save_info();
+  m_add(by_num, nummer, ({mquestpoints, allowedobj}));
+  MQMLOG(sprintf("AddMiniQuest: %s %O (%s)", allowedobj, miniquests[allowedobj],
+                 getuid(this_interactive())));
+
+  ClearUsersMQCache();
+  if (find_call_out(#'DumpMiniQuests) == -1)
+    call_out(#'DumpMiniQuests, 60, this_interactive());
+  return 1;
+}
+
+int RemoveMiniQuest(string name) {
+  if (!allowed_write_access())
+    return 0;
+  // Gibt es einen solchen Eintrag ueberhaupt?
+  if (!member(miniquests,name))
+    return -1;
+
+  MQMLOG(sprintf("RemoveMiniQuest: %s %O (%s)",
+    name, m_entry(miniquests, name), getuid(this_interactive())));
+
+  // MQ aus dem MQ-Indexnummern-Cache loeschen.
+  m_delete(by_num, miniquests[name,MQ_DATA_QUESTNO]);
+  // MQ aus der Miniquestliste austragen.
+  m_delete(miniquests, name);
+  save_info();
+
+  // MQ-Punkte-Cache loeschen, da nicht feststellbar ist, welcher der
+  // dort eingetragenen Spieler die gerade ausgetragene MQ geloest hatte.
+  ClearUsersMQCache();
+  if (find_call_out(#'DumpMiniQuests) == -1)
+    call_out(#'DumpMiniQuests, 60, this_interactive());
+  return 1;
+}
+
+int ChangeMiniQuest(mixed mq_obj, int param, mixed newvalue) {
+  if (!allowed_write_access())
+    return 0;
+
+  // MQ weder als Pfad, noch als Indexnummer angegeben?
+  if ( !stringp(mq_obj) && !intp(mq_obj) && !intp(param))
+    return MQ_KEY_INVALID;
+
+  // gewaehlter Parameter ungueltig?
+  if ( param < MQ_DATA_POINTS || param > MQ_DATA_QUERY_PERMITTED )
+    return MQ_KEY_INVALID;
+
+  // Indexnummer der MQ in den Pfad umwandeln
+  if ( intp(mq_obj) )
+    mq_obj = by_num[mq_obj][1];
+
+  // Vergebendes Objekt nicht gefunden? Bloed, das brauchen wir naemlich.
+  if (!stringp(mq_obj))
+    return MQ_KEY_INVALID;
+
+  if ( !member(miniquests, mq_obj) )
+    return MQ_ILLEGAL_OBJ;
+
+  switch(param) {
+    // MQ_DATA_QUESTNO ist nicht aenderbar, daher hier nicht behandelt, so
+    // dass Fallback auf default erfolgt.
+    // Stufenpunkte muessen Integers sein.
+    case MQ_DATA_POINTS:
+      if ( !intp(newvalue) || newvalue < 1 )
+        return MQ_KEY_INVALID;
+      break;
+    // Aufgabenbeschreibung, Titel, "geschafft"-Text und zugeordnete Region
+    // muessen Strings sein
+    case MQ_DATA_TASKDESC:
+    case MQ_DATA_TITLE:
+    case MQ_DATA_DIARYTEXT:
+    case MQ_DATA_ASSIGNED_DOMAIN:
+      if ( !stringp(newvalue) || !sizeof(newvalue) ) 
+        return MQ_KEY_INVALID;
+      break;
+    // das Sichtbarkeits- und das aktiv/inaktiv-Flag muessen 0/1 sein.
+    case MQ_DATA_VISIBLE:
+    case MQ_DATA_ACTIVE:
+      if ( !intp(newvalue) || newvalue < 0 || newvalue > 1 )
+        return MQ_KEY_INVALID;
+      break;
+    // Die Voraussetzungen muessen als Mapping eingetragen werden, das aber
+    // leer oder Null sein kann, wenn es keine Restriktionen gibt.
+    case MQ_DATA_RESTRICTIONS:
+      if ( !mappingp(newvalue) && newvalue != 0 )
+        return MQ_KEY_INVALID;
+      break;
+    // Regionszuordnung muss ein nicht-leeres Array sein, das nur aus Strings
+    // bestehen darf, die nicht leer sein duerfen.
+    case MQ_DATA_QUERY_PERMITTED:
+      if ( pointerp(newvalue) ) {
+        newvalue = filter(filter(newvalue, #'stringp), #'sizeof);
+        if (!sizeof(newvalue))
+          return MQ_KEY_INVALID;
+      }
+      else
+        return MQ_KEY_INVALID;
+      break;
+    default:
+      return MQ_KEY_INVALID;
+  }
+
+  mixed *altemq = m_entry(miniquests, mq_obj);
+  int nummer = miniquests[mq_obj,MQ_DATA_QUESTNO];
+  miniquests[mq_obj, param] = newvalue;
+  by_num[nummer] = ({miniquests[mq_obj,MQ_DATA_POINTS], mq_obj});
+  save_info();
+
+  MQMLOG(sprintf("ChangeMiniQuest: %s from %O to %O (%s)", mq_obj,
+    altemq, m_entry(miniquests, mq_obj), getuid(this_interactive())));
+
+  ClearUsersMQCache();
+  if (find_call_out(#'DumpMiniQuests) == -1)
+    call_out(#'DumpMiniQuests, 60, this_interactive());
+  return 1;
+}
+
+mixed QueryMiniQuestByName(string name) {
+  if (!allowed_write_access())
+    return 0;
+  return deep_copy(miniquests & ({name}));
+}
+
+mixed QueryMiniQuestByNumber(int nummer) {
+  // Zugriffsabsicherung erfolgt dort auch, daher hier unnoetig
+  return (by_num[nummer]?QueryMiniQuestByName(by_num[nummer][1]):0);
+}
+
+// Das vollstaendige MQ-Mapping nur als Kopie ausliefern.
+mixed QueryMiniQuests() {
+  return allowed_write_access() ? deep_copy(miniquests) : 0;
+}
+
+// De-/Aktivieren einer Miniquest, wirkt als Umschalter, d.h. eine aktive
+// MQ wird durch Aufruf dieser Funktion als inaktiv markiert und umgekehrt.
+int SwitchMiniQuestActive(string name) {
+  if (!allowed_write_access())
+    return -1;
+  // Haben wir eine solche MQ ueberhaupt?
+  if (!member(miniquests, name))
+    return -2;
+
+  // active-Flag invertieren
+  miniquests[name, MQ_DATA_ACTIVE] = !miniquests[name, MQ_DATA_ACTIVE];
+  save_info();
+
+  MQMLOG(sprintf("%s: %s (%s)",
+    (miniquests[name,MQ_DATA_ACTIVE]?"Activate":"Deactivate"), name,
+    getuid(this_interactive()))
+  );
+  return miniquests[name,MQ_DATA_ACTIVE];
+}
+
+int GiveMiniQuest(object winner) {
+  // Spieler muss existieren und interactive sein.
+  if (!winner ||
+      (this_interactive() && (this_interactive() != winner)) ||
+      ((this_player() == winner) && !query_once_interactive(winner)))
+    return MQ_ILLEGAL_OBJ;
+  // Gaeste koennen keine Miniquests bestehen.
+  if (winner->QueryGuest())
+    return MQ_GUEST;
+  // Aufrufendes Objekt existiert gar nicht?
+  if (!previous_object())
+    return MQ_ILLEGAL_OBJ;
+
+  string objname = load_name(previous_object());
+  // Miniquest muss existieren
+  if (!member(miniquests,objname))
+    return MQ_KEY_INVALID;
+  // Inaktive Miniquests koennen nicht vergeben werden.
+  if (!miniquests[objname, MQ_DATA_ACTIVE])
+    return MQ_IS_INACTIVE;
+
+  string mq = (MASTER->query_mq(getuid(winner)) || "");
+
+  // Spieler hat die MQ schonmal bestanden? Dann keine weiteren Aktivitaet
+  // noetig
+  if (test_bit(mq, miniquests[objname, MQ_DATA_QUESTNO]))
+    return MQ_ALREADY_SET;
+
+  catch(mq = set_bit(mq, miniquests[objname,MQ_DATA_QUESTNO]);publish);
+  MASTER->update_mq(getuid(winner), mq);
+
+  MQSOLVEDLOG(sprintf("%s: %s, (#%d), (Stupse %d)",
+    objname, geteuid(winner), miniquests[objname, MQ_DATA_QUESTNO],
+    miniquests[objname, MQ_DATA_POINTS]));
+
+  // Miniquest-Event ausloesen
+  EVENTD->TriggerEvent( EVT_LIB_MINIQUEST_SOLVED, ([
+            E_OBJECT: previous_object(),
+            E_OBNAME: objname,
+            E_PLNAME: getuid(winner),
+            E_MINIQUESTNAME: miniquests[objname, MQ_DATA_TITLE] ]) );
+
+  // Spielereintrag aus dem MQ-Punkte-Cache loeschen
+  m_delete(users_mq, getuid(winner));
+
+  return 1;
+}
+
+int QueryMiniQuestPoints(mixed pl) {
+  string spieler;
+
+  //if (!allowed_write_access())
+  //  return 0;
+
+  if (!pl)
+    return -1;
+
+  if (!objectp(pl) && !stringp(pl))
+    return -2;
+
+  if (objectp(pl) && !query_once_interactive(pl))
+    return -3;
+
+  if (objectp(pl))
+    spieler = getuid(pl);
+  else
+    spieler = pl;
+
+  if (!member(users_mq, spieler)) {
+    int mqpoints;
+    int p=-1;
+    string s = (MASTER->query_mq(spieler) || "");
+    while( (p=next_bit(s, p)) != -1) {
+      mqpoints+=by_num[p][0];
+    }
+    users_mq[spieler] = mqpoints;
+  }
+  return users_mq[spieler];
+}
+
+int HasMiniQuest(mixed pl, mixed name) {
+  string mq, spieler;
+
+  if (!pl || !name)
+    return MQ_ILLEGAL_OBJ;
+
+  if (!objectp(pl) && !stringp(pl))
+    return MQ_ILLEGAL_OBJ;
+
+  if (objectp(pl) && !query_once_interactive(pl))
+    return MQ_ILLEGAL_OBJ;
+
+  if (!objectp(name) && !stringp(name) && !intp(name))
+    return MQ_ILLEGAL_OBJ;
+
+  if (objectp(name))
+    name = explode(object_name(name), "#")[0];
+
+  if ( intp(name) )
+    name = by_num[name][1];
+
+  if (objectp(pl))
+    spieler = getuid(pl);
+  else
+    spieler = pl;
+
+  if (!member(miniquests,name))
+    return MQ_KEY_INVALID;
+
+  mq = (MASTER->query_mq(spieler) || "");
+
+  return test_bit(mq, miniquests[name, MQ_DATA_QUESTNO]);
+}
+
+// Zum Von-Hand-Setzen der MiniQuests
+int SetPlayerMiniQuest(string pl, string name) {
+  if(!allowed_write_access())
+    return 0;
+  if(!pl)
+    return MQ_ILLEGAL_OBJ;
+  if(!previous_object())
+    return MQ_ILLEGAL_OBJ;
+
+  if (!member(miniquests,name))
+    return MQ_KEY_INVALID;
+
+  string mq = (MASTER->query_mq(pl) || "");
+
+  if (test_bit(mq, miniquests[name,MQ_DATA_QUESTNO]))
+    return MQ_ALREADY_SET;
+
+  catch (mq = set_bit(mq, miniquests[name, MQ_DATA_QUESTNO]);publish);
+  MASTER->update_mq(pl, mq);
+
+  MQMLOG(sprintf("SetPlayerMiniQuest: %s %s (%s)",
+                 pl, name, getuid(this_interactive())));
+  // Spielereintrag aus dem MQ-Punkte-Cache loeschen
+  m_delete(users_mq, pl);
+  return 1;
+}
+
+int ClearPlayerMiniQuest(string pl, string name) {
+  if (!allowed_write_access())
+    return 0;
+  if (!pl)
+    return MQ_ILLEGAL_OBJ;
+  if (!previous_object())
+    return MQ_ILLEGAL_OBJ;
+
+  if (!member(miniquests,name))
+    return MQ_KEY_INVALID;
+
+  string mq = (MASTER->query_mq(pl) || "");
+
+  if (!test_bit(mq, miniquests[name, MQ_DATA_QUESTNO]))
+    return MQ_ALREADY_SET;
+
+  catch (mq = clear_bit(mq, miniquests[name, MQ_DATA_QUESTNO]);publish);
+  MASTER->update_mq(pl, mq);
+
+  MQMLOG(sprintf("ClearPlayerMiniQuest: %s %s (%s)",
+                 pl, name, getuid(this_interactive())));
+  // Spielereintrag aus dem MQ-Punkte-Cache loeschen
+  m_delete(users_mq, pl);
+  return 1;
+}
+
+// Umtragen von Miniquests von Objekt <old> auf Objekt <new>
+int MoveMiniQuest(string old_mqob, string new_mqob) {
+  if ( !allowed_write_access() )
+    return -1;
+
+  // Haben wir ueberhaupt einen solchen Eintrag?
+  if ( !member(miniquests, old_mqob) )
+    return -2;
+
+  // Pruefen, ob die als <new_mqob> angegebene Datei existiert.
+  if (new_mqob[<2..] == ".c")
+    new_mqob = new_mqob[0..<3];
+  new_mqob = explode(new_mqob, "#")[0];
+  new_mqob = (string)"/secure/master"->_get_path(new_mqob,0);
+  if (file_size(new_mqob+".c") <= 0)
+    return -3;
+  // Wenn das neue Objekt schon eine MQ vergibt, kann es keine weitere
+  // annehmen.
+  if ( member(miniquests, new_mqob) )
+    return -4;
+
+  // Der Miniquestliste einen neuen Key "new" mit den Daten des alten Keys
+  // hinzufuegen. m_entry() liefert alle Values dazu als Array, und der
+  // flatten-Operator "..." uebergibt dessen Elemente als einzelne Parameter.
+  m_add(miniquests, new_mqob, m_entry(miniquests, old_mqob)...);
+  m_delete(miniquests, old_mqob);
+  // Nummern-Index auch umtragen, sonst koennen Funktionen wie zB
+  // QueryMiniQuestByNumber() die neue nicht finden.
+  by_num[miniquests[new_mqob,MQ_DATA_QUESTNO]][1] = new_mqob;
+  return 1;
+}
+
+#define FRA_BIB "/d/ebene/miril/fraternitas/room/bibliothek"
+
+// Erlaubt die Abfrage aller MQs einer bestimmten Region fuer die Bibliothek
+// der kleinen und grossen Heldentaten in der Fraternitas.
+// Gibt ein Mapping der Form ([ indexnummer : titel; erledigt_Beschreibung ])
+// zurueck.
+mapping QuerySolvedMQsByDomain(mixed pl, string region) {
+  if ( !objectp(pl) && !stringp(pl) && 
+       load_name(previous_object())!=FRA_BIB) /*|| !allowed_write_access())*/
+    return ([:2]);
+
+  mapping res = m_allocate(30,2);   // reicht vermutlich
+  // Die angegebene Region muss in der Spalte MQ_DATA_ASSIGNED_DOMAIN
+  // enthalten sein, und das abfragende Objekt muss die Fraternitas-Bib sein
+  foreach(string mqobj, int mqp, int index, string task, int vis, int act,
+    string title, string donedesc, mapping restr, string domain:
+    miniquests) {
+      // aktive MQs der angeforderten Region zusammentragen, die der Spieler
+      // bestanden hat.
+      if ( domain == region && act && HasMiniQuest(pl, mqobj) )
+        m_add(res, index, title, donedesc);
+  }
+  //DEBUG(sprintf("%O\n",res));
+  return res;
+}
+#undef FRA_BIB
+
+// Abfrage der noch offenen MQs des angegebenen Spielers.
+// Zurueckgegeben wird ein Mapping mit den Miniquest-Nummern als Keys und
+// den Aufgabenbeschreibungen als Values, oder ein leeres Mapping, falls
+// das abfragende Objekt keine Zugriffsberechtigung hat, oder das 
+// uebergebene Spielerobjekt keine offenen Miniquests mehr hat.
+mapping QueryOpenMiniQuestsForPlayer(object spieler) {
+  // map() etwas beschleunigen
+  closure chk_restr = symbol_function("check_restrictions",
+                                      "/std/restriction_checker");
+  // Cache-Eintrag fuer das abfragende Objekt holen
+  string *list = mq_query_permitted[load_name(previous_object())];
+  mapping res = ([:2]); 
+  
+  if (!pointerp(list) || !sizeof(list))
+    return res;
+  // Liste der MQ-Objekte umwandeln in deren MQ-Nummer plus 
+  // Aufgabenbeschreibung, sofern der Spieler die MQ noch nicht bestanden
+  // hat, aber die Voraussetzungen erfuellt.
+  foreach ( string mq_obj : list ) 
+  {
+    // Nur wenn der Spieler die MQ noch nicht hat, kann er ueberhaupt einen
+    // Tip dazu bekommen.
+    if ( !HasMiniQuest(spieler, mq_obj) ) {
+      // Restriction Checker fragen, ob der Spieler statt des Hinweises
+      // eine Info bekommen muss, dass er eine Vorbedingung nicht erfuellt.
+      string restr_result = funcall(chk_restr, spieler, miniquests[mq_obj,
+        MQ_DATA_RESTRICTIONS]);
+      // Wenn so eine Info dabei rauskommt, wird diese in die Ergebnisliste
+      // uebernommen. In diesem Fall wird KEIN MQ-Hinweistext ausgeliefert.
+      if ( stringp(restr_result) )
+      {
+        m_add(res, miniquests[mq_obj,MQ_DATA_QUESTNO], 0, restr_result);
+      }
+      // Anderenfalls wird der Hinweistext uebernommen; einen Eintrag 
+      // bzgl. eines eventuellen Hinderungsgrundes gibt's dann nicht.
+      else
+      {
+        m_add(res, miniquests[mq_obj,MQ_DATA_QUESTNO], 
+          miniquests[mq_obj,MQ_DATA_TASKDESC], 0);
+      }
+    }
+  }
+  // Ergebnisliste zurueckgeben.
+  return res;
+}
+
+// Datenkonverter fuer das bisherige MQ-Mapping von
+// ([ obj : ({daten1..daten5}) ]) nach
+// ([ obj : daten1; daten2; ...; daten9 ]), wobei daten6..9 als Leerspalten
+// erzeugt werden.
+/*void ConvertMQData() {
+  if ( !allowed_write_access() )
+    return;
+
+  by_num=([]);
+  // spaltenweise aus dem miniquests-Mapping ein Array aus Arrays erzeugen
+  // Zunaechst die Keys des Mappings aufnehmen.
+  mixed *mqdata = ({m_indices(miniquests)});
+
+  // Dann das Datenarray spaltenweise dazu (jedes Array ist eine Spalte).
+  mqdata += transpose_array(m_values(miniquests));
+  // 1. Array: Keys, alle weiteren jeweils eine Wertespalte
+
+  // Array erzeugen als Array aus 5 Array-Elementen, die alle soviele
+  // Nullen enthalten, wie es Miniquests gibt,
+  // ({ ({0,0,...}), ({0,0,...}), ({0,0,...}), ({0,0,...}), ({0,0,...}) })
+  // dieses hinzufuegen. Sind die hinzukommenden 5 Spalten.
+  mqdata += allocate(5, allocate(sizeof(miniquests),0));
+
+  // Mapping erzeugen, indem mit dem flatten-Operator "..." die Einzel-
+  // Arrays des Datenpakets uebergeben werden. Erzeugt auf diese Weise
+  // ([ keys : daten1; daten2; daten3; daten4; daten5; 0; 0; 0; 0; 0,])
+  miniquests=mkmapping(mqdata...);
+}
+
+// Neue Daten einlesen, Visible-Flag bei allen MQs per Default auf 1 setzen.
+// Es gibt keine wirklich unsichtbaren MQs mehr.
+void ReadNewData() {
+  if ( !allowed_write_access() )
+    return;
+
+  string *import = explode(read_file("/players/arathorn/mqdata"),"\n")-({""});
+  string *fields;
+  foreach(string mqdata : import) {
+    fields = explode(mqdata, "#")-({""});
+    DEBUG(sprintf("%O\n", fields[0]));
+    if ( miniquests[fields[4], MQ_DATA_QUESTNO] != to_int(fields[0]) ) {
+      raise_error("MQ-Nummern stimmen nicht ueberein!\n");
+      return;
+    }
+    // fields[4] ist der MQ-Objektpfad
+    miniquests[fields[4], MQ_DATA_TITLE] = fields[7];
+    miniquests[fields[4], MQ_DATA_DIARYTEXT] = fields[6];
+    miniquests[fields[4], MQ_DATA_TASKDESC] = fields[5];
+    miniquests[fields[4], MQ_DATA_VISIBLE] = 1; // Default: visible
+    miniquests[fields[4], MQ_DATA_ASSIGNED_DOMAIN] = fields[8];
+    miniquests[fields[4], MQ_DATA_QUERY_PERMITTED] = fields[9];
+    if ( fields[3] != "0" ) {
+      miniquests[fields[4], MQ_DATA_RESTRICTIONS] =
+        restore_value(fields[3]+"\n");
+    }
+    else miniquests[fields[4], MQ_DATA_RESTRICTIONS] = 0;
+    if ( fields[9] != "0" )
+      miniquests[fields[4], MQ_DATA_QUERY_PERMITTED] =
+        restore_value(fields[9]+"\n");
+    else miniquests[fields[4], MQ_DATA_QUERY_PERMITTED] = 0;
+  }
+}
+*/
