blob: 53b90c460011f39f8a605416d9b6fd5e804e75df [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.
Arathornd5c9c022020-01-08 22:04:28 +010017inherit "/std/npc/comm.c";
MG Mud User88f12472016-06-24 23:31:02 +020018
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
Zesstra31ae1582019-07-30 20:09:01 +0200336 // verzoegern, bis der Spieler wirklich fertig und in /d/ angekommen ist,
337 // weil dann der initiale Scroll abgeklungen ist und der Spieler die
338 // Willkommensmeldungen von Merlin und Spielern hoffentlich auch wahrnimmt.
339 if (!environment(pl)
340 || strstr(object_name(environment(pl)), "/"DOMAINDIR"/") != 0)
341 {
342 call_out(#'AnnounceNewPlayer,20,pl);
MG Mud User88f12472016-06-24 23:31:02 +0200343 return;
344 }
345
Arathornd5c9c022020-01-08 22:04:28 +0100346 if (!pl->QueryGuest()) {
347 string plname = ({string})pl->Name(WER);
MG Mud User88f12472016-06-24 23:31:02 +0200348 CHMASTER->send("Anfaenger", this_object(),
349 sprintf("%s macht nun ebenfalls das Morgengrauen unsicher. "
350 "Herzlich Willkommen %s!", plname, plname)
351 );
352 }
353}
354
355// Kann bei reboot wieder raus... zesstra, 16.03.2007
356#if __BOOT_TIME__ < 1318110723
357#define BUGTIME 1318003200
358#define BUGFIXTIME 1318109421
359void renew_player(string plname, int force) {
360 object pl;
361 mixed err;
362
363 pl = find_player(plname);
364 if (!objectp(pl) || !query_once_interactive(pl)) return;
365
366 // jung oder alt genug, Abbruch. ;-)
367 if ((object_time(pl) > BUGFIXTIME)
368 || object_time(pl) < BUGTIME)
369 return;
370
371 if (get_eval_cost() < 1000000 || !force ) {
372 call_out("renew_player",8,plname,1);
373 tell_object(pl,break_string(sprintf("Huhu %s, um einen Bug in "
374 "Deinem Spielerobjekt zu beheben, wirst Du in ca. 8s "
375 "neugeladen. Bitte warte bis dahin ab und bleibe, wo "
376 "Du gerade bist.",pl->Name()),78,"Merlin teilt Dir mit: "));
377 return;
378 }
379
380 plname=getuid(pl);
381 tell_object(pl,break_string(sprintf("Huhu %s, um einen Bug in "
382 "Deinem Spielerobjekt zu beheben, wirst Du jetzt "
383 "neugeladen.",pl->Name()),78,"Merlin teilt Dir mit: "));
384
385 if (err=catch(master()->renew_player_object(pl);publish)) {
386 log_file("zesstra/failed_rewew.log",sprintf("%s: Fehler %O beim "
387 "Renew von %s\n",dtime(time()),err,plname));
388 tell_object(pl,break_string("Beim Neuladen Deines Spielerobjekts "
389 "gab es einen Fehler. Bitte wende Dich an einen EM.",78,
390 "Merlin teilt Dir mit: "));
391 }
392 else {
393 log_file("zesstra/renewed.log",sprintf("%s: %s wurde renewed.\n",
394 dtime(time()),plname));
395 if (objectp(find_player(plname)))
396 tell_object(find_player(plname),
397 break_string("Dein Spielerobjekt wurde neugeladen. Du "
398 "kannst jetzt normal weiterspielen. Falls Du etwas ungewoehnliches "
399 "bemerkst, melde Dich bitte bei einem Erzmagier. Viel Spass im "
400 "Spiel!",78, "Merlin teilt Dir mit: "));
401 }
402}
403#endif
404
405void player_change(string eid, object trigob, mixed data) {
406
407 if (!trigob || !interactive(trigob))
408 return;
409
410 switch(eid) {
411 case EVT_LIB_PLAYER_CREATION:
412 call_out(#'AnnounceNewPlayer, 5, trigob);
413 break;
414 case EVT_LIB_LOGIN:
415 notify_player_change(data[E_PLNAME],1);
416#if __BOOT_TIME__ < 1318110723
417 // Spieler evtl. renewen? Bei reboot raus (08.10.2011)
418 renew_player(data[E_PLNAME],0);
419#endif
420 break;
421 }
422}
423
424
425//besser P_NO_ATTACK als Defend()...
426mixed _query_no_attack() {
427 if (!living(PL) || !objectp(environment(PL)) ) return(1);
428
429 tell_room(environment(), "Merlin schimpft: Lass das!!!\n",({PL}));
430 tell_room(environment(),sprintf(
431 "Merlin gibt %s eine schallende Ohrfeige.\n",
Arathornd5c9c022020-01-08 22:04:28 +0100432 capitalize(({string})this_player()->name(WEM))), ({this_player()}));
MG Mud User88f12472016-06-24 23:31:02 +0200433 return("Merlin schimpft: Lass das!!!\n"
434 "Merlin gibt Dir eine schallende Ohrfeige.\n");
435}
436
437/*
438int Defend(int dam, string dam_type, int spell, object enemy)
439{
440 object en;
441 if (!en=previous_object() || !living(en))
442 en = this_player();
443 tell_room(environment(), "Merlin schimpft: Lass das!!!\n");
444 write("Merlin gibt Dir eine schallende Ohrfeige.\n");
445 say(sprintf("Merlin gibt %s eine schallende Ohrfeige.\n",
446 capitalize((string)this_player()->name(WEM))), this_player());
447 en->StopHuntFor(this_object(), 1);
448}
449*/
450void shoutansw()
451{
452 object env,ti;
453 string *path;
454 string ans;
455
456 if (!(env=environment()))
457 return;
Arathornd5c9c022020-01-08 22:04:28 +0100458 if (!(ti=this_interactive())||ti->QueryProp(P_LEVEL)<19||ti->QueryProp(P_GHOST))
MG Mud User88f12472016-06-24 23:31:02 +0200459 return;
460 tell_object(ti,"Du spuerst einen sengenden Schmerz.\n");
Arathornd5c9c022020-01-08 22:04:28 +0100461 ti->do_damage( ti->QueryProp(P_HP) / 2 + 5);
462 if(ti->QueryProp(P_GHOST)) return;
MG Mud User88f12472016-06-24 23:31:02 +0200463 ans="ich hab nicht die leiseste Idee, wo ich hier bin ...\n";
464 path=old_explode(object_name(env),"/");
465 if (path[0]=="d")
466 {
467 ans="werweisswo ..";
468 switch(path[1])
469 {
470 case "gebirge":
471 case "wald":
472 case "dschungel":
473 ans="im "+capitalize(path[1]);
474 break;
475 case "inseln":
476 ans="auf den Inseln";
477 break;
478 case "polar":
479 ans="im Polargebiet";
480 break;
481 case "unterwelt":
482 case "ebene":
483 case "wueste":
484 ans="in der "+capitalize(path[1]);
485 break;
486 case "vland":
487 ans="im Verlorenen Land";
488 break;
489 case "fernwest":
490 ans="in Fernwest";
491 break;
492 }
493 ans="ich bin "+ans+".\n";
494 }
495 if (path[0]=="players")
496 ans="ich hab mich verlaufen - ich schaetze, "+capitalize(path[1])+
497 " hat was damit zu tun...\n";
498 if (path[0]=="gilden") {
499 switch(path[1]) {
500 case "abenteurer":
501 ans="der Abenteurergilde";
502 break;
503 case "bierschuettler":
504 ans="der Bierschuettlergilde";
505 break;
506 case "chaos":
507 ans="der Gilde der Chaoten";
508 break;
509 case "kaempfer":
510 ans="der Kaempfergilde";
511 break;
512 case "karate":
513 ans="einem Karatedojo";
514 break;
515 case "klerus":
516 ans="einem Tempel der Kleriker";
517 break;
518 case "zauberer":
519 ans="der Akademie der Zauberer";
520 break;
521 default:
522 ans="irgendeiner Gilde";
523 }
524 ans="ich stehe in "+ans+".\n";
525 }
526 if( path[0]=="p" && path[1]=="verein" ) {
527 ans="ich stehe in Port Vain.";
528 }
529 if (!this_interactive()->QueryProp(P_INVIS))
530 ans=this_interactive()->Name(WER)+", "+ans;
531 else ans=capitalize(ans);
532 call_out("myshout",0,break_string(ans, 78, "Merlin ruft: "));
533}
534
535void myshout(string s)
536{
537 write(s);
538 shout(s);
539}
540
541void catch_tell(string str)
542{
543 string name, dummy; mixed message;
544 int i,s;
545
546 if (!this_player())
547 return;
548
549 if (environment()==environment(this_player()) && previous_object()!=ME)
550 tell_room(this_object(),"*"+str);
551
552 if (this_player() != this_interactive())
553 return;
554
555 if (busy) {
556 tell_object(this_player(),
557 "Merlin teilt Dir mit: Ich bin beschaeftigt.\n");
558 return;
559 }
560
561 str=lower_case(str);
562
563 if ((strstr(str, "teilt dir mit:") != -1)
564 && (strstr(str, "wo bist du") !=-1)) {
565 shoutansw();
566 return;
567 }
568
569 if ((strstr(str, "teilt dir mit:") != -1) &&
570 ((strstr(str, "seher") != -1 || strstr(str, "seherin") != -1)))
571 {
572 create_seer(this_player());
573 return;
574 }
575
576 if (sscanf(str,"%s %s sagt: %s",dummy,name,message)!=3)
577 if (sscanf(str,"%s sagt: %s",name,message)!=2)
578 return;
579
Zesstraf5a8bf32017-01-30 23:06:00 +0100580 if (!name || !sizeof(name) || !master()->find_userinfo(name))
MG Mud User88f12472016-06-24 23:31:02 +0200581 return;
582
583 if (name!=getuid(this_interactive()) && !ARCH_SECURITY)
584 {
585 if (flag==getuid(this_interactive())+"##"+name)
586 return;
587 call_out("do_say",0,"Merlin sagt: "+capitalize(getuid(this_interactive()))+" hat gerade so getan, als wuerde "+capitalize(name)+" etwas sagen!\n");
588 flag=getuid(this_interactive())+"##"+name;
589 call_out("clear_flag",0);
590 return;
591 }
592 flag=0;
593 for (i=0;i<sizeof(whitespaces);i++)
594 {
595 message=old_explode(message,whitespaces[i]);
596 if (!pointerp(message)||sizeof(message)==0)
597 return;
598 message=implode(message," ");
599 }
600
601 message=old_explode(message," ");
602
603 if (!pointerp(message) || !sizeof(message))
604 return;
605
606 message-=({0})-({""});
607
608 if (!message || sizeof(message)==0)
609 return;
610
611 if (member(message, "merlin")==-1)
612 return;
613
614 message-=({"merlin"});
615
616 message=implode(message," ");
617
618 if (!message || message=="")
619 return;
620
621 determine_action(message, name);
622}
623
624static int determine_action(string mess, string name)
625{
626 string str;
627
628 if (mess=="mach mich zum magier" || mess=="mach mich zur magierin")
629 return create_wizard(name,name);
630
631 if (sscanf(mess,"mach %s zum magier",str)==1||sscanf(mess,"mach %s zur magierin",str)==1)
632 return create_wizard(lower_case(str),name);
633
634 give_help(name);
635 return 0;
636}
637
638#define Say(str) say(str,who)
639#define Write(str) tell_object(who,str)
640
641int QueryBedingungen(object pl,string was)
642{
643 int ret,i,gen;
644 string s;
645
646 if (IS_SEER(pl))
647 return 1;
648
Arathornd5c9c022020-01-08 22:04:28 +0100649 if (LEPMASTER->QueryReadyForWiz(pl)==1)
MG Mud User88f12472016-06-24 23:31:02 +0200650 return 1;
651
Arathornd5c9c022020-01-08 22:04:28 +0100652 s=({string})LEPMASTER->QueryReadyForWizText(pl);
MG Mud User88f12472016-06-24 23:31:02 +0200653
654 tell_object(pl, break_string("Merlin gruebelt ein wenig und teilt Dir "
655 "nach einigem Ueberlegen mit:\n\n", 78,0,1));
656
657 tell_object(pl, s+"\n");
658
659 tell_object(pl, break_string("Da ist wohl fuer Dich noch etwas zu tun...",
660 78, "Merlin teilt Dir mit: "));
661
662 if (environment() == environment(pl))
Arathornd5c9c022020-01-08 22:04:28 +0100663 say(pl->name(WER)
664 +" erfuellt noch nicht alle Anforderungen fuer den "+was+
665 "status.\n",pl);
MG Mud User88f12472016-06-24 23:31:02 +0200666
667 return 0;
668}
669
670static int create_wizard(mixed who, mixed promoter)
671{
672 mixed *domains;
673 object vertrag;
674 int ret;
675 string gen;
676
677 who=find_player(who);
678 promoter=find_player(promoter);
679 if (!who || !promoter)
680 return 0;
681 //
682 // player not interactive?
683 //
684 if (!interactive(who))
685 {
686 write(capitalize(getuid(who))+" ist nicht aktiv.\n");
687 return 0;
688 }
689 //
690 // player is second?
691 //
692 if (who->QueryProp(P_SECOND))
693 {
694 tell_object(who,"Du bist ein Zweitspieler und kannst als solcher kein Magier werden.\n"
695 +"Versuchs Doch mal mit Deinem Erstie.\n");
696 write("Du kannst "+who->name()+" nicht zum Magier machen. Das geht bei "
697 +"Zweities\nleider nicht. Frag doch mal nach dem Erstie.\n");
698 return 1;
699 }
700 //
701 // wants to advance himself?
702 //
703 if (who==promoter)
704 {
705 write("Du kannst Dich nicht selber befoerdern. Such Dir dazu bitte einen "+
706 "Vollmagier,\nder Dir einen Vertrag gibt.\n");
707 return 1;
708 }
709 //
710 // banished?
711 //
712 if (MBanishListe[who,1])
713 {
714 tell_object(promoter,capitalize(who)+" darf nur von einem Erzmagier zum "+
715 "Magier gemacht werden.\n");
716 say(promoter->name(WER)+" ist kein Erzmagier und darf "+capitalize(who)+
717 " nicht zum Magier machen.\n");
718 return 1;
719 }
720 //
721 // player has PK?
722 //
723 if (who->QueryProp("playerkills")) {
724 tell_room(environment(who),who->name()+" hat noch einen Playerkill und kann somit kein Magier werden.\n"
725 "Am besten den Sheriff oder einen Erzmagier verstaendigen.\n");
726 return 1;
727 }
728 //
729 // already dom_member?
730 //
731 if (IS_DOMAINMEMBER(who))
732 {
733 Write("Fuer Dich kann ich nichts mehr tun. Du bist doch schon Magier!\n");
734 return 1;
735 }
736
737 //
738 // "advanced learner"?
739 //
740 if (query_wiz_level(who) == 20)
741 {
742 if (!ARCH_SECURITY) {
743 Write("Dich kann nur ein Erzmagier zum \"richtigen\" Magier machen!\n");
744 Say("Nur ein Erzmagier kann "+who->name(WEN)+" zum \"richtigen\" Magier machen!\n");
745 return 0;
746 }
Arathornd5c9c022020-01-08 22:04:28 +0100747 ret=({int})"secure/master"->advance_wizlevel(geteuid(who),21);
MG Mud User88f12472016-06-24 23:31:02 +0200748 if (ret<=0)
749 {
750 say("Merlin: error "+ret+"\n");
751 write("Merlin: error "+ret+"\n");
752 }
Arathornd5c9c022020-01-08 22:04:28 +0100753 write("Merlin ruft: "+who->name(WER)+" ist in den Kreis der Magier "+
MG Mud User88f12472016-06-24 23:31:02 +0200754 "aufgenommen worden!\n");
Arathornd5c9c022020-01-08 22:04:28 +0100755 shout("Merlin ruft: "+who->name(WER)+" ist in den Kreis der Magier "+
MG Mud User88f12472016-06-24 23:31:02 +0200756 "aufgenommen worden!\n");
757 "secure/master"->renew_player_object(who);
758 return 1;
759 }
760
761 //
762 // already wizard?
763 //
764 if (IS_WIZARD(who))
765 {
Arathornd5c9c022020-01-08 22:04:28 +0100766 domains=({string*})"secure/master"->get_domain_homes(getuid(who));
MG Mud User88f12472016-06-24 23:31:02 +0200767 if (!domains || !pointerp(domains) || !sizeof(domains))
768 {
769 Say(who->name(WER)+" gehoert noch keiner Region an und kann daher noch "+
770 "kein Voll-\nmagier werden.\n");
771 Write("Du gehoerst noch keiner Region an. Schliess Dich zunaechst einer "+
772 "an und komm\ndann wieder!\n");
773 return 0;
774 }
Arathornd5c9c022020-01-08 22:04:28 +0100775 ret=({int})"secure/master"->advance_wizlevel(geteuid(who),25);
MG Mud User88f12472016-06-24 23:31:02 +0200776 if(ret>0)
777 {
778 shout(who->name(WER)+" arbeitet jetzt an einer Region mit!\n");
779 "secure/master"->renew_player_object(who);
780 return 1;
781 }
782 write("RETURNVALUE "+ret+"\n");
783 say("RETURNVALUE "+ret+"\n");
784 return 0;
785 }
786
787 //
788 // still learner?
789 //
790 if (IS_LEARNER(who))
791 {
792 if (!ARCH_SECURITY) {
793 Write("Dich kann nur ein Erzmagier zum \"richtigen\" Magier machen!\n");
794 Say("Nur ein Erzmagier kann "+who->name(WEN)+" zum \"richtigen\" Magier machen!\n");
795 return 0;
796 }
Arathornd5c9c022020-01-08 22:04:28 +0100797 ret=({int})"secure/master"->advance_wizlevel(geteuid(who),20);
MG Mud User88f12472016-06-24 23:31:02 +0200798 if (ret<=0)
799 {
800 say("Merlin: error "+ret+"\n");
801 write("Merlin: error "+ret+"\n");
802 }
Arathornd5c9c022020-01-08 22:04:28 +0100803 string wizname = ({string})who->query_real_name();
MG Mud User88f12472016-06-24 23:31:02 +0200804 "secure/master"->renew_player_object(who);
805 // Fehlerteufel geben
806 call_out(#'GibFehlerteufel,4,find_player(wizname));
807 return 1;
808 }
809
810 //
811 // promoter's level is not >DOMAINMEMBER_LVL+1
812 //
813 if (secure_level()<=DOMAINMEMBER_LVL)
814 {
815 tell_object(promoter,"Du musst derzeit mindestens Level "+
816 (DOMAINMEMBER_LVL+1)+" haben, um jemanden befoerden zu "+
817 "koennen.\n");
818 say(promoter->name(WER)+" ist kein Vollmagier und darf daher niemanden "+
819 "zum Vollmagier machen.\n");
820 return 1;
821 }
822
823 // der Check auf den Blutprintnamen ist fast ueberfluessig, aber nur fast.
824 // Er schlaegt fehl, wenn der Vertrag der Clone einer alten BP ist.
825 if (!(vertrag=present_clone("/obj/vertrag",who)) ||
826 object_name(blueprint(vertrag))!="/obj/vertrag" ||
Arathornd5c9c022020-01-08 22:04:28 +0100827 !(vertrag->is_unterschrieben()) )
MG Mud User88f12472016-06-24 23:31:02 +0200828 {
829 Write("Du hast ja gar keinen unterschriebenen Vertrag bei Dir. Besorg Dir "+
830 "einen Ver-\ntrag, unterschreibe ihn und komm dann wieder!\n");
831 Say(who->name(WER)+" hat keinen unterschriebenen Vertrag.\n");
832 return 1;
833 }
834 if (geteuid(vertrag)!=secure_euid())
835 {
836 tell_object(promoter,"Das geht nicht, er hat einen Vertrag von "+
837 capitalize(geteuid(vertrag))+" bei sich.\n");
838 say(promoter->name(WER)+" versucht, "+who->name(WER)+" zum Magier zu "+
839 "machen, doch "+who->name(WER)+" hat einen Vertrag\nvon "+
840 capitalize(geteuid(vertrag))+" bei sich.\n",promoter);
841 return 0;
842 }
843 if (!QueryBedingungen(who,"Magier"))
844 return 0;
Arathornd5c9c022020-01-08 22:04:28 +0100845 ret=({int})"secure/master"->advance_wizlevel(geteuid(who),15);
MG Mud User88f12472016-06-24 23:31:02 +0200846 if (ret>0)
847 {
848 PostMagier(capitalize(getuid(who)),
Arathornd5c9c022020-01-08 22:04:28 +0100849 capitalize(secure_euid()),
850 who->QueryProp(P_GENDER));
MG Mud User88f12472016-06-24 23:31:02 +0200851 write_file("/log/SPONSOR",dtime(time())+": "+capitalize(getuid(promoter))+" macht "+
852 who->name(WER)+" zum Learner.\n");
853 write(who->name(WER)+" ist in den Kreis der Magier aufgenommen worden!\n");
854 shout(who->name(WER)+" ist in den Kreis der Magier aufgenommen worden!\n");
855 if ("secure/master"->set_player_object(geteuid(who),"/std/shells/magier")
856 <=0)
857 {
858 say("MERLIN: konnte Magiershell nicht einstellen.\n");
859 write("MERLIN: konnte Magiershell nicht einstellen.\n");
860 }
861 "secure/master"->renew_player_object(who);
862 return 1;
863 }
864 write(" --RETURNVALUE IS "+ret+"\n");
865 say(" --RETURNVALUE IS "+ret+"\n");
866
867 return(ret); //non-void funktion
868}
869
870void clear_flag()
871{
872 flag=0;
873}
874
875void do_say(string str)
876{
877 say(str);
878}
879
880
881
Zesstrab16348b2019-05-21 19:41:36 +0200882void seer_sequenz3(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200883{
884 string playername;
885 object faq;
886 string text;
887
Zesstra60d9e252019-05-21 20:02:56 +0200888 if (!objectp(player) || !interactive(player)) {
MG Mud User88f12472016-06-24 23:31:02 +0200889 tell_room(environment(), sprintf("Merlin sagt: Na, wo ist denn %s "
890 "hin?\n", plname));
891 busy = 0;
892 return;
893 }
894 if (environment() != environment(player))
895 move(environment(player), M_TPORT);
896
897 tell_object(player,break_string("\n\nEs macht *PUFF* und eine Schwefelwolke "
898 +"steigt um Dich herum auf.\n\nDie Aura "
899 +"verschwindet langsam und Du fuehlst Dich "
900 +"nun viel erfahrener.", 78,0,1));
901 tell_room(environment(),
902 break_string(sprintf(
903 "\n\nEs macht *PUFF* und eine Schwefelwolke steigt "
904 +"um %s herum auf.\n\nDie Aura verschwindet langsam.\n",
905 plname),78,0,1), ({player}));
906
907 if ("secure/master"->advance_wizlevel(geteuid(player),1)<=0)
908 {
909 write("Merlin sagt: Da geht was schief ... sag mal Zook Bescheid.\n");
910 say("Merlin sagt: Da geht was schief ... sag mal Zook Bescheid.\n");
911 busy = 0;
912 return;
913 }
914 playername = geteuid(player);
915 "secure/master"->renew_player_object(player);
916 player = find_player(playername);
917 text = sprintf(" ist jetzt ein%s Seher%s!\n",
Arathornd5c9c022020-01-08 22:04:28 +0100918 ((player->QueryProp(P_GENDER))==2?"e":""),
919 ((player->QueryProp(P_GENDER))==2?"in":""));
MG Mud User88f12472016-06-24 23:31:02 +0200920 write("Merlin ruft: "+capitalize(playername)+text);
921 shout("Merlin ruft: "+capitalize(playername)+text);
922 PostSeher(capitalize(playername),(int)player->QueryProp(P_GENDER));
923 if(!catch(
924 faq=clone_object("/d/seher/haeuser/special/seherfaqmobil") ;publish))
925 {
926 faq->move(player,M_NOCHECK);
927 tell_object(player, "Aus dem Nichts erscheint eine kleine Belohnung fuer Dich.\n");
928 }
929
930 tell_object(player, "\n\nDu laechelst gluecklich in die Runde.\n\n");
931 tell_room(environment(), sprintf("\n\n%s laechelt gluecklich in die Runde.\n\n", plname), ({player}));
932
933 busy=0;
934}
935
Zesstrab16348b2019-05-21 19:41:36 +0200936void seer_sequenz2(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200937{
Zesstra60d9e252019-05-21 20:02:56 +0200938 if (!objectp(player) || !interactive(player)) {
MG Mud User88f12472016-06-24 23:31:02 +0200939 tell_room(environment(), sprintf(
940 "Merlin sagt: Na, wo ist denn %s hin?\n",
941 plname));
942 busy = 0;
943 return;
944 }
945 if (environment() != environment(player))
946 move(environment(player), M_TPORT);
947
zesstra70a0a3e2016-07-06 20:35:40 +0200948 tell_object(player, break_string("\nMerlin hebt die Arme "
MG Mud User88f12472016-06-24 23:31:02 +0200949 +"und macht einige beschwoerende Gesten. Um Dich herum erscheint "
950 +"eine gelbliche Aura, die immer heller wird, bis Du Deine "
951 +"Umwelt kaum mehr erkennen kannst.\n\n",
952 78,0,1));
953 tell_room(environment(),
954 break_string(sprintf("\nMerlin hebt die Arme und macht einige "
955 +"beschwoerende Gesten. Um %s erscheint eine "
956 +"gelbliche Aura, die immer heller wird, bis "
957 +"man %s kaum mehr erkennen kann.\n\n",
958 plname, plname),78,0,1), ({player}));
959
960 call_out("seer_sequenz3", 7, player, plname);
961}
962
Zesstrab16348b2019-05-21 19:41:36 +0200963void seer_sequenz1(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200964{
Zesstra60d9e252019-05-21 20:02:56 +0200965 if (!objectp(player) || !interactive(player))
MG Mud User88f12472016-06-24 23:31:02 +0200966 return;
967
968 move(environment(player), M_TPORT);
969
970 tell_room(environment(),
971 break_string(sprintf("Das ist eine grosse Freude. %s hat sich "
972 "tapfer durch das "MUDNAME" geschlagen und mittlerweile alle "
973 "Anforderungen erfuellt, um %s zu werden.",
Arathornd5c9c022020-01-08 22:04:28 +0100974 plname, (player->QueryProp(P_GENDER))==1?"Seher":"Seherin"),
MG Mud User88f12472016-06-24 23:31:02 +0200975 78, "Merlin sagt: "));
976
977 call_out("seer_sequenz2", 4, player, plname);
978}
979
980
Zesstrab16348b2019-05-21 19:41:36 +0200981static int create_seer(object player)
MG Mud User88f12472016-06-24 23:31:02 +0200982{
Zesstra60d9e252019-05-21 20:02:56 +0200983 if (!objectp(player) || !interactive(player))
MG Mud User88f12472016-06-24 23:31:02 +0200984 return 0;
985 if (IS_SEER(player))
986 {
987 write(break_string("Du bist doch schon kein normaler Spieler mehr, "
988 +"was soll es also?", 78, "Merlin teilt Dir mit: "));
989 return 1;
990 }
991
992 if (!QueryBedingungen(player,"Seher"))
993 return -1;
994
995
996 write(break_string("Grosse Freude! Du hast alle Anforderungen "
997 "erfuellt. Warte einen Moment...", 78,
998 "Merlin teilt Dir mit: "));
999 busy=1;
1000 call_out("seer_sequenz1",4,player, player->Name());
1001 return(0); //non-void funktion
1002}
1003
1004static void give_help(mixed player)
1005{
1006 if (!objectp(player))
1007 return;
1008
1009 tell_object(player,
1010 break_string("Ich weiss nicht, was ich fuer Dich tun kann. "
1011 +"Ich kann Dich zum Seher oder zum Magier "
1012 +"machen, wenn Du mich darum bittest.", 78,
1013 "Merlin teilt Dir mit: "));
1014}
1015
1016
1017void reset()
1018{
1019}
1020
1021public int remove(int silent) {
1022 EVENTD->UnregisterEvent(EVT_LIB_LOGIN, ME);
1023 EVENTD->UnregisterEvent(EVT_LIB_PLAYER_CREATION, ME);
1024 destruct(this_object());
1025 return 1;
1026}
1027
1028void wandern()
1029{
MG Mud User88f12472016-06-24 23:31:02 +02001030 while (remove_call_out("wandern")>=0);
1031 call_out("wandern",45+random(100));
1032 if (busy) return;
1033 if (delay)
1034 {
1035 delay=0;
1036 return;
1037 }
Zesstra1b6b7362019-04-25 14:08:02 +02001038 if (!environment())
MG Mud User88f12472016-06-24 23:31:02 +02001039 {
1040 move("/gilden/abenteurer",0);
MG Mud User88f12472016-06-24 23:31:02 +02001041 }
1042 //ueber Inv iterieren, ob da ein nicht-idelnder Spieler mit genug XP
Zesstra1b6b7362019-04-25 14:08:02 +02001043 //rumhaengt. In diesem Raum bleiben, wenn ja.
1044 foreach(object ob: all_inventory(environment()))
1045 {
1046 if (interactive(ob) && query_idle(ob)<180
1047 && ob->QueryProp(P_XP)>999999)
MG Mud User88f12472016-06-24 23:31:02 +02001048 return;
1049 }
Zesstra1b6b7362019-04-25 14:08:02 +02001050 // Ausgaenge durchsuchen
Arathornd5c9c022020-01-08 22:04:28 +01001051 mapping ex=({mapping})environment()->QueryProp(P_EXITS);
MG Mud User88f12472016-06-24 23:31:02 +02001052 if (!mappingp(ex))
1053 return;
Zesstra1b6b7362019-04-25 14:08:02 +02001054 mapping rooms = m_allocate(sizeof(ex));
1055 foreach(string cmd, string|closure dest, string msg : ex)
MG Mud User88f12472016-06-24 23:31:02 +02001056 {
Zesstra1b6b7362019-04-25 14:08:02 +02001057 object ob;
1058 // nur normale Ausgaenge benutzen
1059 if (!stringp(dest)
1060 || dest = object_name(environment()))
MG Mud User88f12472016-06-24 23:31:02 +02001061 continue;
Zesstra1b6b7362019-04-25 14:08:02 +02001062 rooms += ([dest]);
MG Mud User88f12472016-06-24 23:31:02 +02001063 }
Zesstra1b6b7362019-04-25 14:08:02 +02001064 if (!sizeof(rooms))
1065 return;
1066
1067 // Und nicht zuruecklatschen, wenn moeglich.
MG Mud User88f12472016-06-24 23:31:02 +02001068 if (prev_room && sizeof(m_indices(rooms))>1)
1069 rooms-=([prev_room]);
Zesstra1b6b7362019-04-25 14:08:02 +02001070 prev_room=object_name(environment());
1071
1072 string *raeume=m_indices(rooms);
1073 move(raeume[sizeof(raeume)],0);
MG Mud User88f12472016-06-24 23:31:02 +02001074}
1075
1076string int_short()
1077{
1078 return "Du bist im allseits beliebten Wizclub \"Zum lustigen Merlin\".\n";
1079}
1080
1081string int_long(object who,mixed where)
1082{
1083 string descr;
1084
1085 if( IS_LEARNER(who) && who->QueryProp( P_WANTS_TO_LEARN ) )
1086 descr = "[" + object_name(ME) + "]\n";
1087 else
1088 descr = "";
1089 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";
1090 if ( who->QueryProp(P_SHOW_EXITS) )
1091 descr += "Es gibt 2 sichtbare Ausgaenge: raus und gilde.\n";
1092 descr += make_invlist(who, all_inventory(ME) - ({ who }));
1093 if( environment())
1094 descr += "\nAusserhalb siehst Du:\n"
1095 + environment()->int_short(who,ME);
1096 return descr;
1097}
1098
1099string make_invlist(object viewer,object *inv)
1100{
1101 int i, iswiz;
1102 string descr;
1103
1104 descr = "";
1105 iswiz = IS_LEARNER( viewer ) && viewer->QueryProp(P_WANTS_TO_LEARN);
1106
1107 for (i = 0; i < sizeof(inv); i++)
1108 {
1109 string sh;
Arathornd5c9c022020-01-08 22:04:28 +01001110 sh = ({string})inv[i]->short();
MG Mud User88f12472016-06-24 23:31:02 +02001111 if (iswiz)
1112 {
1113 if (sh) sh = sh[0..<2] + " ["+object_name(inv[i])+"]\n";
1114 else sh = "["+object_name(inv[i])+"]\n";
1115 }
1116 if (sh) descr += sh;
1117 }
1118 return descr;
1119}
1120
1121void init()
1122{
1123 if (interactive(this_player()) && environment(this_player())==ME)
1124 add_action("gehen","",1);
1125 add_action("befoerdere","befoerder",1);
1126}
1127
1128int befoerdere(string str)
1129{
1130 string wen;
1131 int ret,stufe,l;
1132
1133 if (!LORD_SECURITY) return 0;
1134 if (!str||sscanf(str,"%s auf stufe %d",wen,stufe)<2)
1135 {
1136 notify_fail("Syntax: befoerdere <name> auf stufe <stufe>\n");
1137 return 0;
1138 }
1139 if (stufe>29)
1140 {
1141 write("Maximum ist Stufe 29!\n");
1142 return 1;
1143 }
1144 l=query_wiz_level(wen);
1145 if (l<25)
1146 {
1147 printf("%s muss mindestens zwecks Weiterbefoerderung mindestens Stufe 25 haben.\n",
1148 capitalize(wen));
1149 return 1;
1150 }
1151 if (l>=stufe)
1152 {
1153 printf("%s ist schon Stufe %d.\n",capitalize(wen),l);
1154 return 1;
1155 }
Arathornd5c9c022020-01-08 22:04:28 +01001156 ret=({int})"secure/master"->advance_wizlevel(wen,stufe);
MG Mud User88f12472016-06-24 23:31:02 +02001157 if (ret<=0)
1158 printf("Errorcode %d\n",ret);
1159 else
1160 write("ok\n");
1161 return 1;
1162}
1163
1164int sag(mixed str)
1165{
1166 int i;
1167
1168 if (str==0)
1169 str="";
1170 str = old_explode(break_string(str, 60 ), "\n");
1171 if (busy) {
1172 tell_room(ME, "Merlin mault: Ich bin beschaeftigt.\n");
1173 return 0;
1174 }
1175 for (i = 0; i < sizeof(str); i++)
1176 {
1177 if (!str[i])
1178 str[i]="";
1179 tell_room(environment(),"Merlin sagt: "+str[i]+"\n");
1180 tell_room(ME,"*Merlin sagt: "+str[i]+"\n");
1181 }
1182 return 1;
1183}
1184
1185void show_exits()
1186{
1187 printf("%s",environment()->GetExits());
1188}
1189
1190int gehen(string str)
1191{
MG Mud User88f12472016-06-24 23:31:02 +02001192 if (busy) {
1193 write("Merlin mault: Ich bin beschaeftigt.\n");
1194 return 0;
1195 }
1196
Arathornd5c9c022020-01-08 22:04:28 +01001197 str=({string})this_interactive()->_unparsed_args();
Zesstra1b6b7362019-04-25 14:08:02 +02001198 switch (query_verb())
MG Mud User88f12472016-06-24 23:31:02 +02001199 {
1200 case "gilde":
1201 this_player()->move("/gilden/abenteurer",M_GO,"in die Gilde");
1202 return 1;
1203 case "raus":
1204 this_player()->move(environment(),M_GO,"raus");
1205 return 1;
1206 }
1207 if (!IS_WIZARD(this_interactive()))
1208 return 0;
Zesstra1b6b7362019-04-25 14:08:02 +02001209 if (query_verb()!="merlin")
MG Mud User88f12472016-06-24 23:31:02 +02001210 return 0;
1211 delay=1;
Arathornd5c9c022020-01-08 22:04:28 +01001212 mapping exits=({mapping})environment()->QueryProp(P_EXITS);
MG Mud User88f12472016-06-24 23:31:02 +02001213 if (!str||str=="")
1214 {
MG Mud User88f12472016-06-24 23:31:02 +02001215 printf(environment()->int_short(ME,ME));
1216 show_exits();
1217 return 1;
1218 }
1219 if (old_explode(str," ")[0]=="sag")
1220 return sag(implode(old_explode(str," ")[1..]," "));
1221 if (str[0]==';')
1222 {
1223 tell_room(environment(ME),"Merlins "+str[1..]+"\n");
1224 tell_room(ME,"*Merlins "+str[1..]+"\n");
1225 return 1;
1226 }
1227 if (str[0]==':')
1228 {
1229 tell_room(environment(ME),"Merlin "+str[1..]+"\n");
1230 tell_room(ME,"*Merlin "+str[1..]+"\n");
1231 return 1;
1232 }
1233 if (str[0]=='*')
1234 {
1235 goto(str[1..]);
1236 printf(environment()->int_short(ME,ME));
1237 show_exits();
1238 return 1;
1239 }
1240 if (!exits[str])
1241 return 0;
1242 move(exits[str],0);
1243 write("Merlin sagt: Jawoll, Chef.\n");
1244 printf(environment()->int_short(ME,ME));
1245 show_exits();
1246 return 1;
1247}
1248
1249int goto(mixed dest)
1250{
1251 object ob;
1252 string path;
1253 mixed ret;
1254
1255 if (busy) {
1256 write("Merlin mault: Ich bin beschaeftigt.\n");
1257 return 1;
1258 }
1259
1260 if (!dest) {
1261 write("Wohin moechtest Du Merlin bringen ?\n");
1262 return 1;
1263 }
1264 ob = find_living(dest);
1265 if (ob) {
1266 ob = environment(ob);
1267 move(object_name(ob),0);
1268 return 1;
1269 }
Arathornd5c9c022020-01-08 22:04:28 +01001270 path = ({string})master()->make_path_absolute(dest);
MG Mud User88f12472016-06-24 23:31:02 +02001271 ret=catch(load_object(path);publish);
1272 if (ret && file_size(path)<0)
1273 {
1274 dest=match_living(dest,1);
1275 if (stringp(dest))
1276 {
1277 ob = environment(find_living(dest));
1278 move(object_name(ob),M_TPORT|M_NOCHECK);
1279 return 1;
1280 }
1281 printf("Fehler beim Teleport nach %O: No such file.\n",path);
1282 return 1;
1283 }
1284 if (ret)
1285 printf("Fehler beim Teleport nach %O: %O\n",dest,ret);
1286 ret=catch(move(path,M_TPORT|M_NOCHECK);publish);
1287 if (stringp(ret))
1288 ret=implode(old_explode(ret,"\n"),"");
1289 if (ret)
1290 printf("Fehler beim Teleport nach %O: %O\n",dest,ret);
1291 return 1;
1292}
1293
1294mixed locate_objects(string complex_desc)
1295{
1296 object ob;
1297
1298 if (complex_desc=="alles" || complex_desc=="alle")
1299 return filter_objects(all_inventory(this_object()),"short");
1300 if (ob = present(complex_desc,this_object()) )
1301 return ({ ob });
1302 return ({}) ;
1303}
1304
1305void MBanishInsert(string name, string grund, object wer)
1306{
1307 if ( !name || !stringp(name) || !sizeof(name) ||
1308 !grund || !stringp(grund) || !sizeof(grund) ||
1309 !wer || !objectp(wer) || getuid(wer) != secure_euid() ||
1310 !IS_DEPUTY(wer) )
1311 return;
1312
1313 MBanishListe += ([name:grund;getuid(wer)]);
1314 save_object(SAVEFILE);
1315}
1316
1317mapping MBanishList()
1318{
1319 if ( !IS_DEPUTY(secure_euid()) )
1320 return 0;
1321
1322 return deep_copy(MBanishListe);
1323}
1324
1325void MBanishDelete(string name)
1326{
1327 if ( !name || !stringp(name) || !sizeof(name) || !ARCH_SECURITY )
1328 return 0;
1329
1330 MBanishListe = m_copy_delete( MBanishListe, name );
1331 save_object(SAVEFILE);
1332}
1333
1334string _query_noget()
1335{
1336 return "Merlin mag das nicht!\n";
1337}
1338