Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/obj/tools/merkzettel/merkzettel.c b/obj/tools/merkzettel/merkzettel.c
new file mode 100644
index 0000000..70447ab
--- /dev/null
+++ b/obj/tools/merkzettel/merkzettel.c
@@ -0,0 +1,1130 @@
+/* /obj/tools/merkzettel.c
+ Merkzettel fuer Magier
+ Autor: Zesstra
+ ggf. Changelog:
+*/
+#pragma strict_types
+#pragma no_shadow
+#pragma range_check
+#pragma pedantic
+
+inherit "/std/secure_thing";
+
+#include <properties.h>
+#include <language.h>
+#include <wizlevels.h>
+#include <moving.h>
+#include <defines.h>
+
+#define NEED_PROTOTYPES
+#include "merkzettel.h"
+#undef NEED_PROTOTYPES
+
+//Variablen
+mapping notizen;
+//mapping notizen_inaktiv;
+int maxusedID;
+static string owner; //UID des Besitzers, wird in P_AUTOLOAD gespeichert
+//static int *cache; //nach Prioritaet sortiertes Array der IDs
+
+void create() {
+ ::create();
+ SetProp(P_NAME, "Merkzettel");
+ SetProp(P_SHORT, "Ein Merkzettel");
+ AddId(({"merkzettel","zettel"}));
+ //Absicht, damit die Blueprint eine ID, P_NAME und P_SHORT hat.
+ if(!clonep(this_object())) return;
+
+ SetProp(P_LONG,
+ "Was wolltest Du gleich nochmal schoenes proggen? ;-)\n"
+ "Befehlsliste:\n"
+ "zmerke/znotiz <string> : Etwas auf den Merkzettel schreiben\n"
+ "zliste : 20 wichtigsten Notizen anzeigen\n"
+ "zliste <int> : <int> wichtigste Notizen anzeigen\n"
+ " (unwichtigste, wenn <int> negativ)\n"
+ " Angabe von 0 oder 'alle' gibt alle aus\n"
+ "zliste <int> <filter> : <int> wichtigste Notizen anzeigen\n"
+ " (Filter: 'aktiv', 'wartend'\n"
+ " 'inaktiv', 'abgehakt', 'alle'|'0')\n"
+ " Ohne Angabe eines Filter gilt 'aktiv'\n"
+ "zstatus <int> : Status von Notiz mit ID umschalten\n"
+ "zstatus <int> <int2> : Status von Notiz mit ID auf <int> setzen \n"
+ "zloesche/zrm <int> : Notiz mit ID <int> loeschen\n"
+ "zlies/zlese <int> : Notiz mit ID <int> anzeigen\n"
+ "zdeplies <int> <int2> : Abhaengigkeiten von <int> lesen, \n"
+ " : rekursiv, wenn <int2> != 0\n"
+ "zfertig/zhake <int> : Notiz mit ID <int> abhaken (fertig)\n"
+ "zprio <int1> <int2> : Notiz mit ID <int> mit Prioritaet <int2>\n"
+ " versehen.\n"
+ "zdep <int1> <int2> : Notiz mit ID <int> soll von Notiz mit ID\n"
+ " <int2> abhaengen.\n"
+ "zhelfer <int1> <namen> : Notiz mit ID <int> wird (mit)bearbeitet\n"
+ " von den angegebenen Personen\n"
+ "zergaenze <int> <text> : haengt <text> an Notiz <int> an\n"
+ "zersetze <int> <text> : ersetzt Text von Notiz <int> durch <text>\n"
+ "zexpire <int> : alle abgehakten Notizen archivieren und loeschen,\n"
+ " : die aelter als <int> Tage sind.\n"
+ "zzeige <name> ; zeige <name>, wie furchtbar viel Du zu tun hast\n"
+ "zwedel <name> : <name> aus der Ferne vor der Nase rumwedeln.\n"
+ );
+ SetProp(P_INFO,break_string("Ein Merkzettel fuer Magier. ;-)."));
+ SetProp(P_GENDER, MALE);
+ SetProp(P_ARTICLE, 1);
+ SetProp(P_WEIGHT, 0);
+ SetProp(P_VALUE, 0);
+ Set(P_AUTOLOADOBJ,#'query_autoloadobj,F_QUERY_METHOD);
+ Set(P_AUTOLOADOBJ,#'set_autoloadobj,F_SET_METHOD);
+ Set(P_AUTOLOADOBJ,PROTECTED,F_MODE_AS);
+ SetProp(P_NEVERDROP,1);
+ SetProp(P_NODROP,1);
+ AddCmd(({"zmerke","znotiz"}),"AddNotiz");
+ AddCmd(({"zliste","ztodo"}),"ListNotizen");
+ AddCmd(({"zloesche","zrm"}),"RemoveNotiz");
+ AddCmd(({"zfertig","zhake"}),"FinishNotiz");
+ AddCmd(({"zlies","zlese"}),"LiesNotiz");
+ AddCmd(({"zprio"}),"ChangePrio");
+ AddCmd(({"zdep"}),"ChangeDep");
+ AddCmd(({"zstatus"}),"ChangeStatus");
+ AddCmd(({"zersetze"}),"ErsetzeText");
+ AddCmd(({"zergaenze"}),"ErgaenzeText");
+ AddCmd(({"zhelfer","zdelegiere"}),"ChangeHelper");
+ AddCmd(({"zzeige"}),"ZeigeZettel");
+ AddCmd(({"zwedel"}),"WedelZettel");
+ AddCmd(({"zdeplies"}),"LiesDeps");
+ AddCmd(({"zexpire"}),"Expire");
+ //cache=({});
+
+}
+
+//****************** AddCmd *****************************
+int AddNotiz(string str) {
+
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ //ggf. nur Einlesen, Cache muss hier nicht aktualisiert werden ;-)
+ checkStatus(1);
+ str=(string)PL->_unparsed_args(0); //kein parsing
+ if (!stringp(str) || !sizeof(str)) {
+ tell_object(PL,
+ "Was moechtest Du Dir denn notieren?\n");
+ return(1);
+ }
+ if (sizeof(str)>MAX_NOTE_LENGTH) {
+ tell_object(PL,BS(
+ sprintf("Deine Notiz ist mit %d Zeichen zu lang! Leider passen auf "
+ "Deinen Merkzettel nur % Zeichen drauf.",
+ sizeof(str),MAX_NOTE_LENGTH)));
+ return(1);
+ }
+
+ //m_allocate gilt nur bis Funktionsende, daher hilft das in
+ //checkStatus leider nicht.
+ if (!mappingp(notizen) || !sizeof(notizen))
+ notizen=m_allocate(0,7);
+
+ //freie ID finden (maxusedID+1 sollte die naechste frei sein, aber falls
+ //da mal was kaputtgegangen ist: Pruefen ;-) )
+ while(member(notizen,maxusedID)) {maxusedID++;}
+ //Reihenfolge: s. merkzettel.h
+ notizen+=([maxusedID:str;0;time();({});({});NOTE_ACTIVE;0]);
+/* notizen+=([maxusedID]);
+ notizen[maxusedID,NOTE_TEXT]=str;
+ notizen[maxusedID,NOTE_PRIO]=0;
+ notizen[maxusedID,NOTE_STARTTIME]=time();
+ notizen[maxusedID,NOTE_DEPS]=({});
+*/
+
+ //cache=({}); //cache invalidieren
+ //in Kuerze speichern, aber nicht fuer jede Aenderung speichern
+ save_me(60);
+ tell_object(PL,BS(
+ sprintf("Du schreibst sorgfaeltig Deine Notiz auf Deinen Merkzettel. "
+ "Es ist nun die %d. Notiz.",maxusedID)));
+ tell_room(environment(TI),
+ BS(sprintf("%s notiert sich etwas auf %s Merkzettel.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int LiesNotiz(string str) {
+ int id;
+
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
+ tell_object(PL,
+ "Welche Notiz moechtest Du lesen? Bitte eine ID angeben!\n");
+ return(1);
+ }
+ if (!checkStatus()) {
+ tell_object(PL,
+ "Es gibt keine Notiz, die Du lesen koenntest!\n");
+ return(1);
+ }
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ //Ausgabetext holen und ausgeben
+ tell_object(PL,sprintf("\nDu vertiefst Dich in Deinen Merkzettel und liest:\n%s\n",_LiesNotiz(id)));
+ tell_room(environment(TI),
+ BS(sprintf("%s liest etwas auf %s Merkzettel.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int RemoveNotiz(string str) {
+ int id;
+
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
+ tell_object(PL,
+ "Welche Notiz moechtest Du ausradieren? Bitte eine ID angeben!\n");
+ return(1);
+ }
+ if (!checkStatus()) {
+ tell_object(PL,
+ "Es gibt keine Notiz, die Du ausradieren koenntest!\n");
+ return(1);
+ }
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ //direkt Loeschen, keine Kopie, daher m_delete()
+ m_delete(notizen,id);
+ //in Kuerze speichern, aber nicht fuer jede Aenderung speichern
+ save_me(60);
+ //cache invalidieren
+ //cache=({});
+ tell_object(PL,
+ sprintf("Sorgfaeltig radierst Du Notiz %d von Deinem Merkzettel.\n",
+ id));
+ tell_room(environment(TI),
+ BS(sprintf("%s radiert sorgfaeltig etwas von %s Merkzettel.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int FinishNotiz(string str) {
+ int id;
+ mixed liste;
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
+ tell_object(PL,
+ "Welche Notiz moechtest Du abhaken? Bitte eine ID angeben!\n");
+ return(1);
+ }
+ if (!checkStatus()) {
+ tell_object(PL,
+ "Es gibt keine Notiz, die Du abhaken koenntest!\n");
+ return(1);
+ }
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ if(notizen[id,NOTE_STATUS]==NOTE_FINISHED) {
+ tell_object(PL,
+ sprintf("Notiz %d ist schon abgehakt!\n",id));
+ return(1);
+ }
+ liste=getUnresolvedDeps(id); //liste ist Array von ints
+ if (sizeof(liste)) {
+ liste=map(liste,#'to_string); //liste ist Array von strings
+ tell_object(PL,BS(sprintf("Du kannst Notiz %d nicht abhaken, da noch "
+ "nicht erledigte Abhaengigkeiten existieren. IDs: %s.",
+ id,CountUp(liste))));
+ return(1);
+ }
+ notizen[id,NOTE_STATUS]=NOTE_FINISHED;
+ notizen[id,NOTE_CLOSETIME]=time();
+ tell_object(PL,BS(
+ sprintf("Du malst zufrieden einen schoenen grossen Haken hinter "
+ "die Notiz Nr. %d. Hach - was bist Du nun zufrieden! :-)\n",id)));
+ tell_room(environment(TI),
+ BS(sprintf("%s hakt erfreut etwas auf %s Merkzettel ab.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int ListNotizen(string str) {
+ int zahl,notizzahl,i,id,filterstate;
+ string txt;
+ string *arr;
+ status invers;
+
+ if(!objectp(TI)) return(0);
+ str=(string)PL->_unparsed_args(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ if (!notizzahl=checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ //Argumente parsen
+ if(stringp(str) && sizeof(str))
+ arr=explode(str," ");
+ if (pointerp(arr)) arr-=({""}); //doppelte leerzeichen im String
+ if (pointerp(arr) && sizeof(arr)>=2) {
+ zahl=to_int(arr[0]);
+ switch(arr[1]) {
+ case "aktiv":
+ filterstate=NOTE_ACTIVE; break;
+ case "inaktiv":
+ filterstate=NOTE_INACTIVE; break;
+ case "wartend":
+ case "pending":
+ filterstate=NOTE_PENDING; break;
+ case "abgehakt":
+ case "fertig":
+ case "abgeschlossen":
+ filterstate=NOTE_FINISHED; break;
+ case "alle":
+ filterstate=0; break;
+ default:
+ filterstate=to_int(arr[1]);
+ break;
+ }
+ }
+ else if (pointerp(arr) && sizeof(arr)==1) {
+ zahl=to_int(arr[0]);
+ filterstate=NOTE_ACTIVE;
+ }
+ else {
+ //Voreinstellungen
+ zahl=20;
+ filterstate=NOTE_ACTIVE;
+ }
+ //1. Argument "all" oder "alle" ist: alle anzeigen
+ if (pointerp(arr) && sizeof(arr) && stringp(arr[0]) &&
+ sizeof(arr[0]) && arr[0]=="alle")
+ zahl=notizzahl; //alle anzeigen
+
+ //wenn die gewuenschte Zahl die Anzahl gespeicherter
+ //Notizen ueberschreitet (oder 0 ist)
+ if(!zahl || zahl>notizzahl) zahl=notizzahl;
+
+ //wenn 1. Argument negativ: Liste in umgekehrter Reihenfolge
+ if (zahl<0) {
+ invers=1;
+ zahl=zahl*-1;
+ }
+ txt=sprintf("\n|%:9|s|%:56|s|%:7|s|\n","ID","Notiztext","Prio.");
+ txt+=sprintf("%:78'-'s\n","-");
+ //alle passenden Notizen ermitteln
+ arr=filter(m_indices(notizen),#'note_filter,filterstate);
+ //sortieren
+ arr=sort_array(arr,#'sort_prio);
+ if (zahl>sizeof(arr)) zahl=sizeof(arr);
+ //ausgeben
+ for(i=0;i<zahl;i++) {
+ if (!invers)
+ id=to_int(arr[i]);
+ else
+ //von hinten
+ id=to_int(arr[<i+1]); // i+1 ist wirklich Absicht. ;-)
+ txt+=sprintf("| %:7|d | %:54-s | %:5|d |\n",
+ id,
+ //nur bis zum ersten \n anzeigen
+ explode(notizen[id,NOTE_TEXT],"\n")[0],
+ notizen[id,NOTE_PRIO]);
+ }
+ txt+=sprintf("%:78'-'s\n\n","-");
+ tell_object(PL,txt);
+ tell_room(environment(TI),
+ BS(sprintf("%s wirft einen Blick auf %s Merkzettel.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihren" : "seinen")
+ )),({TI}));
+ return(1);
+}
+
+int ChangeDep(string str) {
+ int id;
+ string *arr;
+ int *deps;
+
+ notify_fail("Bitte eine ID und eine min. eine Abhaengigkeit angeben!\n");
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return(0);
+
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ arr=explode(str," ");
+ arr-=({""}); // "" entfernen, wichtig. ;-)
+ if (sizeof(arr)<2)
+ return(0);
+ id=to_int(arr[0]);
+ arr-=({arr[0]}); //eigene ID loeschen
+ if (sizeof(arr)<1)
+ return(0); //mehrfach die eigene ID gilt nicht.;-)
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ //dies updated direkt die Abhaengigkeiten in 'notizen'!
+ map(arr,#'update_deps,id);
+ save_me(60);
+ tell_object(PL,BS(
+ sprintf("Du aenderst die Abhaengigkeiten von Notiz %d.\n",
+ id)));
+ tell_room(environment(TI),
+ BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int ChangePrio(string str) {
+ int id, prio;
+ string* arr;
+
+ notify_fail("Bitte eine ID und eine neue Prioritaet angeben!\n");
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return(0);
+
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ arr=explode(str," ");
+ if (sizeof(arr)>2) {
+ notify_fail("Bitte nur eine ID und eine neue Prioritaet angeben!");
+ return(0);
+ }
+ else if(sizeof(arr)==2) {
+ id=to_int(arr[0]);
+ prio=to_int(arr[1]);
+ }
+ else
+ return(0);
+
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ notizen[id,NOTE_PRIO]=prio;
+ //cache=({}); //cache invalidieren
+ save_me(60);
+ tell_object(PL,BS(
+ sprintf("Du aenderst die Prioritaet von Notiz %d auf %d.",
+ id,notizen[id,NOTE_PRIO])));
+ tell_room(environment(TI),
+ BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int ChangeHelper(string str) {
+ int id;
+ string *arr;
+
+ notify_fail("Bitte eine ID und eine min. einen Namen angeben!\n");
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return(0);
+
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ arr=explode(str," ");
+ arr-=({""}); // "" entfernen, wichtig. ;-)
+ if (sizeof(arr)<2)
+ return(0);
+ id=to_int(arr[0]);
+ arr-=({arr[0]}); //eigene ID loeschen
+ if (sizeof(arr)<1)
+ return(0); //mehrfach die eigene ID gilt nicht.;-)
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ notizen[id,NOTE_HELPER]=arr;
+ save_me(60);
+ tell_object(PL,BS(
+ sprintf("Mitarbeiter von Notiz %d geaendert.",id)));
+ tell_room(environment(TI),
+ BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int ChangeStatus(string str) {
+ int id, state;
+ string *arr;
+
+ notify_fail(BS(
+ "Bitte min. eine ID angeben, um den Status umzuschalten oder "
+ "eine ID und den neuen Status (1==Aktiv, 2==Wartend, "
+ "-1==Inaktiv/Pause)"));
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return(0);
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ arr=explode(str," ");
+ if (sizeof(arr)>2) {
+ notify_fail("Bitte nur eine ID und einen neuen Status angeben!");
+ return(0);
+ }
+ else if(sizeof(arr)==2) {
+ id=to_int(arr[0]);
+ state=to_int(arr[1]);
+ }
+ else if(sizeof(arr)==1) {
+ id=to_int(arr[0]);
+ }
+ else
+ return(0);
+
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ if(member(NOTE_STATES,state)==-1) {
+ if (notizen[id,NOTE_STATUS]==NOTE_ACTIVE) {
+ tell_object(PL,BS(
+ sprintf("%d ist ein unbekannter Status, setzt Notiz %d auf "
+ "'Inaktiv'.",state,id)));
+ state=NOTE_INACTIVE;
+ }
+ else {
+ tell_object(PL,BS(
+ sprintf("%d ist ein unbekannter Status, setzt Notiz %d auf "
+ "'Aktiv'.",state,id)));
+ state=NOTE_ACTIVE;
+ }
+ }
+ notizen[id,NOTE_STATUS]=state;
+ save_me(60);
+ tell_object(PL,BS(
+ sprintf("Status von Notiz %d geaendert.",id)));
+ tell_room(environment(TI),
+ BS(sprintf("%s kritzelt auf %s Notizzettel herum.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int ErsetzeText(string str) {
+ string *arr;
+ int id;
+
+ notify_fail("Bitte eine ID und einen neuen Text angeben!\n");
+ if(!objectp(TI)) return(0);
+
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return(0);
+
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ arr=explode(str," ");
+ arr-=({""}); // "" entfernen
+ if (sizeof(arr)<2)
+ return(0);
+ id=to_int(arr[0]);
+ str=implode(arr[1..]," "); //text wiederherstellen, ohne erstes Element
+ if (!sizeof(str)) return(0);
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ notizen[id,NOTE_TEXT]=str;
+ save_me(60);
+ tell_object(PL,BS(
+ sprintf("Text von Notiz %d ersetzt.",id)));
+ tell_room(environment(TI),
+ BS(sprintf("%s radiert zuerst etwas auf %s Notizzettel herum und "
+ "schreibt anschliessend sorgfaeltig etwas neues auf.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int ErgaenzeText(string str) {
+ string *arr;
+ int id;
+
+ notify_fail("Bitte eine ID und einen Text angeben!\n");
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return(0);
+
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ arr=explode(str," ");
+ arr-=({""}); // "" entfernen
+ if (sizeof(arr)<2)
+ return(0);
+ id=to_int(arr[0]);
+ str="\n";
+ str+=implode(arr[1..]," "); //text wiederherstellen
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ notizen[id,NOTE_TEXT]+=str;
+ save_me(60);
+ tell_object(PL,BS(
+ sprintf("Text von Notiz %d ergaenzt.",id)));
+ tell_room(environment(TI),
+ BS(sprintf("%s ergaenzt etwas auf %s Notizzettel.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int ZeigeZettel(string str) {
+ //anderen zeigen, wie furchtbar viel man zu tun hat.
+ object pl;
+ int count;
+ int *ids;
+
+ notify_fail("Wem willst Du Deinen Merkzettel zeigen?\n");
+ if (!objectp(TI)) return(0);
+ if (!environment() || !environment(environment()))
+ return(0);
+ if (!stringp(str) || !sizeof(str)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun? Du willst anderen Leuten doch bestimmt nicht "
+ "zeigen, dass Du nix zu tun hast, oder?"));
+ return(1);
+ }
+ if(!objectp(pl=present(str,environment(environment()))))
+ return(0);
+ if (!living(pl))
+ return(0);
+
+ ids=filter(m_indices(notizen),#'note_filter,NOTE_ACTIVE);
+ tell_object(TI,BS("Du zeigst "+pl->Name(WEM)+" voller Stolz deinen vollen "
+ "Merkzettel."));
+ tell_room(environment(environment()),BS(sprintf(
+ "%s zeigt %s %s Merkzettel.",
+ TI->Name(WER),pl->Name(WEM),TI->QueryPossPronoun(MALE,WEN,SINGULAR))),
+ ({TI,pl}));
+ switch(sizeof(ids)) {
+ case 0..10:
+ tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
+ "wirfst einen schnellen Blick darueber und zaehlst %d "
+ "Notizen. Na, soviel ist das ja zum Glueck noch nicht.",
+ TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
+ sizeof(ids))));
+ break;
+ case 11..20:
+ tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
+ "wirfst einen schnellen Blick darueber und zaehlst %d "
+ "Notizen. Oh, das ist ja schon so einiges!",
+ TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
+ sizeof(ids))));
+ break;
+ default:
+ tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
+ "wirfst einen schnellen Blick darueber und zaehlst %d "
+ "Notizen. Puuuh. %s hat ganz schoen viel zu tun! In "
+ "Dir regt sich leises Mitleid.",
+ TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
+ sizeof(ids),TI->Name(WER) )));
+ break;
+ }
+ return(1);
+ }
+
+int WedelZettel(string str) {
+ object pl;
+ string rwedel;
+ //wedelt anderen mit dem Zettel vor der Nase herum.
+ notify_fail("Wem willst Du Deinen Merkzettel zeigen?\n");
+ if (!objectp(TI)) return(0);
+ if (!environment() || !environment(environment()))
+ return(0);
+ if (!stringp(str) || !sizeof(str)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ if (!objectp(pl=find_player(str))) return(0);
+ if (!present(pl,environment(environment())))
+ rwedel="aus der Ferne";
+
+ tell_object(PL,BS("Du wedelst "+pl->Name(WEM)
+ + (rwedel?" "+rwedel:"")
+ +" heftig mit Deinem Merkzettel vor der Nase herum."));
+ tell_object(pl,BS(PL->Name(WER)+ " wedelt Dir "
+ + (rwedel?rwedel+" ":"") +"heftig mit "
+ +PL->QueryPossPronoun(MALE,WEM,SINGULAR)
+ +" Merkzettel vor der Nase herum."));
+ tell_room(environment(pl),BS(PL->Name(WER) + " wedelt "
+ +pl->Name(WEM) + (rwedel?" "+rwedel:"") + " heftig mit "
+ +PL->QueryPossPronoun(MALE,WEM,SINGULAR)
+ +" Merkzettel vor der Nase herum."),({PL,pl}));
+ return(1);
+}
+
+int LiesDeps(string str) {
+ //erstmal (rekursiv) alle Abhaengigkeiten einer Notiz ermitteln
+ string *arr;
+ int id, rec, i;
+ int *liste;
+
+ notify_fail("Bitte eine ID und ggf. '1' fuer rekursive Suche angeben!\n");
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return(0);
+
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ arr=explode(str," ");
+ arr-=({""}); // "" entfernen
+ if (sizeof(arr)==1) {
+ id=to_int(arr[0]);
+ rec=0; //Standard: keine Rekursion
+ }
+ else if (sizeof(arr)>=2) {
+ id=to_int(arr[0]);
+ rec=to_int(arr[1]);
+ }
+ else {
+ return(0);
+ }
+ if (!member(notizen,id)) {
+ tell_object(PL,
+ sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+ return(1);
+ }
+ //Notizen, von denen id abhaengt, holen
+ //und nur aktive Notizen behalten
+ liste=filter(getDeps(id,rec),#'note_filter,NOTE_ACTIVE);
+ //nach Prioritaet sortieren
+ liste=sort_array(liste,#'sort_prio);
+ //dann mal ausgeben.
+ i=sizeof(liste);
+ tell_object(PL,BS(sprintf("Du vertiefst Dich in die Abhaenhigkeiten von Notiz: %d\n",id)));
+ while(i--) {
+ tell_object(PL,_LiesNotiz(liste[i])+"\n");
+ }
+ tell_room(environment(TI),
+ BS(sprintf("%s liest etwas auf %s Merkzettel.\n",
+ capitalize((string)TI->name(WER)),
+ (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
+ )),({TI}));
+ return(1);
+}
+
+int Expire(string str) {
+ float age;
+ int sekunden, i;
+ int *liste;
+ string res;
+
+ notify_fail("Bitte angeben, wie alt zu loeschende Notizen sein sollen (in Tagen)!\n");
+ if(!objectp(TI)) return(0);
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ str=(string)PL->_unparsed_args(0);
+ if (!stringp(str) || !sizeof(str))
+ return(0);
+ age=to_float(str);
+ if (age<=0) return(0);
+ sekunden=time() - (int)(age*86400);
+ if (!checkStatus()) {
+ tell_object(PL,BS(
+ "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+ "Hast Du nix zu tun?"));
+ return(1);
+ }
+ //abgehakte Notizen ermitteln
+ liste=filter(m_indices(notizen),#'note_filter,NOTE_FINISHED);
+ //Notizen ermitteln, die lang genug abgehakt sind.
+ liste=filter(liste,#'aelter_als,sekunden);
+ if (!sizeof(liste)) {
+ tell_object(PL,BS("Keine Notizen gefunden, die lang genug abgehakt sind."));
+ return(1);
+ }
+ res=sprintf("Archivierte Notizen vom %s\n\n",dtime(time()));
+ for (i=sizeof(liste);i--;) {
+ //Infos noch einmal ausgeben und loeschen
+ res+=_LiesNotiz(liste[i])+"\n";
+ m_delete(notizen,liste[i]);
+ }
+ res+="\n";
+ write_file(ARCHIVE(owner),res);
+ tell_object(PL,BS(sprintf(
+ "%d alte Notizen wurden nach %s archiviert und geloescht.",
+ sizeof(liste),ARCHIVE(owner))));
+ return(1);
+}
+
+//
+static string _LiesNotiz(int id) {
+ //Funktion verlaesst sich drauf, dass id existiert. ;-)
+ string res,txt;
+ res=BSL(sprintf("%-11s: %d","Notiz-Nr.",id));
+ res+=break_string(notizen[id,NOTE_TEXT],78,"Notiztext : ",
+ BS_INDENT_ONCE|BS_LEAVE_MY_LFS);
+ res+=sprintf("%-11s: %d\n","Prioritaet",notizen[id,NOTE_PRIO]);
+ //wenn nicht aktiv: Status anzeigen
+ if (notizen[id,NOTE_STATUS]!=NOTE_ACTIVE) {
+ switch(notizen[id,NOTE_STATUS]) {
+ case NOTE_INACTIVE:
+ txt="Inaktiv/Pause";
+ break;
+ case NOTE_FINISHED:
+ txt="Abgeschlossen";
+ break;
+ case NOTE_PENDING:
+ txt="Warte auf Rueckmeldung";
+ break;
+ default: txt=sprintf("%d",notizen[id,NOTE_STATUS]); break;
+ }
+ res+=sprintf("%-11s: %s\n","Status",txt);
+ //wenn abgeschlossen: Endezeit anzeigen
+ if (notizen[id,NOTE_STATUS]==NOTE_FINISHED)
+ res+=sprintf("%-11s: %s\n","Endezeit",
+ dtime(notizen[id,NOTE_CLOSETIME]));
+ }
+ res+=sprintf("%-11s: %s\n","Merkzeit",dtime(notizen[id,NOTE_STARTTIME]));
+ //nur wenn Abhaengigkeiten: anezeigen
+ if (pointerp(notizen[id,NOTE_DEPS]) && sizeof(notizen[id,NOTE_DEPS])) {
+ txt=implode(map(notizen[id,NOTE_DEPS],#'to_string)," ");
+ res+=sprintf("%-11s: %s\n","abh. von",txt);
+ }
+ //nur wenn Helfer: anezeigen
+ if (pointerp(notizen[id,NOTE_HELPER]) && sizeof(notizen[id,NOTE_HELPER]))
+ res+=sprintf("%-11s: %s\n","Helfer",
+ implode(notizen[id,NOTE_HELPER]," "));
+ return(res);
+}
+
+//int. Helfer
+static int note_filter(int id,int filterstate) {
+ //kein filter -> passt immer
+ if (!filterstate) return(1);
+ if (member(notizen,id) &&
+ notizen[id,NOTE_STATUS]==filterstate)
+ return(1);
+ return(0);
+}
+
+static int aelter_als(int id,int zeit) {
+ //liefert 1 zurueck, wenn Schliesszeit der Notiz laenger als 'sekunden' her ist, sonst 0.
+ if (notizen[id,NOTE_CLOSETIME]<zeit) return(1);
+ return(0);
+}
+
+static string update_deps(string str,int id) {
+ //wandelt str nach int um
+ //schaut, ob dep positiv und noch nicht bekannt ist, wenn ja:
+ //zu deps hinzufuegen
+ //wenn dep < 0 und bekannt ist: aus deps entfernen
+ //Rueckgabewert ist egal. ;-)
+ int dep;
+ dep=to_int(str);
+ if (dep>0 && member(notizen[id,NOTE_DEPS],dep)==-1)
+ notizen[id,NOTE_DEPS]+=({dep});
+ else if (dep<0 && member(notizen[id,NOTE_DEPS],dep*-1)!=-1)
+ notizen[id,NOTE_DEPS]-=({dep*-1});
+ return("");
+}
+
+static int *getDeps(int id, int rec) {
+ //ermittelt (ggf. rekursiv bei rec!=0) die Abhaengigkeiten einer Notiz
+ int i, *liste;
+ liste=notizen[id,NOTE_DEPS];
+ //jetzt ggf. noch rekursiv weiterholen
+ if (rec) {
+ i=0;
+ while(i<sizeof(liste)) {
+ //nicht schreien. ;-)
+ if (get_eval_cost()<100000) {
+ tell_object(PL,"Fehler: Zu lange Rekursion bei "
+ "Ermitteln der Abhaengigkeiten, Abbruch\n");
+ return(liste);
+ }
+ //Abhaengigkeiten der anderen Abhaengigkeiten hinten anhaengen.
+ liste+=notizen[liste[i],NOTE_DEPS];
+ i++;
+ }
+ }
+ return(liste);
+}
+
+static int *getUnresolvedDeps(int id) {
+ //liefert die Anzahl der nicht abgehakten Notizen, von denen eine
+ //Notiz abhaengig ist (rekursiv)
+ int *liste;
+ //Abhaengigkeiten rekursiv holen
+ liste=getDeps(id,1);
+ //nicht abgehakte zurueckgeben
+ return(liste-filter(liste,#'note_filter,NOTE_FINISHED));
+}
+
+void init() {
+ ::init();
+ //wenn kein Env, Env kein magier oder nicht der Eigentuemer ist: weg
+ if (!objectp(environment()) || !IS_LEARNER(environment())
+ || (stringp(owner) && getuid(environment())!=owner) ) {
+ if (find_call_out("remove") == -1)
+ call_out("remove",1,1);
+ return;
+ }
+ //beim erstmaligen Bewegen in einen Magier wird der als Eigentuemer
+ //registriert. Danach kommt diese Info aus P_AUTOLOAD
+ if (!stringp(owner))
+ owner=getuid(environment());
+}
+
+static nomask status check_allowed() {
+ //Zugriff auf die Daten fuer den Eigentuemer
+ if(objectp(this_interactive()) &&
+ getuid(this_interactive())==owner
+ && !process_call())
+ return(1);
+ return(0);
+}
+
+protected int restore_me() {
+ //laedt Savefile im Home vom Magier
+ if(!stringp(owner)) return(0);
+ if(!restore_object(SAVEFILE(owner))) {
+ maxusedID=1;
+ notizen=0;
+ //cache=({});
+ return(0);
+ }
+ return(1);
+}
+
+varargs protected void save_me(int delay) {
+ //speichert Savefile im Home vom Magier
+ if(!stringp(owner)) return;
+ //wenn maxusedID==0 wurde der zettel noch nicht ordentlich initialisiert
+ //bzw. restauriert. In diesem Fall wuerde ein leeres Savefile geschrieben
+ if (maxusedID==0)
+ restore_me();
+ if(!delay)
+ //direkt speichen. ;-)
+ save_object(SAVEFILE(owner));
+ else {
+ //verzoegert speichern, wenn schon ein call_out laeuft, nehm ich den
+ if(find_call_out(#'save_me)==-1)
+ call_out(#'save_me,delay);
+ }
+}
+
+varargs int remove(int silent) {
+ //erstmal speichern. ;-)
+ save_me();
+ return ::remove(silent);
+}
+
+static string query_autoloadobj() {
+ //in P_AUTOLOAD wird nur der Eigentuemer gespeichert
+ return owner;
+}
+
+static string set_autoloadobj(mixed arg) {
+ //Eigentuemer aus P_AUTOLOAD restaurieren
+ if (stringp(arg))
+ owner=arg;
+ return(owner);
+}
+
+//Shadow unerwuenscht
+int query_prevent_shadow() {return(1);}
+
+varargs static int checkStatus(int nocache) {
+ //schaut, ob Notizen da, ob der Cache Ok ist, etc.
+ //liefert Anzahl der Notizen auf dem Merkzettel
+
+ //wenn keine Notizen da sind, schauen, ob das Savefile eingelesen werden
+ //kann
+ if (!mappingp(notizen) || !sizeof(notizen))
+ restore_me();
+ if (!mappingp(notizen)) return(0);
+/* Cache ist eigentlich nicht noetig und mir gerade zu unpraktisch, raus damit.
+ //wenn keine Aktualisierung des Cache erwuenscht ist
+ if(nocache) return(0);
+
+ if (sizeof(notizen)) {
+ if(!pointerp(cache) || !sizeof(cache)) {
+ //cache erneuern
+ cache=sort_array(m_indices(notizen),"sort_prio");
+ }
+ }
+ return(sizeof(cache)); //aequivalent zu sizeof(notizen)
+ */
+ return(sizeof(notizen));
+}
+
+static status sort_prio(int key1, int key2) {
+ // 1, falls falsche Reihenfolge,
+ // 0, wenn richtige
+ // und zwar _absteigend_, also hoechste Prio in liste[0] !
+ return(notizen[key1,NOTE_PRIO]<=notizen[key2,NOTE_PRIO]);
+}
+
+
+//*******************************************************
+
+// Debugging
+mapping QueryNotizen() {
+
+ if(!check_allowed()) {
+ if(objectp(this_interactive()))
+ tell_object(this_interactive(),
+ BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+ return(0);
+ }
+ checkStatus();
+ return(notizen);
+}
+
+//int *QueryCache() {return(cache);}
+
+int QuerySize() {return(sizeof(notizen));}
+
+string QueryOwner() {return(owner);}