// MorgenGrauen MUDlib
//
// player/quests.c -- quest handler
//
// $Id: quests.c 9142 2015-02-04 22:17:29Z Zesstra $

// Dieses Modul enhaelt die Quest-spezifischen Teile der Playerobjekte.
#pragma strong_types
#pragma save_types
#pragma range_check
#pragma no_clone

#define NEED_PROTOTYPES
#include <player/life.h>
#include <player/quest.h>
#include <thing/properties.h>
#include <player/base.h>
#include <living/life.h>
#undef NEED_PROTOTYPES

#include "/secure/questmaster.h"
#include <wizlevels.h>
#include <daemon.h>
#include <language.h>
#include <mail.h>
#include <defines.h>
#include <new_skills.h>
#include <properties.h>
#include <events.h>

mixed quests;

int QueryQuest(string questname);
// local properties prototype
static mixed _query_quests();
static int   _query_questpoints();

protected void create() {
  Set(P_QUESTS, NOSETMETHOD, F_SET_METHOD);
  Set(P_QUESTS, quests = ([]), F_VALUE);
  Set(P_QUESTS, SECURED, F_MODE);
  Set(P_QP, SAVE, F_MODE);
  Set(P_QP, SECURED, F_MODE);
}

varargs int GiveQuest(string questname, string message) {

  mixed *quest = QM->QueryQuest(questname);
  // Questname ungueltig
  if (!quest||!pointerp(quest)||quest==({}))
    return GQ_KEY_INVALID;
  // Unbefugter Zugriff auf deaktivierte Quest
  if (!quest[6]&&!IS_ARCH(this_interactive()))
    return GQ_IS_INACTIVE;
  // Unbefugter Zugriff
  if (member(quest[2], load_name(previous_object()))==-1 &&
      !IS_ARCH(this_interactive()))
    return GQ_ILLEGAL_OBJ;
  // Gaeste haben keine Quests.
  if(QueryGuest())
    return QQ_GUEST;

  // Gilde wird in jedem Fall informiert.
  string guild=GUILD_DIR+QueryProp(P_GUILD);
  if (find_object(guild) || file_size(guild+".c")>-1)
    catch( call_other(guild, "NotifyGiveQuest", ME, questname);publish );

  // Quest bereits gesetzt
  if (QueryQuest(questname))
    return GQ_ALREADY_SET;
  AddExp(quest[1]);
  quests += ([ questname : quest[0]; time() ]);
  force_save();
  // Event ausloesen
  EVENTD->TriggerEvent(EVT_LIB_QUEST_SOLVED,([
             E_OBJECT: ME,
             E_PLNAME: getuid(ME),
             E_ENVIRONMENT: environment(),
             E_QUESTNAME: questname,
             E_QP_GRANTED: quest[0] ]) );

  if (message && message!="") {
    if (message!="__silent__") {
      message=implode(explode(message,"@@name@@"),
          capitalize(query_real_name()));
    }
    else {
      message="";
    }
  }
  else
    message=capitalize(query_real_name())
      +" hat gerade ein Abenteuer bestanden: "+ questname+"\n";
  if(message!="")
    catch(QM->Channel(message);publish);
  catch(QM->SendMail(questname, quest, ME);publish);
  return OK;
}

int DeleteQuest(string questname) {
  // Quest ist nicht gesetzt
  if(!QueryQuest(questname))
    return DQ_NOT_SET;

  mixed *quest = QM->QueryQuest(questname);
  // Questname ungueltig
  if (!quest||!pointerp(quest)||quest==({}))
    return DQ_KEY_INVALID;
  // Unbefugter Zugriff
  if (!IS_ARCH(this_interactive()))
    return DQ_ILLEGAL_OBJ;
  AddExp(-quest[1]);
  m_delete(quests, questname);
  force_save();
  return OK;
}

int QueryQuest(string questname) {
  // Questname ist tatsaechlich in der Questliste enthalten? Alles klar!
  if ( member(quests, questname) )
    return OK;
  // Ansonsten war der Name wohl ungueltig.
  return QQ_KEY_INVALID;
}

