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

private void RebuildMQCache() {
  by_num = ([]);
  mq_query_permitted = ([]);
  walk_mapping(miniquests, #'make_num /*'*/ );
}

void create() {
  seteuid(getuid(ME));
  if (!restore_object(QUESTS)) {
    save_info();
  }

  RebuildMQCache();
  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 = ([]);
  RebuildMQCache();
  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)master()->make_path_absolute(allowedobj[i]);
    }
  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 = ([]);
  RebuildMQCache();

  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; dies wird von der
 *    Bibliothek in der Fraternitas (/d/ebene/miril/fraternitas/room/bibliothek) 
 *    ausgewertet. Diese kennt (Stand 2019-07-30) folgende Regionen: 
 *    #define REGIONEN ({"wald","ebene","polar","wueste","inseln",\
 *                  "unterwelt","fernwest","dschungel","gebirge"})
 *    D.h. MiniQuests im Verlorenen Land sollten als "inseln" geschluesselt
 *    werden. 
 *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()->make_path_absolute(allowedobj);
  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)master()->make_path_absolute(new_mqob);
  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 ) 
  {
    // Ist die MQ nicht aktiv, ist der Rest hinfaellig.
    if(!miniquests[mq_obj,MQ_DATA_ACTIVE]) continue;

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