// 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)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 = ([]);

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