int ModifyQuestTime(string qname, int when) {
  if ( process_call() )
    return -1;

  // Nur EM+ oder der Tagebuchmaster duerfen die Werte aendern.
  if ( !IS_ARCH(this_interactive()) &&
    load_name(previous_object())!="/d/wald/leusel/quest/objs/tagebuch-master")
    return -1;

  // Questliste ist unerwartet kein Mapping.
  if ( !mappingp(quests) )
    return -2;

  // Kein Questname angegeben, oder Spieler hat diese Quest ueberhaupt nicht
  // geloest.
  if ( !stringp(qname) || !member(quests, qname) )
    return -3;

  // Der Tagebuchmaster setzt Eintraege ggf. auf 0, wenn er keine Daten
  // findet, und EM+ wollen Eintraege auf -1 setzen koennen, um das Einlesen
  // der Daten noch einmal zu ermoeglichen, d.h. diese Werte sind zusaetzlich
  // zu gueltigen Zeitwerten erlaubt.
  if ( !intp(when) || when < -1 || when > time() )
    return -4;

  // Neuen Wert eintragen.
  quests[qname,1] = when;
  return 1;
}

int QueryQuestTime(string qname) {
  return quests[qname,1];
}

// Konvertiert Datenstruktur von quests in ein Mapping mit folgendem Aufbau:
// quests = ([ "questname" : Abenteuerpunkte; Zeit_des_Questabschlusses, ])
protected void updates_after_restore(mixed newflag) {
  // Ganz frischer Spieler? Dann keine Behandlung erforderlich.
  if ( newflag )
    return;
  // Wenn die Questliste noch kein Mapping ist, Konvertierung anstossen.
  if ( !mappingp(quests) ) {
    // Wenn noch keine Quests eingetragen sind, Leermapping eintragen.
    if ( !sizeof(quests) ) {
      quests = ([:2]);
      return;
    }
    // Vorsichtshalber Leereintraege rausziehen.
    quests -= ({({})});
    // Liste der Questzeiten aus dem Spieler auslesen. Wenn nicht vorhanden,
    // Array mit -1-Elementen passender Laenge erzeugen.
    // -1 an allen Stellen eintragen, wo bisher keine Daten vorliegen.
    // Diese werden dann vom Questtagebuch durch die Daten ersetzt.
    int *qtimes = QueryProp("questtime")||allocate(sizeof(quests), -1);
    // Falls die Questliste laenger ist als die Zeitenliste, wird letztere
    // um die fehlende Laenge in Form von -1-eintraegen ergaenzt, unter der
    // Annahme, dass die fehlenden Eintraege bisher lediglich nicht
    // eingelesen wurden. Im umgekehrten Fall werden alle Zeiten verworfen,
    // da dieser Fall eintritt, wenn einem Spieler eine Quest ausgetragen
    // wurde und die Listen in der Vergangenheit nicht synchron gehalten
    // wurden.
    if ( sizeof(qtimes) < sizeof(quests) ) {
      qtimes += allocate(sizeof(quests)-sizeof(qtimes), -1);
    }
    if ( sizeof(qtimes) > sizeof(quests) ) {
      qtimes = allocate(sizeof(quests), -1);
    }
    // Questdaten und Questzeiten zusammenpferchen. Ergibt folg. Mapping:
    // temp = ([ ({Questname1, QP1}) : Questzeit, ... ])
    mapping temp = mkmapping(quests, qtimes);
    quests = m_allocate(sizeof(quests),2);
    foreach(mixed qdata, int qtime : temp) {
      quests += ([ qdata[0] : qdata[1]; qtime ]);
    }
    if (QueryProp("questtime")) {
      SetProp("questtime",0);
      Set("questtime", SAVE, F_MODE_AD);
    }
  }
}

// **** local property methods
static int _query_questpoints() {
  int qp;

  if ( !mappingp(quests) || !sizeof(quests) ) {
    return 0;
  }

  closure qqp = symbol_function("QueryQuestPoints", QM);
  // Die aktuell gueltigen Abenteuerpunkte aus dem Questmaster holen und
  // die Questliste damit aktualisieren. qp wird als Referenz mit uebergeben
  // damit das Additionsergebnis auch nach dem Durchlauf ausserhalb der
  // Closure verfuegbar ist.
  // Falls Abenteuerpunkte < 0 existieren, wird die entsprechende Quest
  // aus der Liste ausgetragen.
  walk_mapping(quests,
    function void (string qname, int qpoints, int qtime, int sum)
    {
      qpoints = funcall(qqp, qname);
      if (qpoints<0)
        m_delete(quests,qname);
      else
        sum += qpoints;
    }, &qp);

  Set(P_QP, qp);
  return qp;
}

static mixed _query_quests() {
  return copy(quests);
}
