blob: ed5c180b0ea47b67e6a334bc0f5573b6382af000 [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
Zesstraff356512018-08-27 20:20:36 +020030protected void create() {
MG Mud User88f12472016-06-24 23:31:02 +020031 ::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);
Arathorn5fecd832020-07-27 23:46:37 +0200726 tell_object(TI,BS("Du zeigst "+({string})pl->Name(WEM)+
727 " voller Stolz deinen vollen Merkzettel."));
MG Mud User88f12472016-06-24 23:31:02 +0200728 tell_room(environment(environment()),BS(sprintf(
729 "%s zeigt %s %s Merkzettel.",
Arathorn5fecd832020-07-27 23:46:37 +0200730 ({string})TI->Name(WER), ({string})pl->Name(WEM),
731 ({string})TI->QueryPossPronoun(MALE,WEN,SINGULAR))),
MG Mud User88f12472016-06-24 23:31:02 +0200732 ({TI,pl}));
733 switch(sizeof(ids)) {
734 case 0..10:
735 tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
736 "wirfst einen schnellen Blick darueber und zaehlst %d "
737 "Notizen. Na, soviel ist das ja zum Glueck noch nicht.",
Arathorn5fecd832020-07-27 23:46:37 +0200738 ({string})TI->Name(WER),
739 ({string})TI->QueryPossPronoun(MALE,WEN,SINGULAR),
MG Mud User88f12472016-06-24 23:31:02 +0200740 sizeof(ids))));
741 break;
742 case 11..20:
743 tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
744 "wirfst einen schnellen Blick darueber und zaehlst %d "
745 "Notizen. Oh, das ist ja schon so einiges!",
Arathorn5fecd832020-07-27 23:46:37 +0200746 ({string})TI->Name(WER),
747 ({string})TI->QueryPossPronoun(MALE,WEN,SINGULAR),
MG Mud User88f12472016-06-24 23:31:02 +0200748 sizeof(ids))));
749 break;
750 default:
751 tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
752 "wirfst einen schnellen Blick darueber und zaehlst %d "
753 "Notizen. Puuuh. %s hat ganz schoen viel zu tun! In "
754 "Dir regt sich leises Mitleid.",
Arathorn5fecd832020-07-27 23:46:37 +0200755 ({string})TI->Name(WER),
756 ({string})TI->QueryPossPronoun(MALE,WEN,SINGULAR),
757 sizeof(ids),
758 ({string})TI->Name(WER) )));
MG Mud User88f12472016-06-24 23:31:02 +0200759 break;
760 }
761 return(1);
762 }
763
764int WedelZettel(string str) {
765 object pl;
766 string rwedel;
767 //wedelt anderen mit dem Zettel vor der Nase herum.
768 notify_fail("Wem willst Du Deinen Merkzettel zeigen?\n");
769 if (!objectp(TI)) return(0);
770 if (!environment() || !environment(environment()))
771 return(0);
772 if (!stringp(str) || !sizeof(str)) return(0);
773 if(!check_allowed()) {
774 if(objectp(this_interactive()))
775 tell_object(this_interactive(),
776 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
777 return(0);
778 }
779 if (!objectp(pl=find_player(str))) return(0);
780 if (!present(pl,environment(environment())))
781 rwedel="aus der Ferne";
782
Arathorn5fecd832020-07-27 23:46:37 +0200783 tell_object(PL,BS("Du wedelst "+({string})pl->Name(WEM)+
784 (rwedel?" "+rwedel:"")+
785 " heftig mit Deinem Merkzettel vor der Nase herum."));
786 tell_object(pl,BS(({string})PL->Name(WER)+ " wedelt Dir "
787 +(rwedel?rwedel+" ":"") +"heftig mit "
788 +({string})PL->QueryPossPronoun(MALE,WEM,SINGULAR)
789 +" Merkzettel vor der Nase herum."));
790 tell_room(environment(pl),BS(({string})PL->Name(WER) + " wedelt "
791 +({string})pl->Name(WEM) + (rwedel?" "+rwedel:"") + " heftig mit "
792 +({string})PL->QueryPossPronoun(MALE,WEM,SINGULAR)
793 +" Merkzettel vor der Nase herum."),({PL,pl}));
MG Mud User88f12472016-06-24 23:31:02 +0200794 return(1);
795}
796
797int LiesDeps(string str) {
798 //erstmal (rekursiv) alle Abhaengigkeiten einer Notiz ermitteln
799 string *arr;
800 int id, rec, i;
801 int *liste;
802
803 notify_fail("Bitte eine ID und ggf. '1' fuer rekursive Suche angeben!\n");
804 if(!objectp(TI)) return(0);
805 if(!check_allowed()) {
806 if(objectp(this_interactive()))
807 tell_object(this_interactive(),
808 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
809 return(0);
810 }
811 str=(string)PL->_unparsed_args(0);
812 if (!stringp(str) || !sizeof(str))
813 return(0);
814
815 if (!checkStatus()) {
816 tell_object(PL,BS(
817 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
818 "Hast Du nix zu tun?"));
819 return(1);
820 }
821 arr=explode(str," ");
822 arr-=({""}); // "" entfernen
823 if (sizeof(arr)==1) {
824 id=to_int(arr[0]);
825 rec=0; //Standard: keine Rekursion
826 }
827 else if (sizeof(arr)>=2) {
828 id=to_int(arr[0]);
829 rec=to_int(arr[1]);
830 }
831 else {
832 return(0);
833 }
834 if (!member(notizen,id)) {
835 tell_object(PL,
836 sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
837 return(1);
838 }
839 //Notizen, von denen id abhaengt, holen
840 //und nur aktive Notizen behalten
841 liste=filter(getDeps(id,rec),#'note_filter,NOTE_ACTIVE);
842 //nach Prioritaet sortieren
843 liste=sort_array(liste,#'sort_prio);
844 //dann mal ausgeben.
845 i=sizeof(liste);
846 tell_object(PL,BS(sprintf("Du vertiefst Dich in die Abhaenhigkeiten von Notiz: %d\n",id)));
847 while(i--) {
848 tell_object(PL,_LiesNotiz(liste[i])+"\n");
849 }
850 tell_room(environment(TI),
851 BS(sprintf("%s liest etwas auf %s Merkzettel.\n",
852 capitalize((string)TI->name(WER)),
853 (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem")
854 )),({TI}));
855 return(1);
856}
857
858int Expire(string str) {
859 float age;
860 int sekunden, i;
861 int *liste;
862 string res;
863
864 notify_fail("Bitte angeben, wie alt zu loeschende Notizen sein sollen (in Tagen)!\n");
865 if(!objectp(TI)) return(0);
866 if(!check_allowed()) {
867 if(objectp(this_interactive()))
868 tell_object(this_interactive(),
869 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
870 return(0);
871 }
872 str=(string)PL->_unparsed_args(0);
873 if (!stringp(str) || !sizeof(str))
874 return(0);
875 age=to_float(str);
876 if (age<=0) return(0);
877 sekunden=time() - (int)(age*86400);
878 if (!checkStatus()) {
879 tell_object(PL,BS(
880 "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
881 "Hast Du nix zu tun?"));
882 return(1);
883 }
884 //abgehakte Notizen ermitteln
885 liste=filter(m_indices(notizen),#'note_filter,NOTE_FINISHED);
886 //Notizen ermitteln, die lang genug abgehakt sind.
887 liste=filter(liste,#'aelter_als,sekunden);
888 if (!sizeof(liste)) {
889 tell_object(PL,BS("Keine Notizen gefunden, die lang genug abgehakt sind."));
890 return(1);
891 }
892 res=sprintf("Archivierte Notizen vom %s\n\n",dtime(time()));
893 for (i=sizeof(liste);i--;) {
894 //Infos noch einmal ausgeben und loeschen
895 res+=_LiesNotiz(liste[i])+"\n";
896 m_delete(notizen,liste[i]);
897 }
898 res+="\n";
899 write_file(ARCHIVE(owner),res);
900 tell_object(PL,BS(sprintf(
901 "%d alte Notizen wurden nach %s archiviert und geloescht.",
902 sizeof(liste),ARCHIVE(owner))));
903 return(1);
904}
905
906//
907static string _LiesNotiz(int id) {
908 //Funktion verlaesst sich drauf, dass id existiert. ;-)
909 string res,txt;
910 res=BSL(sprintf("%-11s: %d","Notiz-Nr.",id));
911 res+=break_string(notizen[id,NOTE_TEXT],78,"Notiztext : ",
912 BS_INDENT_ONCE|BS_LEAVE_MY_LFS);
913 res+=sprintf("%-11s: %d\n","Prioritaet",notizen[id,NOTE_PRIO]);
914 //wenn nicht aktiv: Status anzeigen
915 if (notizen[id,NOTE_STATUS]!=NOTE_ACTIVE) {
916 switch(notizen[id,NOTE_STATUS]) {
917 case NOTE_INACTIVE:
918 txt="Inaktiv/Pause";
919 break;
920 case NOTE_FINISHED:
921 txt="Abgeschlossen";
922 break;
923 case NOTE_PENDING:
924 txt="Warte auf Rueckmeldung";
925 break;
926 default: txt=sprintf("%d",notizen[id,NOTE_STATUS]); break;
927 }
928 res+=sprintf("%-11s: %s\n","Status",txt);
929 //wenn abgeschlossen: Endezeit anzeigen
930 if (notizen[id,NOTE_STATUS]==NOTE_FINISHED)
931 res+=sprintf("%-11s: %s\n","Endezeit",
932 dtime(notizen[id,NOTE_CLOSETIME]));
933 }
934 res+=sprintf("%-11s: %s\n","Merkzeit",dtime(notizen[id,NOTE_STARTTIME]));
935 //nur wenn Abhaengigkeiten: anezeigen
936 if (pointerp(notizen[id,NOTE_DEPS]) && sizeof(notizen[id,NOTE_DEPS])) {
937 txt=implode(map(notizen[id,NOTE_DEPS],#'to_string)," ");
938 res+=sprintf("%-11s: %s\n","abh. von",txt);
939 }
940 //nur wenn Helfer: anezeigen
941 if (pointerp(notizen[id,NOTE_HELPER]) && sizeof(notizen[id,NOTE_HELPER]))
942 res+=sprintf("%-11s: %s\n","Helfer",
943 implode(notizen[id,NOTE_HELPER]," "));
944 return(res);
945}
946
947//int. Helfer
948static int note_filter(int id,int filterstate) {
949 //kein filter -> passt immer
950 if (!filterstate) return(1);
951 if (member(notizen,id) &&
952 notizen[id,NOTE_STATUS]==filterstate)
953 return(1);
954 return(0);
955}
956
957static int aelter_als(int id,int zeit) {
958 //liefert 1 zurueck, wenn Schliesszeit der Notiz laenger als 'sekunden' her ist, sonst 0.
959 if (notizen[id,NOTE_CLOSETIME]<zeit) return(1);
960 return(0);
961}
962
963static string update_deps(string str,int id) {
964 //wandelt str nach int um
965 //schaut, ob dep positiv und noch nicht bekannt ist, wenn ja:
966 //zu deps hinzufuegen
967 //wenn dep < 0 und bekannt ist: aus deps entfernen
968 //Rueckgabewert ist egal. ;-)
969 int dep;
970 dep=to_int(str);
971 if (dep>0 && member(notizen[id,NOTE_DEPS],dep)==-1)
972 notizen[id,NOTE_DEPS]+=({dep});
973 else if (dep<0 && member(notizen[id,NOTE_DEPS],dep*-1)!=-1)
974 notizen[id,NOTE_DEPS]-=({dep*-1});
975 return("");
976}
977
978static int *getDeps(int id, int rec) {
979 //ermittelt (ggf. rekursiv bei rec!=0) die Abhaengigkeiten einer Notiz
980 int i, *liste;
981 liste=notizen[id,NOTE_DEPS];
982 //jetzt ggf. noch rekursiv weiterholen
983 if (rec) {
984 i=0;
985 while(i<sizeof(liste)) {
986 //nicht schreien. ;-)
987 if (get_eval_cost()<100000) {
988 tell_object(PL,"Fehler: Zu lange Rekursion bei "
989 "Ermitteln der Abhaengigkeiten, Abbruch\n");
990 return(liste);
991 }
992 //Abhaengigkeiten der anderen Abhaengigkeiten hinten anhaengen.
993 liste+=notizen[liste[i],NOTE_DEPS];
994 i++;
995 }
996 }
997 return(liste);
998}
999
1000static int *getUnresolvedDeps(int id) {
1001 //liefert die Anzahl der nicht abgehakten Notizen, von denen eine
1002 //Notiz abhaengig ist (rekursiv)
1003 int *liste;
1004 //Abhaengigkeiten rekursiv holen
1005 liste=getDeps(id,1);
1006 //nicht abgehakte zurueckgeben
1007 return(liste-filter(liste,#'note_filter,NOTE_FINISHED));
1008}
1009
Zesstraff356512018-08-27 20:20:36 +02001010public varargs void init(object origin) {
MG Mud User88f12472016-06-24 23:31:02 +02001011 ::init();
1012 //wenn kein Env, Env kein magier oder nicht der Eigentuemer ist: weg
1013 if (!objectp(environment()) || !IS_LEARNER(environment())
1014 || (stringp(owner) && getuid(environment())!=owner) ) {
1015 if (find_call_out("remove") == -1)
1016 call_out("remove",1,1);
1017 return;
1018 }
1019 //beim erstmaligen Bewegen in einen Magier wird der als Eigentuemer
1020 //registriert. Danach kommt diese Info aus P_AUTOLOAD
1021 if (!stringp(owner))
1022 owner=getuid(environment());
1023}
1024
1025static nomask status check_allowed() {
1026 //Zugriff auf die Daten fuer den Eigentuemer
1027 if(objectp(this_interactive()) &&
1028 getuid(this_interactive())==owner
1029 && !process_call())
1030 return(1);
1031 return(0);
1032}
1033
1034protected int restore_me() {
1035 //laedt Savefile im Home vom Magier
1036 if(!stringp(owner)) return(0);
1037 if(!restore_object(SAVEFILE(owner))) {
1038 maxusedID=1;
1039 notizen=0;
1040 //cache=({});
1041 return(0);
1042 }
1043 return(1);
1044}
1045
1046varargs protected void save_me(int delay) {
1047 //speichert Savefile im Home vom Magier
1048 if(!stringp(owner)) return;
1049 //wenn maxusedID==0 wurde der zettel noch nicht ordentlich initialisiert
1050 //bzw. restauriert. In diesem Fall wuerde ein leeres Savefile geschrieben
1051 if (maxusedID==0)
1052 restore_me();
1053 if(!delay)
1054 //direkt speichen. ;-)
1055 save_object(SAVEFILE(owner));
1056 else {
1057 //verzoegert speichern, wenn schon ein call_out laeuft, nehm ich den
1058 if(find_call_out(#'save_me)==-1)
1059 call_out(#'save_me,delay);
1060 }
1061}
1062
1063varargs int remove(int silent) {
1064 //erstmal speichern. ;-)
1065 save_me();
1066 return ::remove(silent);
1067}
1068
1069static string query_autoloadobj() {
1070 //in P_AUTOLOAD wird nur der Eigentuemer gespeichert
1071 return owner;
1072}
1073
1074static string set_autoloadobj(mixed arg) {
1075 //Eigentuemer aus P_AUTOLOAD restaurieren
1076 if (stringp(arg))
1077 owner=arg;
1078 return(owner);
1079}
1080
1081//Shadow unerwuenscht
1082int query_prevent_shadow() {return(1);}
1083
1084varargs static int checkStatus(int nocache) {
1085 //schaut, ob Notizen da, ob der Cache Ok ist, etc.
1086 //liefert Anzahl der Notizen auf dem Merkzettel
1087
1088 //wenn keine Notizen da sind, schauen, ob das Savefile eingelesen werden
1089 //kann
1090 if (!mappingp(notizen) || !sizeof(notizen))
1091 restore_me();
1092 if (!mappingp(notizen)) return(0);
1093/* Cache ist eigentlich nicht noetig und mir gerade zu unpraktisch, raus damit.
1094 //wenn keine Aktualisierung des Cache erwuenscht ist
1095 if(nocache) return(0);
1096
1097 if (sizeof(notizen)) {
1098 if(!pointerp(cache) || !sizeof(cache)) {
1099 //cache erneuern
1100 cache=sort_array(m_indices(notizen),"sort_prio");
1101 }
1102 }
1103 return(sizeof(cache)); //aequivalent zu sizeof(notizen)
1104 */
1105 return(sizeof(notizen));
1106}
1107
1108static status sort_prio(int key1, int key2) {
1109 // 1, falls falsche Reihenfolge,
1110 // 0, wenn richtige
1111 // und zwar _absteigend_, also hoechste Prio in liste[0] !
1112 return(notizen[key1,NOTE_PRIO]<=notizen[key2,NOTE_PRIO]);
1113}
1114
1115
1116//*******************************************************
1117
1118// Debugging
1119mapping QueryNotizen() {
1120
1121 if(!check_allowed()) {
1122 if(objectp(this_interactive()))
1123 tell_object(this_interactive(),
1124 BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
1125 return(0);
1126 }
1127 checkStatus();
1128 return(notizen);
1129}
1130
1131//int *QueryCache() {return(cache);}
1132
1133int QuerySize() {return(sizeof(notizen));}
1134
1135string QueryOwner() {return(owner);}