blob: 70447abc7679f58718b3746cd41adab09cf1af81 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001/* /obj/tools/merkzettel.c
2 Merkzettel fuer Magier
3 Autor: Zesstra
4 ggf. Changelog:
5*/
6#pragma strict_types
7#pragma no_shadow
8#pragma range_check
9#pragma pedantic
10
11inherit "/std/secure_thing";
12
13#include <properties.h>
14#include <language.h>
15#include <wizlevels.h>
16#include <moving.h>
17#include <defines.h>
18
19#define NEED_PROTOTYPES
20#include "merkzettel.h"
21#undef NEED_PROTOTYPES
22
23//Variablen
24mapping notizen;
25//mapping notizen_inaktiv;
26int maxusedID;
27static string owner; //UID des Besitzers, wird in P_AUTOLOAD gespeichert
28//static int *cache; //nach Prioritaet sortiertes Array der IDs
29
30void create() {
31 ::create();
32 SetProp(P_NAME, "Merkzettel");
33 SetProp(P_SHORT, "Ein Merkzettel");
34 AddId(({"merkzettel","zettel"}));
35 //Absicht, damit die Blueprint eine ID, P_NAME und P_SHORT hat.
36 if(!clonep(this_object())) return;
37
38 SetProp(P_LONG,
39 "Was wolltest Du gleich nochmal schoenes proggen? ;-)\n"
40 "Befehlsliste:\n"
41 "zmerke/znotiz <string> : Etwas auf den Merkzettel schreiben\n"
42 "zliste : 20 wichtigsten Notizen anzeigen\n"
43 "zliste <int> : <int> wichtigste Notizen anzeigen\n"
44 " (unwichtigste, wenn <int> negativ)\n"
45 " Angabe von 0 oder 'alle' gibt alle aus\n"
46 "zliste <int> <filter> : <int> wichtigste Notizen anzeigen\n"
47 " (Filter: 'aktiv', 'wartend'\n"
48 " 'inaktiv', 'abgehakt', 'alle'|'0')\n"
49 " Ohne Angabe eines Filter gilt 'aktiv'\n"
50 "zstatus <int> : Status von Notiz mit ID umschalten\n"
51 "zstatus <int> <int2> : Status von Notiz mit ID auf <int> setzen \n"
52 "zloesche/zrm <int> : Notiz mit ID <int> loeschen\n"
53 "zlies/zlese <int> : Notiz mit ID <int> anzeigen\n"
54 "zdeplies <int> <int2> : Abhaengigkeiten von <int> lesen, \n"
55 " : rekursiv, wenn <int2> != 0\n"
56 "zfertig/zhake <int> : Notiz mit ID <int> abhaken (fertig)\n"
57 "zprio <int1> <int2> : Notiz mit ID <int> mit Prioritaet <int2>\n"
58 " versehen.\n"
59 "zdep <int1> <int2> : Notiz mit ID <int> soll von Notiz mit ID\n"
60 " <int2> abhaengen.\n"
61 "zhelfer <int1> <namen> : Notiz mit ID <int> wird (mit)bearbeitet\n"
62 " von den angegebenen Personen\n"
63 "zergaenze <int> <text> : haengt <text> an Notiz <int> an\n"
64 "zersetze <int> <text> : ersetzt Text von Notiz <int> durch <text>\n"
65 "zexpire <int> : alle abgehakten Notizen archivieren und loeschen,\n"
66 " : die aelter als <int> Tage sind.\n"
67 "zzeige <name> ; zeige <name>, wie furchtbar viel Du zu tun hast\n"
68 "zwedel <name> : <name> aus der Ferne vor der Nase rumwedeln.\n"
69 );
70 SetProp(P_INFO,break_string("Ein Merkzettel fuer Magier. ;-)."));
71 SetProp(P_GENDER, MALE);
72 SetProp(P_ARTICLE, 1);
73 SetProp(P_WEIGHT, 0);
74 SetProp(P_VALUE, 0);
75 Set(P_AUTOLOADOBJ,#'query_autoloadobj,F_QUERY_METHOD);
76 Set(P_AUTOLOADOBJ,#'set_autoloadobj,F_SET_METHOD);
77 Set(P_AUTOLOADOBJ,PROTECTED,F_MODE_AS);
78 SetProp(P_NEVERDROP,1);
79 SetProp(P_NODROP,1);
80 AddCmd(({"zmerke","znotiz"}),"AddNotiz");
81 AddCmd(({"zliste","ztodo"}),"ListNotizen");
82 AddCmd(({"zloesche","zrm"}),"RemoveNotiz");
83 AddCmd(({"zfertig","zhake"}),"FinishNotiz");
84 AddCmd(({"zlies","zlese"}),"LiesNotiz");
85 AddCmd(({"zprio"}),"ChangePrio");
86 AddCmd(({"zdep"}),"ChangeDep");
87 AddCmd(({"zstatus"}),"ChangeStatus");
88 AddCmd(({"zersetze"}),"ErsetzeText");
89 AddCmd(({"zergaenze"}),"ErgaenzeText");
90 AddCmd(({"zhelfer","zdelegiere"}),"ChangeHelper");
91 AddCmd(({"zzeige"}),"ZeigeZettel");
92 AddCmd(({"zwedel"}),"WedelZettel");
93 AddCmd(({"zdeplies"}),"LiesDeps");
94 AddCmd(({"zexpire"}),"Expire");
95 //cache=({});
96
97}
98
99//****************** AddCmd *****************************
100int AddNotiz(string str) {
101
102 if(!objectp(TI)) return(0);
103 if(!check_allowed()) {
104 if(objectp(this_interactive()))
105 tell_object(this_interactive(),
106 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
107 return(0);
108 }
109 //ggf. nur Einlesen, Cache muss hier nicht aktualisiert werden ;-)
110 checkStatus(1);
111 str=(string)PL->_unparsed_args(0); //kein parsing
112 if (!stringp(str) || !sizeof(str)) {
113 tell_object(PL,
114 "Was moechtest Du Dir denn notieren?\n");
115 return(1);
116 }
117 if (sizeof(str)>MAX_NOTE_LENGTH) {
118 tell_object(PL,BS(
119 sprintf("Deine Notiz ist mit %d Zeichen zu lang! Leider passen auf "
120 "Deinen Merkzettel nur % Zeichen drauf.",
121 sizeof(str),MAX_NOTE_LENGTH)));
122 return(1);
123 }
124
125 //m_allocate gilt nur bis Funktionsende, daher hilft das in
126 //checkStatus leider nicht.
127 if (!mappingp(notizen) || !sizeof(notizen))
128 notizen=m_allocate(0,7);
129
130 //freie ID finden (maxusedID+1 sollte die naechste frei sein, aber falls
131 //da mal was kaputtgegangen ist: Pruefen ;-) )
132 while(member(notizen,maxusedID)) {maxusedID++;}
133 //Reihenfolge: s. merkzettel.h
134 notizen+=([maxusedID:str;0;time();({});({});NOTE_ACTIVE;0]);
135/* notizen+=([maxusedID]);
136 notizen[maxusedID,NOTE_TEXT]=str;
137 notizen[maxusedID,NOTE_PRIO]=0;
138 notizen[maxusedID,NOTE_STARTTIME]=time();
139 notizen[maxusedID,NOTE_DEPS]=({});
140*/
141
142 //cache=({}); //cache invalidieren
143 //in Kuerze speichern, aber nicht fuer jede Aenderung speichern
144 save_me(60);
145 tell_object(PL,BS(
146 sprintf("Du schreibst sorgfaeltig Deine Notiz auf Deinen Merkzettel. "
147 "Es ist nun die %d. Notiz.",maxusedID)));
148 tell_room(environment(TI),
149 BS(sprintf("%s notiert sich etwas auf %s Merkzettel.\n",
150 capitalize((string)TI->name(WER)),
151 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
152 )),({TI}));
153 return(1);
154}
155
156int LiesNotiz(string str) {
157 int id;
158
159 if(!objectp(TI)) return(0);
160 if(!check_allowed()) {
161 if(objectp(this_interactive()))
162 tell_object(this_interactive(),
163 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
164 return(0);
165 }
166 if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
167 tell_object(PL,
168 "Welche Notiz moechtest Du lesen? Bitte eine ID angeben!\n");
169 return(1);
170 }
171 if (!checkStatus()) {
172 tell_object(PL,
173 "Es gibt keine Notiz, die Du lesen koenntest!\n");
174 return(1);
175 }
176 if (!member(notizen,id)) {
177 tell_object(PL,
178 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
179 return(1);
180 }
181 //Ausgabetext holen und ausgeben
182 tell_object(PL,sprintf("\nDu vertiefst Dich in Deinen Merkzettel und liest:\n%s\n",_LiesNotiz(id)));
183 tell_room(environment(TI),
184 BS(sprintf("%s liest etwas auf %s Merkzettel.\n",
185 capitalize((string)TI->name(WER)),
186 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
187 )),({TI}));
188 return(1);
189}
190
191int RemoveNotiz(string str) {
192 int id;
193
194 if(!objectp(TI)) return(0);
195 if(!check_allowed()) {
196 if(objectp(this_interactive()))
197 tell_object(this_interactive(),
198 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
199 return(0);
200 }
201 if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
202 tell_object(PL,
203 "Welche Notiz moechtest Du ausradieren? Bitte eine ID angeben!\n");
204 return(1);
205 }
206 if (!checkStatus()) {
207 tell_object(PL,
208 "Es gibt keine Notiz, die Du ausradieren koenntest!\n");
209 return(1);
210 }
211 if (!member(notizen,id)) {
212 tell_object(PL,
213 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
214 return(1);
215 }
216 //direkt Loeschen, keine Kopie, daher m_delete()
217 m_delete(notizen,id);
218 //in Kuerze speichern, aber nicht fuer jede Aenderung speichern
219 save_me(60);
220 //cache invalidieren
221 //cache=({});
222 tell_object(PL,
223 sprintf("Sorgfaeltig radierst Du Notiz %d von Deinem Merkzettel.\n",
224 id));
225 tell_room(environment(TI),
226 BS(sprintf("%s radiert sorgfaeltig etwas von %s Merkzettel.\n",
227 capitalize((string)TI->name(WER)),
228 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
229 )),({TI}));
230 return(1);
231}
232
233int FinishNotiz(string str) {
234 int id;
235 mixed liste;
236 if(!objectp(TI)) return(0);
237 if(!check_allowed()) {
238 if(objectp(this_interactive()))
239 tell_object(this_interactive(),
240 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
241 return(0);
242 }
243 if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
244 tell_object(PL,
245 "Welche Notiz moechtest Du abhaken? Bitte eine ID angeben!\n");
246 return(1);
247 }
248 if (!checkStatus()) {
249 tell_object(PL,
250 "Es gibt keine Notiz, die Du abhaken koenntest!\n");
251 return(1);
252 }
253 if (!member(notizen,id)) {
254 tell_object(PL,
255 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
256 return(1);
257 }
258 if(notizen[id,NOTE_STATUS]==NOTE_FINISHED) {
259 tell_object(PL,
260 sprintf("Notiz %d ist schon abgehakt!\n",id));
261 return(1);
262 }
263 liste=getUnresolvedDeps(id); //liste ist Array von ints
264 if (sizeof(liste)) {
265 liste=map(liste,#'to_string); //liste ist Array von strings
266 tell_object(PL,BS(sprintf("Du kannst Notiz %d nicht abhaken, da noch "
267 "nicht erledigte Abhaengigkeiten existieren. IDs: %s.",
268 id,CountUp(liste))));
269 return(1);
270 }
271 notizen[id,NOTE_STATUS]=NOTE_FINISHED;
272 notizen[id,NOTE_CLOSETIME]=time();
273 tell_object(PL,BS(
274 sprintf("Du malst zufrieden einen schoenen grossen Haken hinter "
275 "die Notiz Nr. %d. Hach - was bist Du nun zufrieden! :-)\n",id)));
276 tell_room(environment(TI),
277 BS(sprintf("%s hakt erfreut etwas auf %s Merkzettel ab.\n",
278 capitalize((string)TI->name(WER)),
279 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
280 )),({TI}));
281 return(1);
282}
283
284int ListNotizen(string str) {
285 int zahl,notizzahl,i,id,filterstate;
286 string txt;
287 string *arr;
288 status invers;
289
290 if(!objectp(TI)) return(0);
291 str=(string)PL->_unparsed_args(0);
292 if(!check_allowed()) {
293 if(objectp(this_interactive()))
294 tell_object(this_interactive(),
295 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
296 return(0);
297 }
298 if (!notizzahl=checkStatus()) {
299 tell_object(PL,BS(
300 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
301 "Hast Du nix zu tun?"));
302 return(1);
303 }
304 //Argumente parsen
305 if(stringp(str) && sizeof(str))
306 arr=explode(str," ");
307 if (pointerp(arr)) arr-=({""}); //doppelte leerzeichen im String
308 if (pointerp(arr) && sizeof(arr)>=2) {
309 zahl=to_int(arr[0]);
310 switch(arr[1]) {
311 case "aktiv":
312 filterstate=NOTE_ACTIVE; break;
313 case "inaktiv":
314 filterstate=NOTE_INACTIVE; break;
315 case "wartend":
316 case "pending":
317 filterstate=NOTE_PENDING; break;
318 case "abgehakt":
319 case "fertig":
320 case "abgeschlossen":
321 filterstate=NOTE_FINISHED; break;
322 case "alle":
323 filterstate=0; break;
324 default:
325 filterstate=to_int(arr[1]);
326 break;
327 }
328 }
329 else if (pointerp(arr) && sizeof(arr)==1) {
330 zahl=to_int(arr[0]);
331 filterstate=NOTE_ACTIVE;
332 }
333 else {
334 //Voreinstellungen
335 zahl=20;
336 filterstate=NOTE_ACTIVE;
337 }
338 //1. Argument "all" oder "alle" ist: alle anzeigen
339 if (pointerp(arr) && sizeof(arr) && stringp(arr[0]) &&
340 sizeof(arr[0]) && arr[0]=="alle")
341 zahl=notizzahl; //alle anzeigen
342
343 //wenn die gewuenschte Zahl die Anzahl gespeicherter
344 //Notizen ueberschreitet (oder 0 ist)
345 if(!zahl || zahl>notizzahl) zahl=notizzahl;
346
347 //wenn 1. Argument negativ: Liste in umgekehrter Reihenfolge
348 if (zahl<0) {
349 invers=1;
350 zahl=zahl*-1;
351 }
352 txt=sprintf("\n|%:9|s|%:56|s|%:7|s|\n","ID","Notiztext","Prio.");
353 txt+=sprintf("%:78'-'s\n","-");
354 //alle passenden Notizen ermitteln
355 arr=filter(m_indices(notizen),#'note_filter,filterstate);
356 //sortieren
357 arr=sort_array(arr,#'sort_prio);
358 if (zahl>sizeof(arr)) zahl=sizeof(arr);
359 //ausgeben
360 for(i=0;i<zahl;i++) {
361 if (!invers)
362 id=to_int(arr[i]);
363 else
364 //von hinten
365 id=to_int(arr[<i+1]); // i+1 ist wirklich Absicht. ;-)
366 txt+=sprintf("| %:7|d | %:54-s | %:5|d |\n",
367 id,
368 //nur bis zum ersten \n anzeigen
369 explode(notizen[id,NOTE_TEXT],"\n")[0],
370 notizen[id,NOTE_PRIO]);
371 }
372 txt+=sprintf("%:78'-'s\n\n","-");
373 tell_object(PL,txt);
374 tell_room(environment(TI),
375 BS(sprintf("%s wirft einen Blick auf %s Merkzettel.\n",
376 capitalize((string)TI->name(WER)),
377 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihren" : "seinen")
378 )),({TI}));
379 return(1);
380}
381
382int ChangeDep(string str) {
383 int id;
384 string *arr;
385 int *deps;
386
387 notify_fail("Bitte eine ID und eine min. eine Abhaengigkeit angeben!\n");
388 if(!objectp(TI)) return(0);
389 if(!check_allowed()) {
390 if(objectp(this_interactive()))
391 tell_object(this_interactive(),
392 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
393 return(0);
394 }
395 str=(string)PL->_unparsed_args(0);
396 if (!stringp(str) || !sizeof(str))
397 return(0);
398
399 if (!checkStatus()) {
400 tell_object(PL,BS(
401 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
402 "Hast Du nix zu tun?"));
403 return(1);
404 }
405 arr=explode(str," ");
406 arr-=({""}); // "" entfernen, wichtig. ;-)
407 if (sizeof(arr)<2)
408 return(0);
409 id=to_int(arr[0]);
410 arr-=({arr[0]}); //eigene ID loeschen
411 if (sizeof(arr)<1)
412 return(0); //mehrfach die eigene ID gilt nicht.;-)
413 if (!member(notizen,id)) {
414 tell_object(PL,
415 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
416 return(1);
417 }
418 //dies updated direkt die Abhaengigkeiten in 'notizen'!
419 map(arr,#'update_deps,id);
420 save_me(60);
421 tell_object(PL,BS(
422 sprintf("Du aenderst die Abhaengigkeiten von Notiz %d.\n",
423 id)));
424 tell_room(environment(TI),
425 BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
426 capitalize((string)TI->name(WER)),
427 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
428 )),({TI}));
429 return(1);
430}
431
432int ChangePrio(string str) {
433 int id, prio;
434 string* arr;
435
436 notify_fail("Bitte eine ID und eine neue Prioritaet angeben!\n");
437 if(!objectp(TI)) return(0);
438 if(!check_allowed()) {
439 if(objectp(this_interactive()))
440 tell_object(this_interactive(),
441 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
442 return(0);
443 }
444 str=(string)PL->_unparsed_args(0);
445 if (!stringp(str) || !sizeof(str))
446 return(0);
447
448 if (!checkStatus()) {
449 tell_object(PL,BS(
450 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
451 "Hast Du nix zu tun?"));
452 return(1);
453 }
454 arr=explode(str," ");
455 if (sizeof(arr)>2) {
456 notify_fail("Bitte nur eine ID und eine neue Prioritaet angeben!");
457 return(0);
458 }
459 else if(sizeof(arr)==2) {
460 id=to_int(arr[0]);
461 prio=to_int(arr[1]);
462 }
463 else
464 return(0);
465
466 if (!member(notizen,id)) {
467 tell_object(PL,
468 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
469 return(1);
470 }
471 notizen[id,NOTE_PRIO]=prio;
472 //cache=({}); //cache invalidieren
473 save_me(60);
474 tell_object(PL,BS(
475 sprintf("Du aenderst die Prioritaet von Notiz %d auf %d.",
476 id,notizen[id,NOTE_PRIO])));
477 tell_room(environment(TI),
478 BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
479 capitalize((string)TI->name(WER)),
480 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
481 )),({TI}));
482 return(1);
483}
484
485int ChangeHelper(string str) {
486 int id;
487 string *arr;
488
489 notify_fail("Bitte eine ID und eine min. einen Namen angeben!\n");
490 if(!objectp(TI)) return(0);
491 if(!check_allowed()) {
492 if(objectp(this_interactive()))
493 tell_object(this_interactive(),
494 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
495 return(0);
496 }
497 str=(string)PL->_unparsed_args(0);
498 if (!stringp(str) || !sizeof(str))
499 return(0);
500
501 if (!checkStatus()) {
502 tell_object(PL,BS(
503 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
504 "Hast Du nix zu tun?"));
505 return(1);
506 }
507 arr=explode(str," ");
508 arr-=({""}); // "" entfernen, wichtig. ;-)
509 if (sizeof(arr)<2)
510 return(0);
511 id=to_int(arr[0]);
512 arr-=({arr[0]}); //eigene ID loeschen
513 if (sizeof(arr)<1)
514 return(0); //mehrfach die eigene ID gilt nicht.;-)
515 if (!member(notizen,id)) {
516 tell_object(PL,
517 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
518 return(1);
519 }
520 notizen[id,NOTE_HELPER]=arr;
521 save_me(60);
522 tell_object(PL,BS(
523 sprintf("Mitarbeiter von Notiz %d geaendert.",id)));
524 tell_room(environment(TI),
525 BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
526 capitalize((string)TI->name(WER)),
527 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
528 )),({TI}));
529 return(1);
530}
531
532int ChangeStatus(string str) {
533 int id, state;
534 string *arr;
535
536 notify_fail(BS(
537 "Bitte min. eine ID angeben, um den Status umzuschalten oder "
538 "eine ID und den neuen Status (1==Aktiv, 2==Wartend, "
539 "-1==Inaktiv/Pause)"));
540 if(!objectp(TI)) return(0);
541 if(!check_allowed()) {
542 if(objectp(this_interactive()))
543 tell_object(this_interactive(),
544 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
545 return(0);
546 }
547 str=(string)PL->_unparsed_args(0);
548 if (!stringp(str) || !sizeof(str))
549 return(0);
550 if (!checkStatus()) {
551 tell_object(PL,BS(
552 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
553 "Hast Du nix zu tun?"));
554 return(1);
555 }
556 arr=explode(str," ");
557 if (sizeof(arr)>2) {
558 notify_fail("Bitte nur eine ID und einen neuen Status angeben!");
559 return(0);
560 }
561 else if(sizeof(arr)==2) {
562 id=to_int(arr[0]);
563 state=to_int(arr[1]);
564 }
565 else if(sizeof(arr)==1) {
566 id=to_int(arr[0]);
567 }
568 else
569 return(0);
570
571 if (!member(notizen,id)) {
572 tell_object(PL,
573 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
574 return(1);
575 }
576 if(member(NOTE_STATES,state)==-1) {
577 if (notizen[id,NOTE_STATUS]==NOTE_ACTIVE) {
578 tell_object(PL,BS(
579 sprintf("%d ist ein unbekannter Status, setzt Notiz %d auf "
580 "'Inaktiv'.",state,id)));
581 state=NOTE_INACTIVE;
582 }
583 else {
584 tell_object(PL,BS(
585 sprintf("%d ist ein unbekannter Status, setzt Notiz %d auf "
586 "'Aktiv'.",state,id)));
587 state=NOTE_ACTIVE;
588 }
589 }
590 notizen[id,NOTE_STATUS]=state;
591 save_me(60);
592 tell_object(PL,BS(
593 sprintf("Status von Notiz %d geaendert.",id)));
594 tell_room(environment(TI),
595 BS(sprintf("%s kritzelt auf %s Notizzettel herum.\n",
596 capitalize((string)TI->name(WER)),
597 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
598 )),({TI}));
599 return(1);
600}
601
602int ErsetzeText(string str) {
603 string *arr;
604 int id;
605
606 notify_fail("Bitte eine ID und einen neuen Text angeben!\n");
607 if(!objectp(TI)) return(0);
608
609 if(!check_allowed()) {
610 if(objectp(this_interactive()))
611 tell_object(this_interactive(),
612 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
613 return(0);
614 }
615 str=(string)PL->_unparsed_args(0);
616 if (!stringp(str) || !sizeof(str))
617 return(0);
618
619 if (!checkStatus()) {
620 tell_object(PL,BS(
621 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
622 "Hast Du nix zu tun?"));
623 return(1);
624 }
625 arr=explode(str," ");
626 arr-=({""}); // "" entfernen
627 if (sizeof(arr)<2)
628 return(0);
629 id=to_int(arr[0]);
630 str=implode(arr[1..]," "); //text wiederherstellen, ohne erstes Element
631 if (!sizeof(str)) return(0);
632 if (!member(notizen,id)) {
633 tell_object(PL,
634 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
635 return(1);
636 }
637 notizen[id,NOTE_TEXT]=str;
638 save_me(60);
639 tell_object(PL,BS(
640 sprintf("Text von Notiz %d ersetzt.",id)));
641 tell_room(environment(TI),
642 BS(sprintf("%s radiert zuerst etwas auf %s Notizzettel herum und "
643 "schreibt anschliessend sorgfaeltig etwas neues auf.\n",
644 capitalize((string)TI->name(WER)),
645 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
646 )),({TI}));
647 return(1);
648}
649
650int ErgaenzeText(string str) {
651 string *arr;
652 int id;
653
654 notify_fail("Bitte eine ID und einen Text angeben!\n");
655 if(!objectp(TI)) return(0);
656 if(!check_allowed()) {
657 if(objectp(this_interactive()))
658 tell_object(this_interactive(),
659 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
660 return(0);
661 }
662 str=(string)PL->_unparsed_args(0);
663 if (!stringp(str) || !sizeof(str))
664 return(0);
665
666 if (!checkStatus()) {
667 tell_object(PL,BS(
668 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
669 "Hast Du nix zu tun?"));
670 return(1);
671 }
672 arr=explode(str," ");
673 arr-=({""}); // "" entfernen
674 if (sizeof(arr)<2)
675 return(0);
676 id=to_int(arr[0]);
677 str="\n";
678 str+=implode(arr[1..]," "); //text wiederherstellen
679 if (!member(notizen,id)) {
680 tell_object(PL,
681 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
682 return(1);
683 }
684 notizen[id,NOTE_TEXT]+=str;
685 save_me(60);
686 tell_object(PL,BS(
687 sprintf("Text von Notiz %d ergaenzt.",id)));
688 tell_room(environment(TI),
689 BS(sprintf("%s ergaenzt etwas auf %s Notizzettel.\n",
690 capitalize((string)TI->name(WER)),
691 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
692 )),({TI}));
693 return(1);
694}
695
696int ZeigeZettel(string str) {
697 //anderen zeigen, wie furchtbar viel man zu tun hat.
698 object pl;
699 int count;
700 int *ids;
701
702 notify_fail("Wem willst Du Deinen Merkzettel zeigen?\n");
703 if (!objectp(TI)) return(0);
704 if (!environment() || !environment(environment()))
705 return(0);
706 if (!stringp(str) || !sizeof(str)) return(0);
707 if(!check_allowed()) {
708 if(objectp(this_interactive()))
709 tell_object(this_interactive(),
710 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
711 return(0);
712 }
713 if (!checkStatus()) {
714 tell_object(PL,BS(
715 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
716 "Hast Du nix zu tun? Du willst anderen Leuten doch bestimmt nicht "
717 "zeigen, dass Du nix zu tun hast, oder?"));
718 return(1);
719 }
720 if(!objectp(pl=present(str,environment(environment()))))
721 return(0);
722 if (!living(pl))
723 return(0);
724
725 ids=filter(m_indices(notizen),#'note_filter,NOTE_ACTIVE);
726 tell_object(TI,BS("Du zeigst "+pl->Name(WEM)+" voller Stolz deinen vollen "
727 "Merkzettel."));
728 tell_room(environment(environment()),BS(sprintf(
729 "%s zeigt %s %s Merkzettel.",
730 TI->Name(WER),pl->Name(WEM),TI->QueryPossPronoun(MALE,WEN,SINGULAR))),
731 ({TI,pl}));
732 switch(sizeof(ids)) {
733 case 0..10:
734 tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
735 "wirfst einen schnellen Blick darueber und zaehlst %d "
736 "Notizen. Na, soviel ist das ja zum Glueck noch nicht.",
737 TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
738 sizeof(ids))));
739 break;
740 case 11..20:
741 tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
742 "wirfst einen schnellen Blick darueber und zaehlst %d "
743 "Notizen. Oh, das ist ja schon so einiges!",
744 TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
745 sizeof(ids))));
746 break;
747 default:
748 tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
749 "wirfst einen schnellen Blick darueber und zaehlst %d "
750 "Notizen. Puuuh. %s hat ganz schoen viel zu tun! In "
751 "Dir regt sich leises Mitleid.",
752 TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
753 sizeof(ids),TI->Name(WER) )));
754 break;
755 }
756 return(1);
757 }
758
759int WedelZettel(string str) {
760 object pl;
761 string rwedel;
762 //wedelt anderen mit dem Zettel vor der Nase herum.
763 notify_fail("Wem willst Du Deinen Merkzettel zeigen?\n");
764 if (!objectp(TI)) return(0);
765 if (!environment() || !environment(environment()))
766 return(0);
767 if (!stringp(str) || !sizeof(str)) return(0);
768 if(!check_allowed()) {
769 if(objectp(this_interactive()))
770 tell_object(this_interactive(),
771 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
772 return(0);
773 }
774 if (!objectp(pl=find_player(str))) return(0);
775 if (!present(pl,environment(environment())))
776 rwedel="aus der Ferne";
777
778 tell_object(PL,BS("Du wedelst "+pl->Name(WEM)
779 + (rwedel?" "+rwedel:"")
780 +" heftig mit Deinem Merkzettel vor der Nase herum."));
781 tell_object(pl,BS(PL->Name(WER)+ " wedelt Dir "
782 + (rwedel?rwedel+" ":"") +"heftig mit "
783 +PL->QueryPossPronoun(MALE,WEM,SINGULAR)
784 +" Merkzettel vor der Nase herum."));
785 tell_room(environment(pl),BS(PL->Name(WER) + " wedelt "
786 +pl->Name(WEM) + (rwedel?" "+rwedel:"") + " heftig mit "
787 +PL->QueryPossPronoun(MALE,WEM,SINGULAR)
788 +" Merkzettel vor der Nase herum."),({PL,pl}));
789 return(1);
790}
791
792int LiesDeps(string str) {
793 //erstmal (rekursiv) alle Abhaengigkeiten einer Notiz ermitteln
794 string *arr;
795 int id, rec, i;
796 int *liste;
797
798 notify_fail("Bitte eine ID und ggf. '1' fuer rekursive Suche angeben!\n");
799 if(!objectp(TI)) return(0);
800 if(!check_allowed()) {
801 if(objectp(this_interactive()))
802 tell_object(this_interactive(),
803 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
804 return(0);
805 }
806 str=(string)PL->_unparsed_args(0);
807 if (!stringp(str) || !sizeof(str))
808 return(0);
809
810 if (!checkStatus()) {
811 tell_object(PL,BS(
812 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
813 "Hast Du nix zu tun?"));
814 return(1);
815 }
816 arr=explode(str," ");
817 arr-=({""}); // "" entfernen
818 if (sizeof(arr)==1) {
819 id=to_int(arr[0]);
820 rec=0; //Standard: keine Rekursion
821 }
822 else if (sizeof(arr)>=2) {
823 id=to_int(arr[0]);
824 rec=to_int(arr[1]);
825 }
826 else {
827 return(0);
828 }
829 if (!member(notizen,id)) {
830 tell_object(PL,
831 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
832 return(1);
833 }
834 //Notizen, von denen id abhaengt, holen
835 //und nur aktive Notizen behalten
836 liste=filter(getDeps(id,rec),#'note_filter,NOTE_ACTIVE);
837 //nach Prioritaet sortieren
838 liste=sort_array(liste,#'sort_prio);
839 //dann mal ausgeben.
840 i=sizeof(liste);
841 tell_object(PL,BS(sprintf("Du vertiefst Dich in die Abhaenhigkeiten von Notiz: %d\n",id)));
842 while(i--) {
843 tell_object(PL,_LiesNotiz(liste[i])+"\n");
844 }
845 tell_room(environment(TI),
846 BS(sprintf("%s liest etwas auf %s Merkzettel.\n",
847 capitalize((string)TI->name(WER)),
848 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
849 )),({TI}));
850 return(1);
851}
852
853int Expire(string str) {
854 float age;
855 int sekunden, i;
856 int *liste;
857 string res;
858
859 notify_fail("Bitte angeben, wie alt zu loeschende Notizen sein sollen (in Tagen)!\n");
860 if(!objectp(TI)) return(0);
861 if(!check_allowed()) {
862 if(objectp(this_interactive()))
863 tell_object(this_interactive(),
864 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
865 return(0);
866 }
867 str=(string)PL->_unparsed_args(0);
868 if (!stringp(str) || !sizeof(str))
869 return(0);
870 age=to_float(str);
871 if (age<=0) return(0);
872 sekunden=time() - (int)(age*86400);
873 if (!checkStatus()) {
874 tell_object(PL,BS(
875 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
876 "Hast Du nix zu tun?"));
877 return(1);
878 }
879 //abgehakte Notizen ermitteln
880 liste=filter(m_indices(notizen),#'note_filter,NOTE_FINISHED);
881 //Notizen ermitteln, die lang genug abgehakt sind.
882 liste=filter(liste,#'aelter_als,sekunden);
883 if (!sizeof(liste)) {
884 tell_object(PL,BS("Keine Notizen gefunden, die lang genug abgehakt sind."));
885 return(1);
886 }
887 res=sprintf("Archivierte Notizen vom %s\n\n",dtime(time()));
888 for (i=sizeof(liste);i--;) {
889 //Infos noch einmal ausgeben und loeschen
890 res+=_LiesNotiz(liste[i])+"\n";
891 m_delete(notizen,liste[i]);
892 }
893 res+="\n";
894 write_file(ARCHIVE(owner),res);
895 tell_object(PL,BS(sprintf(
896 "%d alte Notizen wurden nach %s archiviert und geloescht.",
897 sizeof(liste),ARCHIVE(owner))));
898 return(1);
899}
900
901//
902static string _LiesNotiz(int id) {
903 //Funktion verlaesst sich drauf, dass id existiert. ;-)
904 string res,txt;
905 res=BSL(sprintf("%-11s: %d","Notiz-Nr.",id));
906 res+=break_string(notizen[id,NOTE_TEXT],78,"Notiztext : ",
907 BS_INDENT_ONCE|BS_LEAVE_MY_LFS);
908 res+=sprintf("%-11s: %d\n","Prioritaet",notizen[id,NOTE_PRIO]);
909 //wenn nicht aktiv: Status anzeigen
910 if (notizen[id,NOTE_STATUS]!=NOTE_ACTIVE) {
911 switch(notizen[id,NOTE_STATUS]) {
912 case NOTE_INACTIVE:
913 txt="Inaktiv/Pause";
914 break;
915 case NOTE_FINISHED:
916 txt="Abgeschlossen";
917 break;
918 case NOTE_PENDING:
919 txt="Warte auf Rueckmeldung";
920 break;
921 default: txt=sprintf("%d",notizen[id,NOTE_STATUS]); break;
922 }
923 res+=sprintf("%-11s: %s\n","Status",txt);
924 //wenn abgeschlossen: Endezeit anzeigen
925 if (notizen[id,NOTE_STATUS]==NOTE_FINISHED)
926 res+=sprintf("%-11s: %s\n","Endezeit",
927 dtime(notizen[id,NOTE_CLOSETIME]));
928 }
929 res+=sprintf("%-11s: %s\n","Merkzeit",dtime(notizen[id,NOTE_STARTTIME]));
930 //nur wenn Abhaengigkeiten: anezeigen
931 if (pointerp(notizen[id,NOTE_DEPS]) && sizeof(notizen[id,NOTE_DEPS])) {
932 txt=implode(map(notizen[id,NOTE_DEPS],#'to_string)," ");
933 res+=sprintf("%-11s: %s\n","abh. von",txt);
934 }
935 //nur wenn Helfer: anezeigen
936 if (pointerp(notizen[id,NOTE_HELPER]) && sizeof(notizen[id,NOTE_HELPER]))
937 res+=sprintf("%-11s: %s\n","Helfer",
938 implode(notizen[id,NOTE_HELPER]," "));
939 return(res);
940}
941
942//int. Helfer
943static int note_filter(int id,int filterstate) {
944 //kein filter -> passt immer
945 if (!filterstate) return(1);
946 if (member(notizen,id) &&
947 notizen[id,NOTE_STATUS]==filterstate)
948 return(1);
949 return(0);
950}
951
952static int aelter_als(int id,int zeit) {
953 //liefert 1 zurueck, wenn Schliesszeit der Notiz laenger als 'sekunden' her ist, sonst 0.
954 if (notizen[id,NOTE_CLOSETIME]<zeit) return(1);
955 return(0);
956}
957
958static string update_deps(string str,int id) {
959 //wandelt str nach int um
960 //schaut, ob dep positiv und noch nicht bekannt ist, wenn ja:
961 //zu deps hinzufuegen
962 //wenn dep < 0 und bekannt ist: aus deps entfernen
963 //Rueckgabewert ist egal. ;-)
964 int dep;
965 dep=to_int(str);
966 if (dep>0 && member(notizen[id,NOTE_DEPS],dep)==-1)
967 notizen[id,NOTE_DEPS]+=({dep});
968 else if (dep<0 && member(notizen[id,NOTE_DEPS],dep*-1)!=-1)
969 notizen[id,NOTE_DEPS]-=({dep*-1});
970 return("");
971}
972
973static int *getDeps(int id, int rec) {
974 //ermittelt (ggf. rekursiv bei rec!=0) die Abhaengigkeiten einer Notiz
975 int i, *liste;
976 liste=notizen[id,NOTE_DEPS];
977 //jetzt ggf. noch rekursiv weiterholen
978 if (rec) {
979 i=0;
980 while(i<sizeof(liste)) {
981 //nicht schreien. ;-)
982 if (get_eval_cost()<100000) {
983 tell_object(PL,"Fehler: Zu lange Rekursion bei "
984 "Ermitteln der Abhaengigkeiten, Abbruch\n");
985 return(liste);
986 }
987 //Abhaengigkeiten der anderen Abhaengigkeiten hinten anhaengen.
988 liste+=notizen[liste[i],NOTE_DEPS];
989 i++;
990 }
991 }
992 return(liste);
993}
994
995static int *getUnresolvedDeps(int id) {
996 //liefert die Anzahl der nicht abgehakten Notizen, von denen eine
997 //Notiz abhaengig ist (rekursiv)
998 int *liste;
999 //Abhaengigkeiten rekursiv holen
1000 liste=getDeps(id,1);
1001 //nicht abgehakte zurueckgeben
1002 return(liste-filter(liste,#'note_filter,NOTE_FINISHED));
1003}
1004
1005void init() {
1006 ::init();
1007 //wenn kein Env, Env kein magier oder nicht der Eigentuemer ist: weg
1008 if (!objectp(environment()) || !IS_LEARNER(environment())
1009 || (stringp(owner) && getuid(environment())!=owner) ) {
1010 if (find_call_out("remove") == -1)
1011 call_out("remove",1,1);
1012 return;
1013 }
1014 //beim erstmaligen Bewegen in einen Magier wird der als Eigentuemer
1015 //registriert. Danach kommt diese Info aus P_AUTOLOAD
1016 if (!stringp(owner))
1017 owner=getuid(environment());
1018}
1019
1020static nomask status check_allowed() {
1021 //Zugriff auf die Daten fuer den Eigentuemer
1022 if(objectp(this_interactive()) &&
1023 getuid(this_interactive())==owner
1024 && !process_call())
1025 return(1);
1026 return(0);
1027}
1028
1029protected int restore_me() {
1030 //laedt Savefile im Home vom Magier
1031 if(!stringp(owner)) return(0);
1032 if(!restore_object(SAVEFILE(owner))) {
1033 maxusedID=1;
1034 notizen=0;
1035 //cache=({});
1036 return(0);
1037 }
1038 return(1);
1039}
1040
1041varargs protected void save_me(int delay) {
1042 //speichert Savefile im Home vom Magier
1043 if(!stringp(owner)) return;
1044 //wenn maxusedID==0 wurde der zettel noch nicht ordentlich initialisiert
1045 //bzw. restauriert. In diesem Fall wuerde ein leeres Savefile geschrieben
1046 if (maxusedID==0)
1047 restore_me();
1048 if(!delay)
1049 //direkt speichen. ;-)
1050 save_object(SAVEFILE(owner));
1051 else {
1052 //verzoegert speichern, wenn schon ein call_out laeuft, nehm ich den
1053 if(find_call_out(#'save_me)==-1)
1054 call_out(#'save_me,delay);
1055 }
1056}
1057
1058varargs int remove(int silent) {
1059 //erstmal speichern. ;-)
1060 save_me();
1061 return ::remove(silent);
1062}
1063
1064static string query_autoloadobj() {
1065 //in P_AUTOLOAD wird nur der Eigentuemer gespeichert
1066 return owner;
1067}
1068
1069static string set_autoloadobj(mixed arg) {
1070 //Eigentuemer aus P_AUTOLOAD restaurieren
1071 if (stringp(arg))
1072 owner=arg;
1073 return(owner);
1074}
1075
1076//Shadow unerwuenscht
1077int query_prevent_shadow() {return(1);}
1078
1079varargs static int checkStatus(int nocache) {
1080 //schaut, ob Notizen da, ob der Cache Ok ist, etc.
1081 //liefert Anzahl der Notizen auf dem Merkzettel
1082
1083 //wenn keine Notizen da sind, schauen, ob das Savefile eingelesen werden
1084 //kann
1085 if (!mappingp(notizen) || !sizeof(notizen))
1086 restore_me();
1087 if (!mappingp(notizen)) return(0);
1088/* Cache ist eigentlich nicht noetig und mir gerade zu unpraktisch, raus damit.
1089 //wenn keine Aktualisierung des Cache erwuenscht ist
1090 if(nocache) return(0);
1091
1092 if (sizeof(notizen)) {
1093 if(!pointerp(cache) || !sizeof(cache)) {
1094 //cache erneuern
1095 cache=sort_array(m_indices(notizen),"sort_prio");
1096 }
1097 }
1098 return(sizeof(cache)); //aequivalent zu sizeof(notizen)
1099 */
1100 return(sizeof(notizen));
1101}
1102
1103static status sort_prio(int key1, int key2) {
1104 // 1, falls falsche Reihenfolge,
1105 // 0, wenn richtige
1106 // und zwar _absteigend_, also hoechste Prio in liste[0] !
1107 return(notizen[key1,NOTE_PRIO]<=notizen[key2,NOTE_PRIO]);
1108}
1109
1110
1111//*******************************************************
1112
1113// Debugging
1114mapping QueryNotizen() {
1115
1116 if(!check_allowed()) {
1117 if(objectp(this_interactive()))
1118 tell_object(this_interactive(),
1119 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
1120 return(0);
1121 }
1122 checkStatus();
1123 return(notizen);
1124}
1125
1126//int *QueryCache() {return(cache);}
1127
1128int QuerySize() {return(sizeof(notizen));}
1129
1130string QueryOwner() {return(owner);}