blob: 076f44e4c0ab6f39b4f74bc254f40a508bdb0b51 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// merlin.c -- Unser geliebter Merlin
4//
5// $Id: merlin.c 9405 2015-12-13 00:22:01Z Zesstra $
6#pragma strict_types
7#pragma no_clone
8#pragma no_shadow
9#pragma no_inherit
10#pragma verbose_errors
11#pragma combine_strings
12//#pragma pedantic
13//#pragma range_check
14#pragma warn_deprecated
15
16// 2014-Mai-10, Arathorn: Er soll ja weiterhin auf tm reagieren.
17inherit "std/npc/comm.c";
18
19#include <config.h>
20#include <properties.h>
21#include <language.h>
22#include <moving.h>
23#include <defines.h>
24#include <exploration.h>
25#include <news.h>
26#include <exploration.h>
27#include <events.h>
28#include <daemon/channel.h>
29#include "/secure/wizlevels.h"
30#include "/secure/config.h"
31#include "/secure/questmaster.h"
32#include "/secure/lepmaster.h"
33
34#ifndef DEBUG
35#define DEBUG(x) if (find_player("zook")) tell_object(find_player("zook"),x)
36#endif
37
38#define SAVEFILE "/secure/ARCH/merlin"
39#define BS(x) break_string((x),78)
40#define FEHLERTEUFEL "/obj/tools/fehlerteufel"
41
42mixed QueryProp(string prop);
43int move(mixed dest, int method);
44string query_g_suffix(int gen, int casus, int anzahl);
45string make_invlist(object viewer,object *inv);
46static int determine_action(string mess, string name);
47static int create_wizard(mixed who, mixed promoter);
Zesstrab16348b2019-05-21 19:41:36 +020048static int create_seer(object who);
MG Mud User88f12472016-06-24 23:31:02 +020049static void give_help(mixed who);
50int goto(mixed dest);
51
52nosave string *whitespaces=({",",".","?",";",":","-","!","\n","\t"});
Zesstra1b6b7362019-04-25 14:08:02 +020053nosave string prev_room;
MG Mud User88f12472016-06-24 23:31:02 +020054nosave int delay,maxusers,busy;
55nosave string flag;
56
57mapping MBanishListe;
58
59void create()
60{
61 string s;
62 seteuid(ROOTID);
63 if (file_size("/etc/maxusers")<=0)
64 maxusers=0;
65 else
66 {
67 s=read_file("/etc/maxusers",0,1);
68 sscanf(s,"%d",maxusers);
69 }
70 set_living_name("merlin");
71 enable_commands();
72 call_out("wandern",25);
73 move("/gilden/abenteurer",0);
74 MBanishListe = m_allocate(0,2);
75 restore_object(SAVEFILE);
76 EVENTD->RegisterEvent(EVT_LIB_PLAYER_CREATION, "player_change", ME);
77 EVENTD->RegisterEvent(EVT_LIB_LOGIN, "player_change", ME);
78 // absichtlich kein EVT_LIB_LOGOUT, s. Kommentar zu notify_player_leave().
79}
80
81string _query_kill_name()
82{
83 return "Ein genervter Merlin";
84}
85
86int move(mixed ob,int methods)
87{
88 object tmp;
89
90 if (methods&M_GET)
91 return ME_CANT_BE_TAKEN;
92
93 if (stringp(ob))
94 {
95 if (!(tmp=find_object(ob)))
96 {
97 call_other(ob,"?");
98 tmp=find_object(ob);
99 }
100 ob=tmp;
101 }
102 if (!objectp(ob))
103 return 0;
104 if (environment())
105 tell_room(environment(),"Merlin zieht weiter.\n");
106 tell_room(ob,"Merlin kommt an.\n");
107 move_object(ob);
108 return 1;
109}
110
111mixed QueryProp(string str)
112{
113 if (!stringp(str)||str=="")
114 return 0;
115 return call_other(this_object(),"_query_"+str);
116}
117
118varargs int id(string str)
119{
120 return (str=="merlin");
121}
122
123varargs string name(int casus, int demon)
124{
125 if (casus!=WESSEN)
126 return "Merlin";
127 return "Merlins";
128}
129
130varargs string Name(int casus, int daemon)
131{
132 return name(casus,daemon);
133}
134
135string QueryDu(int casus, int gender, int zahl)
136{
137 return
138 ({ ({ ({ "du", "ihr"}), ({ "du", "ihr"}), ({ "du", "ihr"}) }),
139 ({({"deines","deiner"}),({"deines","deiner"}),({"deiner","deiner"})}),
140 ({({"dir","euch"}),({"dir","euch"}),({"dir","euch"})}),
141 ({({"dich","euch"}),({"dich","euch"}),({"dich","euch"})})
142 })[casus][gender][zahl];
143}
144
145string long()
146{
147 EPMASTER->GiveExplorationPoint("merlin");
148 return break_string(
149 "Merlin - der maechtige Urvater aller Magier - ist ein hagerer "
150 "Mann, der einen blauen, mit Monden und Sternen uebersaeten Umhang "
151 "traegt und sich auf einen knorrigen Stock stuetzt. Sein langer weisser "
152 "Bart reicht ihm fast bis zur Guertelschnalle, sein Haupthaar ist fast "
153 "ebenso lang. Auf seinem Kopf traegt er einen spitzen Hut, der ihn noch "
154 "groesser macht, als er ohnehin schon ist.\nEr ist unangreifbar, denn "
155 "er steht ueber solchen Dingen.",78,BS_LEAVE_MY_LFS);
156}
157
158string GetDetail(string key,mixed race,int sense) {
159 switch( sense ) {
160 case SENSE_SMELL: return 0;
161 case SENSE_SOUND: return 0;
162 }
163 switch( key ) {
164 case "nase": case "nasenhaare": case "hakennase":
165 return BS("Merlin hat eine lange, krumme Hakennase, aus deren Nasenloechern weisse Haare spriessen. Auf seiner Nase sitzt eine Brille mit Glaesern in Form eines Halbmondes.");
166 case "brille": case "glaeser": case "form": case "halbmond":
167 return "Merlins Brille besitzt Glaeser in Form eines Halbmondes.\n";
168 case "bart":
169 return "Merlins Bart ist sehr lang - Er reicht fast bis ueber die Guertelschnalle.\n";
170 case "haare" :
171 return "Sie reichen ihm bis zwischen die Schulterblaetter.\n";
172 case "schulterblaetter": case "schulterblatt":
173 return "Seine langen Haare bedecken die Schulterblaetter.\n";
174 case "gewand": case "robe":
175 return BS("Das Gewand ist blau und mit silbernen Monden und Sternen bestickt. Es ist uralt und schon etwas abgetragen, aber es erfuellt immer noch seinen Zweck.");
176 case "zweck":
177 return BS("Der Zweck des Gewandes besteht darn, Merlin standesgemaess zu bekleiden. Diesem Zweck kommt das Gewand in Vollendung nach.");
178 case "vollendung":
179 return "Nichts ist vollkommen.\n";
180 case "hut":
181 return BS("Ein langer, spitzer Hut, der in der gleichen Weise wie seine Robe mit Monden und Sternen bestickt ist.");
182 case "mond": case "monde": case "stern": case "sterne":
183 return BS("Die Monde und die Sterne sind mit silbrigen Faeden gestickt, die das Licht funkelnd zurueckwerfen.");
184 case "faden": case "faeden":
185 return BS("Schwer zu sagen, woraus die Faeden sind. Mithril? "
186 "Mondsilber?");
187 case "licht": case "mondsilber": case "mithril":
188 return BS("Du streckt schon Deine Hand aus, um Merlins Gewand naeher zu untersuchen, aber da trifft Dich sein strenger Blick. Schuechtern nimmst Du von Deinem Vorhaben Abstand.");
189 case "abstand":
190 return BS("Von so einem Magier sollte man aus Respekt einen Schritt Abstand halten.");
191 case "respekt":
192 return "Du hast sicher mehr Respekt vor Merlin, als er vor Dir.\n";
193 case "schritt":
194 return "Wessen Schritt??\n";
195 case "hand": case "haende":
196 return BS("Merlins Haende haben lange, gichtgeplagte Finger und gelbe lange Fingernaegel. Seine linke Hand stuetzt sich auf seinen knorrigen Gehstock. Die rechte Hand ist unter seinem Gewand verborgen.");
197 case "gichtknoten": case "gicht":
198 return BS("Durch die Gichtknoten sehen seine Haende fast so knorrig wie sein Gehstock aus.");
199 case "finger": case "fingernaegel": case "fingernagel":
200 return BS("Seine Finger sind voller Gichtknoten und seine gelben Fingernaegel koennte Merlin auch mal wieder schneiden.");
201 case "gehstock": case "stock":
202 return BS("Merlin stuetzt sich auf einen Gehstock. Der knorrige Stock scheint schon fast Eins mit seiner gichtknotigen Hand geworden zu sein. Ob es sich bei dem Stock um einen Magierstab handelt?");
203 case "zauberstab": case "magierstab":
204 return BS("Merlin stuetzt sich auf einen knorrigen Gehstock. Das koennte sein Zauberstab sein - aber vielleicht ist es auch nur ein Gehstock.");
205 case "guertel": case "guertelschnalle":
206 return BS("Sein Gewand wird von einem weissen Guertel gehalten. Vorne, unter seinem Bart, kannst Du die Guertelschnalle sehen. Auf der Guertelschnalle steht: 'Ich koennte jederzeit aufhoeren.'");
207 }
208 return 0;
209}
210
211
212string short()
213{
214 return "Merlin, der Urvater aller Magier.\n";
215}
216
217string _query_race()
218{
219 return "Magier";
220}
221
222int _query_gender()
223{
224 return 1;
225}
226
227string QueryPossPronoun( mixed what, int casus, int number )
228{
229 int gen2;
230 gen2 = ( intp( what ) ) ? what : what->QueryProp(P_GENDER);
231 return "sein" + query_g_suffix( gen2, casus, number );
232}
233
234string query_g_suffix( int gen, int casus, int anzahl )
235{
236 return ({ ({ ({"","e"}), ({"es","er"}), ({"em","en"}), ({"","e"}) }),
237 ({ ({"","e"}), ({"es","er"}), ({"em","en"}), ({"en","e"}) }),
238 ({ ({"e","e"}), ({"er","er"}), ({"er","en"}), ({"e","e"}) }) })
239 [gen][casus][anzahl];
240}
241
242string QueryPronoun(int casus)
243{
244 switch(casus) {
245 case WER: return "er"; break;
246 case WEM: return "ihm";
247 }
248 return "ihn";
249}
250
251string _query_short()
252{
253 return short();
254}
255
256string _query_long()
257{
258 return long();
259}
260
261string _query_name()
262{
263 return "Merlin";
264}
265
266int _query_weight()
267{
268 return 75000;
269}
270
271static void PostSeher(string who, int g)
272{
273 mixed *art;
274
275 art=({"stufen","Merlin",0,0,sprintf("%s ist jetzt ein%s Seher%s!",who,(g==2?"e":""),(g==2?"in":"")),sprintf("\nAm %s hat %s die noetigen Bedingungen\nerfuellt und ist vom Spielerstatus zum Seherstatus aufgestiegen. \n\n Herzlichen Glueckwunsch, %s!\n",dtime(time()),who,who)});
276 "/secure/news"->WriteNote(art,1);
277}
278
279static void PostMagier(string who, string prom, int gender)
280{
281 mixed *art;
282
283 art=({"stufen","Merlin",0,0,sprintf("%s ist jetzt ein%s Magier%s!",who,(gender==2?"e":""),(gender==2?"in":"")),sprintf("\nAm %s hat %s %s zu%s Magier%s\nberufen. Herzlichen Glueckwunsch, %s. Glueckwuensche auch an Dich,\n %s, zu Deine%s neuen %s!\n",dtime(time()),prom,who,(gender==2?"r":"m"),(gender==2?"in":""),who,prom,
284(gender==2?"r":"m"),(gender==2?"Tochter":"Sohn"))});
285 "/secure/news"->WriteNote(art,1);
286}
287
288
289private void GibFehlerteufel(object wiz) {
290 if (!objectp(wiz))
291 return;
292
293 clone_object(FEHLERTEUFEL)->move(wiz, M_NOCHECK|M_GET);
294 tell_object(wiz, break_string(
295 "Huhu "+wiz->Name(WER) + "! Ich habe gesehen, dass Du keinen "
296 "Fehlerteufel hast. Dieses Tool ist zum Debuggen von Fehlern im "
297 "Mud sehr praktisch. Bitte schau ihn Dir mal an. :-) Die Hilfe zum "
298 "Fehlerteufel kannst Du mit 'man fehlerteufel' lesen. BTW: Wenn "
299 "Du den Fehlerteufel nicht willst, kannst Du ihn zerstoeren, ich "
300 "werde Dich kein zweites Mal damit belaestigen.",78,
301 "Merlin teilt Dir mit: ")
302 + "Merlin ueberreicht Dir aus der Ferne einen knusprig gebratenen "
303 "Fehlerteufel.\n\n");
304}
305
306private void notify_player_change(string who,int rein)
307{
308 if (!stringp(who))
309 return;
310
311 // Max-user festhalten
312 if (file_size("/etc/maxusers")<=0)
313 maxusers=0;
314 if (sizeof(users())>=maxusers)
315 {
316 maxusers=sizeof(users());
317 write_file("etc/maxusers",sprintf("%d user: %s (%s)\n",
318 maxusers,dtime(time()),query_load_average()),1);
319 }
320
321 // allen Magiern ab Level 20, die keinen Fehlerteufel haben und deren
322 // letzter Logout vor "Die, 17. Mar 2009, 23:40:04" => 1237329604 war,
323 // einen Fehlerteufel clonen und nen Hiwneis mitteilen.
324 object ob = find_player(who);
325 if (ob && rein && IS_WIZARD(ob)
326 && !present_clone(FEHLERTEUFEL,ob)
327 && ob->QueryProp(P_LAST_LOGOUT) < 1237329604 )
328 GibFehlerteufel(ob);
329}
330
331private void AnnounceNewPlayer(object pl) {
332
333 if (!pl || !interactive(pl))
334 return;
335
336 // verzoegern, bis der Spieler wirklich fertig ist.
337 if (pl->QueryProp(P_LEVEL) < 0) {
338 call_out(#'AnnounceNewPlayer,10,pl);
339 return;
340 }
341
342 if (!(int)pl->QueryGuest()) {
343 string plname = (string)pl->Name(WER);
344 CHMASTER->send("Anfaenger", this_object(),
345 sprintf("%s macht nun ebenfalls das Morgengrauen unsicher. "
346 "Herzlich Willkommen %s!", plname, plname)
347 );
348 }
349}
350
351// Kann bei reboot wieder raus... zesstra, 16.03.2007
352#if __BOOT_TIME__ < 1318110723
353#define BUGTIME 1318003200
354#define BUGFIXTIME 1318109421
355void renew_player(string plname, int force) {
356 object pl;
357 mixed err;
358
359 pl = find_player(plname);
360 if (!objectp(pl) || !query_once_interactive(pl)) return;
361
362 // jung oder alt genug, Abbruch. ;-)
363 if ((object_time(pl) > BUGFIXTIME)
364 || object_time(pl) < BUGTIME)
365 return;
366
367 if (get_eval_cost() < 1000000 || !force ) {
368 call_out("renew_player",8,plname,1);
369 tell_object(pl,break_string(sprintf("Huhu %s, um einen Bug in "
370 "Deinem Spielerobjekt zu beheben, wirst Du in ca. 8s "
371 "neugeladen. Bitte warte bis dahin ab und bleibe, wo "
372 "Du gerade bist.",pl->Name()),78,"Merlin teilt Dir mit: "));
373 return;
374 }
375
376 plname=getuid(pl);
377 tell_object(pl,break_string(sprintf("Huhu %s, um einen Bug in "
378 "Deinem Spielerobjekt zu beheben, wirst Du jetzt "
379 "neugeladen.",pl->Name()),78,"Merlin teilt Dir mit: "));
380
381 if (err=catch(master()->renew_player_object(pl);publish)) {
382 log_file("zesstra/failed_rewew.log",sprintf("%s: Fehler %O beim "
383 "Renew von %s\n",dtime(time()),err,plname));
384 tell_object(pl,break_string("Beim Neuladen Deines Spielerobjekts "
385 "gab es einen Fehler. Bitte wende Dich an einen EM.",78,
386 "Merlin teilt Dir mit: "));
387 }
388 else {
389 log_file("zesstra/renewed.log",sprintf("%s: %s wurde renewed.\n",
390 dtime(time()),plname));
391 if (objectp(find_player(plname)))
392 tell_object(find_player(plname),
393 break_string("Dein Spielerobjekt wurde neugeladen. Du "
394 "kannst jetzt normal weiterspielen. Falls Du etwas ungewoehnliches "
395 "bemerkst, melde Dich bitte bei einem Erzmagier. Viel Spass im "
396 "Spiel!",78, "Merlin teilt Dir mit: "));
397 }
398}
399#endif
400
401void player_change(string eid, object trigob, mixed data) {
402
403 if (!trigob || !interactive(trigob))
404 return;
405
406 switch(eid) {
407 case EVT_LIB_PLAYER_CREATION:
408 call_out(#'AnnounceNewPlayer, 5, trigob);
409 break;
410 case EVT_LIB_LOGIN:
411 notify_player_change(data[E_PLNAME],1);
412#if __BOOT_TIME__ < 1318110723
413 // Spieler evtl. renewen? Bei reboot raus (08.10.2011)
414 renew_player(data[E_PLNAME],0);
415#endif
416 break;
417 }
418}
419
420
421//besser P_NO_ATTACK als Defend()...
422mixed _query_no_attack() {
423 if (!living(PL) || !objectp(environment(PL)) ) return(1);
424
425 tell_room(environment(), "Merlin schimpft: Lass das!!!\n",({PL}));
426 tell_room(environment(),sprintf(
427 "Merlin gibt %s eine schallende Ohrfeige.\n",
428 capitalize((string)this_player()->name(WEM))), ({this_player()}));
429 return("Merlin schimpft: Lass das!!!\n"
430 "Merlin gibt Dir eine schallende Ohrfeige.\n");
431}
432
433/*
434int Defend(int dam, string dam_type, int spell, object enemy)
435{
436 object en;
437 if (!en=previous_object() || !living(en))
438 en = this_player();
439 tell_room(environment(), "Merlin schimpft: Lass das!!!\n");
440 write("Merlin gibt Dir eine schallende Ohrfeige.\n");
441 say(sprintf("Merlin gibt %s eine schallende Ohrfeige.\n",
442 capitalize((string)this_player()->name(WEM))), this_player());
443 en->StopHuntFor(this_object(), 1);
444}
445*/
446void shoutansw()
447{
448 object env,ti;
449 string *path;
450 string ans;
451
452 if (!(env=environment()))
453 return;
454 if (!(ti=this_interactive())||(int)ti->QueryProp(P_LEVEL)<19||ti->QueryProp(P_GHOST))
455 return;
456 tell_object(ti,"Du spuerst einen sengenden Schmerz.\n");
457 ti->do_damage( ((int)ti->QueryProp(P_HP)) / 2 + 5);
458 if((int)ti->QueryProp(P_GHOST)) return;
459 ans="ich hab nicht die leiseste Idee, wo ich hier bin ...\n";
460 path=old_explode(object_name(env),"/");
461 if (path[0]=="d")
462 {
463 ans="werweisswo ..";
464 switch(path[1])
465 {
466 case "gebirge":
467 case "wald":
468 case "dschungel":
469 ans="im "+capitalize(path[1]);
470 break;
471 case "inseln":
472 ans="auf den Inseln";
473 break;
474 case "polar":
475 ans="im Polargebiet";
476 break;
477 case "unterwelt":
478 case "ebene":
479 case "wueste":
480 ans="in der "+capitalize(path[1]);
481 break;
482 case "vland":
483 ans="im Verlorenen Land";
484 break;
485 case "fernwest":
486 ans="in Fernwest";
487 break;
488 }
489 ans="ich bin "+ans+".\n";
490 }
491 if (path[0]=="players")
492 ans="ich hab mich verlaufen - ich schaetze, "+capitalize(path[1])+
493 " hat was damit zu tun...\n";
494 if (path[0]=="gilden") {
495 switch(path[1]) {
496 case "abenteurer":
497 ans="der Abenteurergilde";
498 break;
499 case "bierschuettler":
500 ans="der Bierschuettlergilde";
501 break;
502 case "chaos":
503 ans="der Gilde der Chaoten";
504 break;
505 case "kaempfer":
506 ans="der Kaempfergilde";
507 break;
508 case "karate":
509 ans="einem Karatedojo";
510 break;
511 case "klerus":
512 ans="einem Tempel der Kleriker";
513 break;
514 case "zauberer":
515 ans="der Akademie der Zauberer";
516 break;
517 default:
518 ans="irgendeiner Gilde";
519 }
520 ans="ich stehe in "+ans+".\n";
521 }
522 if( path[0]=="p" && path[1]=="verein" ) {
523 ans="ich stehe in Port Vain.";
524 }
525 if (!this_interactive()->QueryProp(P_INVIS))
526 ans=this_interactive()->Name(WER)+", "+ans;
527 else ans=capitalize(ans);
528 call_out("myshout",0,break_string(ans, 78, "Merlin ruft: "));
529}
530
531void myshout(string s)
532{
533 write(s);
534 shout(s);
535}
536
537void catch_tell(string str)
538{
539 string name, dummy; mixed message;
540 int i,s;
541
542 if (!this_player())
543 return;
544
545 if (environment()==environment(this_player()) && previous_object()!=ME)
546 tell_room(this_object(),"*"+str);
547
548 if (this_player() != this_interactive())
549 return;
550
551 if (busy) {
552 tell_object(this_player(),
553 "Merlin teilt Dir mit: Ich bin beschaeftigt.\n");
554 return;
555 }
556
557 str=lower_case(str);
558
559 if ((strstr(str, "teilt dir mit:") != -1)
560 && (strstr(str, "wo bist du") !=-1)) {
561 shoutansw();
562 return;
563 }
564
565 if ((strstr(str, "teilt dir mit:") != -1) &&
566 ((strstr(str, "seher") != -1 || strstr(str, "seherin") != -1)))
567 {
568 create_seer(this_player());
569 return;
570 }
571
572 if (sscanf(str,"%s %s sagt: %s",dummy,name,message)!=3)
573 if (sscanf(str,"%s sagt: %s",name,message)!=2)
574 return;
575
Zesstraf5a8bf32017-01-30 23:06:00 +0100576 if (!name || !sizeof(name) || !master()->find_userinfo(name))
MG Mud User88f12472016-06-24 23:31:02 +0200577 return;
578
579 if (name!=getuid(this_interactive()) && !ARCH_SECURITY)
580 {
581 if (flag==getuid(this_interactive())+"##"+name)
582 return;
583 call_out("do_say",0,"Merlin sagt: "+capitalize(getuid(this_interactive()))+" hat gerade so getan, als wuerde "+capitalize(name)+" etwas sagen!\n");
584 flag=getuid(this_interactive())+"##"+name;
585 call_out("clear_flag",0);
586 return;
587 }
588 flag=0;
589 for (i=0;i<sizeof(whitespaces);i++)
590 {
591 message=old_explode(message,whitespaces[i]);
592 if (!pointerp(message)||sizeof(message)==0)
593 return;
594 message=implode(message," ");
595 }
596
597 message=old_explode(message," ");
598
599 if (!pointerp(message) || !sizeof(message))
600 return;
601
602 message-=({0})-({""});
603
604 if (!message || sizeof(message)==0)
605 return;
606
607 if (member(message, "merlin")==-1)
608 return;
609
610 message-=({"merlin"});
611
612 message=implode(message," ");
613
614 if (!message || message=="")
615 return;
616
617 determine_action(message, name);
618}
619
620static int determine_action(string mess, string name)
621{
622 string str;
623
624 if (mess=="mach mich zum magier" || mess=="mach mich zur magierin")
625 return create_wizard(name,name);
626
627 if (sscanf(mess,"mach %s zum magier",str)==1||sscanf(mess,"mach %s zur magierin",str)==1)
628 return create_wizard(lower_case(str),name);
629
630 give_help(name);
631 return 0;
632}
633
634#define Say(str) say(str,who)
635#define Write(str) tell_object(who,str)
636
637int QueryBedingungen(object pl,string was)
638{
639 int ret,i,gen;
640 string s;
641
642 if (IS_SEER(pl))
643 return 1;
644
645 if ((int)LEPMASTER->QueryReadyForWiz(pl)==1)
646 return 1;
647
648 s=(string)LEPMASTER->QueryReadyForWizText(pl);
649
650 tell_object(pl, break_string("Merlin gruebelt ein wenig und teilt Dir "
651 "nach einigem Ueberlegen mit:\n\n", 78,0,1));
652
653 tell_object(pl, s+"\n");
654
655 tell_object(pl, break_string("Da ist wohl fuer Dich noch etwas zu tun...",
656 78, "Merlin teilt Dir mit: "));
657
658 if (environment() == environment(pl))
659 say((string)pl->name(WER)
660 +" erfuellt noch nicht alle Anforderungen fuer den "+was+"status.\n",pl);
661
662 return 0;
663}
664
665static int create_wizard(mixed who, mixed promoter)
666{
667 mixed *domains;
668 object vertrag;
669 int ret;
670 string gen;
671
672 who=find_player(who);
673 promoter=find_player(promoter);
674 if (!who || !promoter)
675 return 0;
676 //
677 // player not interactive?
678 //
679 if (!interactive(who))
680 {
681 write(capitalize(getuid(who))+" ist nicht aktiv.\n");
682 return 0;
683 }
684 //
685 // player is second?
686 //
687 if (who->QueryProp(P_SECOND))
688 {
689 tell_object(who,"Du bist ein Zweitspieler und kannst als solcher kein Magier werden.\n"
690 +"Versuchs Doch mal mit Deinem Erstie.\n");
691 write("Du kannst "+who->name()+" nicht zum Magier machen. Das geht bei "
692 +"Zweities\nleider nicht. Frag doch mal nach dem Erstie.\n");
693 return 1;
694 }
695 //
696 // wants to advance himself?
697 //
698 if (who==promoter)
699 {
700 write("Du kannst Dich nicht selber befoerdern. Such Dir dazu bitte einen "+
701 "Vollmagier,\nder Dir einen Vertrag gibt.\n");
702 return 1;
703 }
704 //
705 // banished?
706 //
707 if (MBanishListe[who,1])
708 {
709 tell_object(promoter,capitalize(who)+" darf nur von einem Erzmagier zum "+
710 "Magier gemacht werden.\n");
711 say(promoter->name(WER)+" ist kein Erzmagier und darf "+capitalize(who)+
712 " nicht zum Magier machen.\n");
713 return 1;
714 }
715 //
716 // player has PK?
717 //
718 if (who->QueryProp("playerkills")) {
719 tell_room(environment(who),who->name()+" hat noch einen Playerkill und kann somit kein Magier werden.\n"
720 "Am besten den Sheriff oder einen Erzmagier verstaendigen.\n");
721 return 1;
722 }
723 //
724 // already dom_member?
725 //
726 if (IS_DOMAINMEMBER(who))
727 {
728 Write("Fuer Dich kann ich nichts mehr tun. Du bist doch schon Magier!\n");
729 return 1;
730 }
731
732 //
733 // "advanced learner"?
734 //
735 if (query_wiz_level(who) == 20)
736 {
737 if (!ARCH_SECURITY) {
738 Write("Dich kann nur ein Erzmagier zum \"richtigen\" Magier machen!\n");
739 Say("Nur ein Erzmagier kann "+who->name(WEN)+" zum \"richtigen\" Magier machen!\n");
740 return 0;
741 }
742 ret=(int)"secure/master"->advance_wizlevel(geteuid(who),21);
743 if (ret<=0)
744 {
745 say("Merlin: error "+ret+"\n");
746 write("Merlin: error "+ret+"\n");
747 }
748 write("Merlin ruft: "+(string)who->name(WER)+" ist in den Kreis der Magier "+
749 "aufgenommen worden!\n");
750 shout("Merlin ruft: "+(string)who->name(WER)+" ist in den Kreis der Magier "+
751 "aufgenommen worden!\n");
752 "secure/master"->renew_player_object(who);
753 return 1;
754 }
755
756 //
757 // already wizard?
758 //
759 if (IS_WIZARD(who))
760 {
761 domains=(string*)"secure/master"->get_domain_homes(getuid(who));
762 if (!domains || !pointerp(domains) || !sizeof(domains))
763 {
764 Say(who->name(WER)+" gehoert noch keiner Region an und kann daher noch "+
765 "kein Voll-\nmagier werden.\n");
766 Write("Du gehoerst noch keiner Region an. Schliess Dich zunaechst einer "+
767 "an und komm\ndann wieder!\n");
768 return 0;
769 }
770 ret=(int)"secure/master"->advance_wizlevel(geteuid(who),25);
771 if(ret>0)
772 {
773 shout(who->name(WER)+" arbeitet jetzt an einer Region mit!\n");
774 "secure/master"->renew_player_object(who);
775 return 1;
776 }
777 write("RETURNVALUE "+ret+"\n");
778 say("RETURNVALUE "+ret+"\n");
779 return 0;
780 }
781
782 //
783 // still learner?
784 //
785 if (IS_LEARNER(who))
786 {
787 if (!ARCH_SECURITY) {
788 Write("Dich kann nur ein Erzmagier zum \"richtigen\" Magier machen!\n");
789 Say("Nur ein Erzmagier kann "+who->name(WEN)+" zum \"richtigen\" Magier machen!\n");
790 return 0;
791 }
792 ret=(int)"secure/master"->advance_wizlevel(geteuid(who),20);
793 if (ret<=0)
794 {
795 say("Merlin: error "+ret+"\n");
796 write("Merlin: error "+ret+"\n");
797 }
798 string wizname = (string)who->query_real_name();
799 "secure/master"->renew_player_object(who);
800 // Fehlerteufel geben
801 call_out(#'GibFehlerteufel,4,find_player(wizname));
802 return 1;
803 }
804
805 //
806 // promoter's level is not >DOMAINMEMBER_LVL+1
807 //
808 if (secure_level()<=DOMAINMEMBER_LVL)
809 {
810 tell_object(promoter,"Du musst derzeit mindestens Level "+
811 (DOMAINMEMBER_LVL+1)+" haben, um jemanden befoerden zu "+
812 "koennen.\n");
813 say(promoter->name(WER)+" ist kein Vollmagier und darf daher niemanden "+
814 "zum Vollmagier machen.\n");
815 return 1;
816 }
817
818 // der Check auf den Blutprintnamen ist fast ueberfluessig, aber nur fast.
819 // Er schlaegt fehl, wenn der Vertrag der Clone einer alten BP ist.
820 if (!(vertrag=present_clone("/obj/vertrag",who)) ||
821 object_name(blueprint(vertrag))!="/obj/vertrag" ||
822 !((int)vertrag->is_unterschrieben()) )
823 {
824 Write("Du hast ja gar keinen unterschriebenen Vertrag bei Dir. Besorg Dir "+
825 "einen Ver-\ntrag, unterschreibe ihn und komm dann wieder!\n");
826 Say(who->name(WER)+" hat keinen unterschriebenen Vertrag.\n");
827 return 1;
828 }
829 if (geteuid(vertrag)!=secure_euid())
830 {
831 tell_object(promoter,"Das geht nicht, er hat einen Vertrag von "+
832 capitalize(geteuid(vertrag))+" bei sich.\n");
833 say(promoter->name(WER)+" versucht, "+who->name(WER)+" zum Magier zu "+
834 "machen, doch "+who->name(WER)+" hat einen Vertrag\nvon "+
835 capitalize(geteuid(vertrag))+" bei sich.\n",promoter);
836 return 0;
837 }
838 if (!QueryBedingungen(who,"Magier"))
839 return 0;
840 ret=(int)"secure/master"->advance_wizlevel(geteuid(who),15);
841 if (ret>0)
842 {
843 PostMagier(capitalize(getuid(who)),
844 capitalize(secure_euid()),(int)who->QueryProp(P_GENDER));
845 write_file("/log/SPONSOR",dtime(time())+": "+capitalize(getuid(promoter))+" macht "+
846 who->name(WER)+" zum Learner.\n");
847 write(who->name(WER)+" ist in den Kreis der Magier aufgenommen worden!\n");
848 shout(who->name(WER)+" ist in den Kreis der Magier aufgenommen worden!\n");
849 if ("secure/master"->set_player_object(geteuid(who),"/std/shells/magier")
850 <=0)
851 {
852 say("MERLIN: konnte Magiershell nicht einstellen.\n");
853 write("MERLIN: konnte Magiershell nicht einstellen.\n");
854 }
855 "secure/master"->renew_player_object(who);
856 return 1;
857 }
858 write(" --RETURNVALUE IS "+ret+"\n");
859 say(" --RETURNVALUE IS "+ret+"\n");
860
861 return(ret); //non-void funktion
862}
863
864void clear_flag()
865{
866 flag=0;
867}
868
869void do_say(string str)
870{
871 say(str);
872}
873
874
875
Zesstrab16348b2019-05-21 19:41:36 +0200876void seer_sequenz3(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200877{
878 string playername;
879 object faq;
880 string text;
881
882 if (!objectp(player)) {
883 tell_room(environment(), sprintf("Merlin sagt: Na, wo ist denn %s "
884 "hin?\n", plname));
885 busy = 0;
886 return;
887 }
888 if (environment() != environment(player))
889 move(environment(player), M_TPORT);
890
891 tell_object(player,break_string("\n\nEs macht *PUFF* und eine Schwefelwolke "
892 +"steigt um Dich herum auf.\n\nDie Aura "
893 +"verschwindet langsam und Du fuehlst Dich "
894 +"nun viel erfahrener.", 78,0,1));
895 tell_room(environment(),
896 break_string(sprintf(
897 "\n\nEs macht *PUFF* und eine Schwefelwolke steigt "
898 +"um %s herum auf.\n\nDie Aura verschwindet langsam.\n",
899 plname),78,0,1), ({player}));
900
901 if ("secure/master"->advance_wizlevel(geteuid(player),1)<=0)
902 {
903 write("Merlin sagt: Da geht was schief ... sag mal Zook Bescheid.\n");
904 say("Merlin sagt: Da geht was schief ... sag mal Zook Bescheid.\n");
905 busy = 0;
906 return;
907 }
908 playername = geteuid(player);
909 "secure/master"->renew_player_object(player);
910 player = find_player(playername);
911 text = sprintf(" ist jetzt ein%s Seher%s!\n",
912 (((int)player->QueryProp(P_GENDER))==2?"e":""),
913 (((int)player->QueryProp(P_GENDER))==2?"in":""));
914 write("Merlin ruft: "+capitalize(playername)+text);
915 shout("Merlin ruft: "+capitalize(playername)+text);
916 PostSeher(capitalize(playername),(int)player->QueryProp(P_GENDER));
917 if(!catch(
918 faq=clone_object("/d/seher/haeuser/special/seherfaqmobil") ;publish))
919 {
920 faq->move(player,M_NOCHECK);
921 tell_object(player, "Aus dem Nichts erscheint eine kleine Belohnung fuer Dich.\n");
922 }
923
924 tell_object(player, "\n\nDu laechelst gluecklich in die Runde.\n\n");
925 tell_room(environment(), sprintf("\n\n%s laechelt gluecklich in die Runde.\n\n", plname), ({player}));
926
927 busy=0;
928}
929
Zesstrab16348b2019-05-21 19:41:36 +0200930void seer_sequenz2(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200931{
932 if (!objectp(player)) {
933 tell_room(environment(), sprintf(
934 "Merlin sagt: Na, wo ist denn %s hin?\n",
935 plname));
936 busy = 0;
937 return;
938 }
939 if (environment() != environment(player))
940 move(environment(player), M_TPORT);
941
zesstra70a0a3e2016-07-06 20:35:40 +0200942 tell_object(player, break_string("\nMerlin hebt die Arme "
MG Mud User88f12472016-06-24 23:31:02 +0200943 +"und macht einige beschwoerende Gesten. Um Dich herum erscheint "
944 +"eine gelbliche Aura, die immer heller wird, bis Du Deine "
945 +"Umwelt kaum mehr erkennen kannst.\n\n",
946 78,0,1));
947 tell_room(environment(),
948 break_string(sprintf("\nMerlin hebt die Arme und macht einige "
949 +"beschwoerende Gesten. Um %s erscheint eine "
950 +"gelbliche Aura, die immer heller wird, bis "
951 +"man %s kaum mehr erkennen kann.\n\n",
952 plname, plname),78,0,1), ({player}));
953
954 call_out("seer_sequenz3", 7, player, plname);
955}
956
Zesstrab16348b2019-05-21 19:41:36 +0200957void seer_sequenz1(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200958{
959 if (!objectp(player))
960 return;
961
962 move(environment(player), M_TPORT);
963
964 tell_room(environment(),
965 break_string(sprintf("Das ist eine grosse Freude. %s hat sich "
966 "tapfer durch das "MUDNAME" geschlagen und mittlerweile alle "
967 "Anforderungen erfuellt, um %s zu werden.",
968 plname, ((int)player->QueryProp(P_GENDER))==1?"Seher":"Seherin"),
969 78, "Merlin sagt: "));
970
971 call_out("seer_sequenz2", 4, player, plname);
972}
973
974
Zesstrab16348b2019-05-21 19:41:36 +0200975static int create_seer(object player)
MG Mud User88f12472016-06-24 23:31:02 +0200976{
977 if (!objectp(player))
978 return 0;
979 if (IS_SEER(player))
980 {
981 write(break_string("Du bist doch schon kein normaler Spieler mehr, "
982 +"was soll es also?", 78, "Merlin teilt Dir mit: "));
983 return 1;
984 }
985
986 if (!QueryBedingungen(player,"Seher"))
987 return -1;
988
989
990 write(break_string("Grosse Freude! Du hast alle Anforderungen "
991 "erfuellt. Warte einen Moment...", 78,
992 "Merlin teilt Dir mit: "));
993 busy=1;
994 call_out("seer_sequenz1",4,player, player->Name());
995 return(0); //non-void funktion
996}
997
998static void give_help(mixed player)
999{
1000 if (!objectp(player))
1001 return;
1002
1003 tell_object(player,
1004 break_string("Ich weiss nicht, was ich fuer Dich tun kann. "
1005 +"Ich kann Dich zum Seher oder zum Magier "
1006 +"machen, wenn Du mich darum bittest.", 78,
1007 "Merlin teilt Dir mit: "));
1008}
1009
1010
1011void reset()
1012{
1013}
1014
1015public int remove(int silent) {
1016 EVENTD->UnregisterEvent(EVT_LIB_LOGIN, ME);
1017 EVENTD->UnregisterEvent(EVT_LIB_PLAYER_CREATION, ME);
1018 destruct(this_object());
1019 return 1;
1020}
1021
1022void wandern()
1023{
MG Mud User88f12472016-06-24 23:31:02 +02001024 while (remove_call_out("wandern")>=0);
1025 call_out("wandern",45+random(100));
1026 if (busy) return;
1027 if (delay)
1028 {
1029 delay=0;
1030 return;
1031 }
Zesstra1b6b7362019-04-25 14:08:02 +02001032 if (!environment())
MG Mud User88f12472016-06-24 23:31:02 +02001033 {
1034 move("/gilden/abenteurer",0);
MG Mud User88f12472016-06-24 23:31:02 +02001035 }
1036 //ueber Inv iterieren, ob da ein nicht-idelnder Spieler mit genug XP
Zesstra1b6b7362019-04-25 14:08:02 +02001037 //rumhaengt. In diesem Raum bleiben, wenn ja.
1038 foreach(object ob: all_inventory(environment()))
1039 {
1040 if (interactive(ob) && query_idle(ob)<180
1041 && ob->QueryProp(P_XP)>999999)
MG Mud User88f12472016-06-24 23:31:02 +02001042 return;
1043 }
Zesstra1b6b7362019-04-25 14:08:02 +02001044 // Ausgaenge durchsuchen
1045 mapping ex=(mapping)environment()->QueryProp(P_EXITS);
MG Mud User88f12472016-06-24 23:31:02 +02001046 if (!mappingp(ex))
1047 return;
Zesstra1b6b7362019-04-25 14:08:02 +02001048 mapping rooms = m_allocate(sizeof(ex));
1049 foreach(string cmd, string|closure dest, string msg : ex)
MG Mud User88f12472016-06-24 23:31:02 +02001050 {
Zesstra1b6b7362019-04-25 14:08:02 +02001051 object ob;
1052 // nur normale Ausgaenge benutzen
1053 if (!stringp(dest)
1054 || dest = object_name(environment()))
MG Mud User88f12472016-06-24 23:31:02 +02001055 continue;
Zesstra1b6b7362019-04-25 14:08:02 +02001056 rooms += ([dest]);
MG Mud User88f12472016-06-24 23:31:02 +02001057 }
Zesstra1b6b7362019-04-25 14:08:02 +02001058 if (!sizeof(rooms))
1059 return;
1060
1061 // Und nicht zuruecklatschen, wenn moeglich.
MG Mud User88f12472016-06-24 23:31:02 +02001062 if (prev_room && sizeof(m_indices(rooms))>1)
1063 rooms-=([prev_room]);
Zesstra1b6b7362019-04-25 14:08:02 +02001064 prev_room=object_name(environment());
1065
1066 string *raeume=m_indices(rooms);
1067 move(raeume[sizeof(raeume)],0);
MG Mud User88f12472016-06-24 23:31:02 +02001068}
1069
1070string int_short()
1071{
1072 return "Du bist im allseits beliebten Wizclub \"Zum lustigen Merlin\".\n";
1073}
1074
1075string int_long(object who,mixed where)
1076{
1077 string descr;
1078
1079 if( IS_LEARNER(who) && who->QueryProp( P_WANTS_TO_LEARN ) )
1080 descr = "[" + object_name(ME) + "]\n";
1081 else
1082 descr = "";
1083 descr+="Du bist im Wizclub 'Zum lustigen Merlin'. Dieser Wizclub ist etwas besonderes -\ner hat keinen festen Standort, sondern wandert im Mud herum. Ausserdem kann er\nSpieler zu Magiern machen - aber nur, wenn man ihn von aussen aus darauf\nanspricht.\n";
1084 if ( who->QueryProp(P_SHOW_EXITS) )
1085 descr += "Es gibt 2 sichtbare Ausgaenge: raus und gilde.\n";
1086 descr += make_invlist(who, all_inventory(ME) - ({ who }));
1087 if( environment())
1088 descr += "\nAusserhalb siehst Du:\n"
1089 + environment()->int_short(who,ME);
1090 return descr;
1091}
1092
1093string make_invlist(object viewer,object *inv)
1094{
1095 int i, iswiz;
1096 string descr;
1097
1098 descr = "";
1099 iswiz = IS_LEARNER( viewer ) && viewer->QueryProp(P_WANTS_TO_LEARN);
1100
1101 for (i = 0; i < sizeof(inv); i++)
1102 {
1103 string sh;
1104 sh = (string)inv[i]->short();
1105 if (iswiz)
1106 {
1107 if (sh) sh = sh[0..<2] + " ["+object_name(inv[i])+"]\n";
1108 else sh = "["+object_name(inv[i])+"]\n";
1109 }
1110 if (sh) descr += sh;
1111 }
1112 return descr;
1113}
1114
1115void init()
1116{
1117 if (interactive(this_player()) && environment(this_player())==ME)
1118 add_action("gehen","",1);
1119 add_action("befoerdere","befoerder",1);
1120}
1121
1122int befoerdere(string str)
1123{
1124 string wen;
1125 int ret,stufe,l;
1126
1127 if (!LORD_SECURITY) return 0;
1128 if (!str||sscanf(str,"%s auf stufe %d",wen,stufe)<2)
1129 {
1130 notify_fail("Syntax: befoerdere <name> auf stufe <stufe>\n");
1131 return 0;
1132 }
1133 if (stufe>29)
1134 {
1135 write("Maximum ist Stufe 29!\n");
1136 return 1;
1137 }
1138 l=query_wiz_level(wen);
1139 if (l<25)
1140 {
1141 printf("%s muss mindestens zwecks Weiterbefoerderung mindestens Stufe 25 haben.\n",
1142 capitalize(wen));
1143 return 1;
1144 }
1145 if (l>=stufe)
1146 {
1147 printf("%s ist schon Stufe %d.\n",capitalize(wen),l);
1148 return 1;
1149 }
1150 ret=(int)"secure/master"->advance_wizlevel(wen,stufe);
1151 if (ret<=0)
1152 printf("Errorcode %d\n",ret);
1153 else
1154 write("ok\n");
1155 return 1;
1156}
1157
1158int sag(mixed str)
1159{
1160 int i;
1161
1162 if (str==0)
1163 str="";
1164 str = old_explode(break_string(str, 60 ), "\n");
1165 if (busy) {
1166 tell_room(ME, "Merlin mault: Ich bin beschaeftigt.\n");
1167 return 0;
1168 }
1169 for (i = 0; i < sizeof(str); i++)
1170 {
1171 if (!str[i])
1172 str[i]="";
1173 tell_room(environment(),"Merlin sagt: "+str[i]+"\n");
1174 tell_room(ME,"*Merlin sagt: "+str[i]+"\n");
1175 }
1176 return 1;
1177}
1178
1179void show_exits()
1180{
1181 printf("%s",environment()->GetExits());
1182}
1183
1184int gehen(string str)
1185{
MG Mud User88f12472016-06-24 23:31:02 +02001186 if (busy) {
1187 write("Merlin mault: Ich bin beschaeftigt.\n");
1188 return 0;
1189 }
1190
MG Mud User88f12472016-06-24 23:31:02 +02001191 str=(string)this_interactive()->_unparsed_args();
Zesstra1b6b7362019-04-25 14:08:02 +02001192 switch (query_verb())
MG Mud User88f12472016-06-24 23:31:02 +02001193 {
1194 case "gilde":
1195 this_player()->move("/gilden/abenteurer",M_GO,"in die Gilde");
1196 return 1;
1197 case "raus":
1198 this_player()->move(environment(),M_GO,"raus");
1199 return 1;
1200 }
1201 if (!IS_WIZARD(this_interactive()))
1202 return 0;
Zesstra1b6b7362019-04-25 14:08:02 +02001203 if (query_verb()!="merlin")
MG Mud User88f12472016-06-24 23:31:02 +02001204 return 0;
1205 delay=1;
Zesstra1b6b7362019-04-25 14:08:02 +02001206 mapping exits=(mapping)environment()->QueryProp(P_EXITS);
MG Mud User88f12472016-06-24 23:31:02 +02001207 if (!str||str=="")
1208 {
MG Mud User88f12472016-06-24 23:31:02 +02001209 printf(environment()->int_short(ME,ME));
1210 show_exits();
1211 return 1;
1212 }
1213 if (old_explode(str," ")[0]=="sag")
1214 return sag(implode(old_explode(str," ")[1..]," "));
1215 if (str[0]==';')
1216 {
1217 tell_room(environment(ME),"Merlins "+str[1..]+"\n");
1218 tell_room(ME,"*Merlins "+str[1..]+"\n");
1219 return 1;
1220 }
1221 if (str[0]==':')
1222 {
1223 tell_room(environment(ME),"Merlin "+str[1..]+"\n");
1224 tell_room(ME,"*Merlin "+str[1..]+"\n");
1225 return 1;
1226 }
1227 if (str[0]=='*')
1228 {
1229 goto(str[1..]);
1230 printf(environment()->int_short(ME,ME));
1231 show_exits();
1232 return 1;
1233 }
1234 if (!exits[str])
1235 return 0;
1236 move(exits[str],0);
1237 write("Merlin sagt: Jawoll, Chef.\n");
1238 printf(environment()->int_short(ME,ME));
1239 show_exits();
1240 return 1;
1241}
1242
1243int goto(mixed dest)
1244{
1245 object ob;
1246 string path;
1247 mixed ret;
1248
1249 if (busy) {
1250 write("Merlin mault: Ich bin beschaeftigt.\n");
1251 return 1;
1252 }
1253
1254 if (!dest) {
1255 write("Wohin moechtest Du Merlin bringen ?\n");
1256 return 1;
1257 }
1258 ob = find_living(dest);
1259 if (ob) {
1260 ob = environment(ob);
1261 move(object_name(ob),0);
1262 return 1;
1263 }
Zesstra5cd26092018-11-08 22:21:21 +01001264 path=(mixed)master()->make_path_absolute(dest);
MG Mud User88f12472016-06-24 23:31:02 +02001265 ret=catch(load_object(path);publish);
1266 if (ret && file_size(path)<0)
1267 {
1268 dest=match_living(dest,1);
1269 if (stringp(dest))
1270 {
1271 ob = environment(find_living(dest));
1272 move(object_name(ob),M_TPORT|M_NOCHECK);
1273 return 1;
1274 }
1275 printf("Fehler beim Teleport nach %O: No such file.\n",path);
1276 return 1;
1277 }
1278 if (ret)
1279 printf("Fehler beim Teleport nach %O: %O\n",dest,ret);
1280 ret=catch(move(path,M_TPORT|M_NOCHECK);publish);
1281 if (stringp(ret))
1282 ret=implode(old_explode(ret,"\n"),"");
1283 if (ret)
1284 printf("Fehler beim Teleport nach %O: %O\n",dest,ret);
1285 return 1;
1286}
1287
1288mixed locate_objects(string complex_desc)
1289{
1290 object ob;
1291
1292 if (complex_desc=="alles" || complex_desc=="alle")
1293 return filter_objects(all_inventory(this_object()),"short");
1294 if (ob = present(complex_desc,this_object()) )
1295 return ({ ob });
1296 return ({}) ;
1297}
1298
1299void MBanishInsert(string name, string grund, object wer)
1300{
1301 if ( !name || !stringp(name) || !sizeof(name) ||
1302 !grund || !stringp(grund) || !sizeof(grund) ||
1303 !wer || !objectp(wer) || getuid(wer) != secure_euid() ||
1304 !IS_DEPUTY(wer) )
1305 return;
1306
1307 MBanishListe += ([name:grund;getuid(wer)]);
1308 save_object(SAVEFILE);
1309}
1310
1311mapping MBanishList()
1312{
1313 if ( !IS_DEPUTY(secure_euid()) )
1314 return 0;
1315
1316 return deep_copy(MBanishListe);
1317}
1318
1319void MBanishDelete(string name)
1320{
1321 if ( !name || !stringp(name) || !sizeof(name) || !ARCH_SECURITY )
1322 return 0;
1323
1324 MBanishListe = m_copy_delete( MBanishListe, name );
1325 save_object(SAVEFILE);
1326}
1327
1328string _query_noget()
1329{
1330 return "Merlin mag das nicht!\n";
1331}
1332