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