blob: 6f20e1cbf2659dff88ff4c718170864b6582d5c4 [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);
bugfixd94d0932020-04-08 11:27:13 +020076 ({int})EVENTD->RegisterEvent(EVT_LIB_PLAYER_CREATION, "player_change", ME);
77 ({int})EVENTD->RegisterEvent(EVT_LIB_LOGIN, "player_change", ME);
MG Mud User88f12472016-06-24 23:31:02 +020078 // 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;
bugfixd94d0932020-04-08 11:27:13 +0200115 return ({mixed})call_other(this_object(),"_query_"+str);
MG Mud User88f12472016-06-24 23:31:02 +0200116}
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{
bugfixd94d0932020-04-08 11:27:13 +0200147 ({int})EPMASTER->GiveExplorationPoint("merlin");
MG Mud User88f12472016-06-24 23:31:02 +0200148 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;
bugfixd94d0932020-04-08 11:27:13 +0200230 gen2 = ( intp( what ) ) ? what : ({int})what->QueryProp(P_GENDER);
MG Mud User88f12472016-06-24 23:31:02 +0200231 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)});
bugfixd94d0932020-04-08 11:27:13 +0200276 ({int})"/secure/news"->WriteNote(art,1);
MG Mud User88f12472016-06-24 23:31:02 +0200277}
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"))});
bugfixd94d0932020-04-08 11:27:13 +0200285 ({int})"/secure/news"->WriteNote(art,1);
MG Mud User88f12472016-06-24 23:31:02 +0200286}
287
288
289private void GibFehlerteufel(object wiz) {
290 if (!objectp(wiz))
291 return;
292
bugfixd94d0932020-04-08 11:27:13 +0200293 ({int})clone_object(FEHLERTEUFEL)->move(wiz, M_NOCHECK|M_GET);
MG Mud User88f12472016-06-24 23:31:02 +0200294 tell_object(wiz, break_string(
bugfixd94d0932020-04-08 11:27:13 +0200295 "Huhu "+({string})wiz->Name(WER) + "! Ich habe gesehen, dass Du keinen "
MG Mud User88f12472016-06-24 23:31:02 +0200296 "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)
bugfixd94d0932020-04-08 11:27:13 +0200327 && ({int})ob->QueryProp(P_LAST_LOGOUT) < 1237329604 )
MG Mud User88f12472016-06-24 23:31:02 +0200328 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
bugfixd94d0932020-04-08 11:27:13 +0200346 if (!({int})pl->QueryGuest()) {
Arathornd5c9c022020-01-08 22:04:28 +0100347 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 "
bugfixd94d0932020-04-08 11:27:13 +0200376 "Du gerade bist.",({string})pl->Name()),78,"Merlin teilt Dir mit: "));
MG Mud User88f12472016-06-24 23:31:02 +0200377 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 "
bugfixd94d0932020-04-08 11:27:13 +0200383 "neugeladen.",({string})pl->Name()),78,"Merlin teilt Dir mit: "));
MG Mud User88f12472016-06-24 23:31:02 +0200384
bugfixd94d0932020-04-08 11:27:13 +0200385 if (err=catch(({int})master()->renew_player_object(pl);publish)) {
MG Mud User88f12472016-06-24 23:31:02 +0200386 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());
bugfixd94d0932020-04-08 11:27:13 +0200447 ({int})en->StopHuntFor(this_object(), 1);
MG Mud User88f12472016-06-24 23:31:02 +0200448}
449*/
450void shoutansw()
451{
452 object env,ti;
453 string *path;
454 string ans;
455
456 if (!(env=environment()))
457 return;
bugfixd94d0932020-04-08 11:27:13 +0200458 if (!(ti=this_interactive())||({int})ti->QueryProp(P_LEVEL)<19||({int})ti->QueryProp(P_GHOST))
MG Mud User88f12472016-06-24 23:31:02 +0200459 return;
460 tell_object(ti,"Du spuerst einen sengenden Schmerz.\n");
bugfixd94d0932020-04-08 11:27:13 +0200461 ({int})ti->do_damage( ({int})ti->QueryProp(P_HP) / 2 + 5);
462 if(({int})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 }
bugfixd94d0932020-04-08 11:27:13 +0200529 if (!({int})this_interactive()->QueryProp(P_INVIS))
530 ans=({string})this_interactive()->Name(WER)+", "+ans;
MG Mud User88f12472016-06-24 23:31:02 +0200531 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
bugfixd94d0932020-04-08 11:27:13 +0200580 if (!name || !sizeof(name) || !({int})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
bugfixd94d0932020-04-08 11:27:13 +0200649 if (({int})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))
bugfixd94d0932020-04-08 11:27:13 +0200663 say(({string})pl->name(WER)
Arathornd5c9c022020-01-08 22:04:28 +0100664 +" 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 //
bugfixd94d0932020-04-08 11:27:13 +0200692 if (({string})who->QueryProp(P_SECOND))
MG Mud User88f12472016-06-24 23:31:02 +0200693 {
694 tell_object(who,"Du bist ein Zweitspieler und kannst als solcher kein Magier werden.\n"
695 +"Versuchs Doch mal mit Deinem Erstie.\n");
bugfixd94d0932020-04-08 11:27:13 +0200696 write("Du kannst "+({string})who->name()+" nicht zum Magier machen. Das geht bei "
MG Mud User88f12472016-06-24 23:31:02 +0200697 +"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");
bugfixd94d0932020-04-08 11:27:13 +0200716 say(({string})promoter->name(WER)+" ist kein Erzmagier und darf "+capitalize(who)+
MG Mud User88f12472016-06-24 23:31:02 +0200717 " nicht zum Magier machen.\n");
718 return 1;
719 }
720 //
721 // player has PK?
722 //
bugfixd94d0932020-04-08 11:27:13 +0200723 if (({string})who->QueryProp("playerkills")) {
724 tell_room(environment(who),({string})who->name()+" hat noch einen Playerkill und kann somit kein Magier werden.\n"
MG Mud User88f12472016-06-24 23:31:02 +0200725 "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");
bugfixd94d0932020-04-08 11:27:13 +0200744 Say("Nur ein Erzmagier kann "+({string})who->name(WEN)+" zum \"richtigen\" Magier machen!\n");
MG Mud User88f12472016-06-24 23:31:02 +0200745 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 }
bugfixd94d0932020-04-08 11:27:13 +0200753 write("Merlin ruft: "+({string})who->name(WER)+" ist in den Kreis der Magier "+
MG Mud User88f12472016-06-24 23:31:02 +0200754 "aufgenommen worden!\n");
bugfixd94d0932020-04-08 11:27:13 +0200755 shout("Merlin ruft: "+({string})who->name(WER)+" ist in den Kreis der Magier "+
MG Mud User88f12472016-06-24 23:31:02 +0200756 "aufgenommen worden!\n");
bugfixd94d0932020-04-08 11:27:13 +0200757 ({int})"secure/master"->renew_player_object(who);
MG Mud User88f12472016-06-24 23:31:02 +0200758 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 {
bugfixd94d0932020-04-08 11:27:13 +0200769 Say(({string})who->name(WER)+" gehoert noch keiner Region an und kann daher noch "+
MG Mud User88f12472016-06-24 23:31:02 +0200770 "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 {
bugfixd94d0932020-04-08 11:27:13 +0200778 shout(({string})who->name(WER)+" arbeitet jetzt an einer Region mit!\n");
779 ({int})"secure/master"->renew_player_object(who);
MG Mud User88f12472016-06-24 23:31:02 +0200780 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");
bugfixd94d0932020-04-08 11:27:13 +0200794 Say("Nur ein Erzmagier kann "+({string})who->name(WEN)+" zum \"richtigen\" Magier machen!\n");
MG Mud User88f12472016-06-24 23:31:02 +0200795 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();
bugfixd94d0932020-04-08 11:27:13 +0200804 ({int})"secure/master"->renew_player_object(who);
MG Mud User88f12472016-06-24 23:31:02 +0200805 // 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");
bugfixd94d0932020-04-08 11:27:13 +0200818 say(({string})promoter->name(WER)+" ist kein Vollmagier und darf daher niemanden "+
MG Mud User88f12472016-06-24 23:31:02 +0200819 "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" ||
bugfixd94d0932020-04-08 11:27:13 +0200827 !(({int})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");
bugfixd94d0932020-04-08 11:27:13 +0200831 Say(({string})who->name(WER)+" hat keinen unterschriebenen Vertrag.\n");
MG Mud User88f12472016-06-24 23:31:02 +0200832 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");
bugfixd94d0932020-04-08 11:27:13 +0200838 say(({string})promoter->name(WER)+" versucht, "+({string})who->name(WER)+" zum Magier zu "+
839 "machen, doch "+({string})who->name(WER)+" hat einen Vertrag\nvon "+
MG Mud User88f12472016-06-24 23:31:02 +0200840 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 {
Zesstra68ee1e52020-04-20 23:24:15 +0200848 // Log ("Magierstammbuch") nach /data/etc loggen, weil SPONSOR ein
849 // langfristlog.
850 write_data("/etc/SPONSOR",dtime(time())+": "+capitalize(getuid(promoter))+" macht "+
bugfixd94d0932020-04-08 11:27:13 +0200851 ({string})who->name(WER)+" zum Learner.\n");
852 write(({string})who->name(WER)+" ist in den Kreis der Magier aufgenommen worden!\n");
853 shout(({string})who->name(WER)+" ist in den Kreis der Magier aufgenommen worden!\n");
Zesstra68ee1e52020-04-20 23:24:15 +0200854 PostMagier(capitalize(getuid(who)),
855 capitalize(secure_euid()),
856 ({int})who->QueryProp(P_GENDER));
bugfixd94d0932020-04-08 11:27:13 +0200857 if (({int})"secure/master"->set_player_object(geteuid(who),"/std/shells/magier")
MG Mud User88f12472016-06-24 23:31:02 +0200858 <=0)
859 {
860 say("MERLIN: konnte Magiershell nicht einstellen.\n");
861 write("MERLIN: konnte Magiershell nicht einstellen.\n");
862 }
bugfixd94d0932020-04-08 11:27:13 +0200863 ({int})"secure/master"->renew_player_object(who);
MG Mud User88f12472016-06-24 23:31:02 +0200864 return 1;
865 }
866 write(" --RETURNVALUE IS "+ret+"\n");
867 say(" --RETURNVALUE IS "+ret+"\n");
868
869 return(ret); //non-void funktion
870}
871
872void clear_flag()
873{
874 flag=0;
875}
876
877void do_say(string str)
878{
879 say(str);
880}
881
882
883
Zesstrab16348b2019-05-21 19:41:36 +0200884void seer_sequenz3(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200885{
886 string playername;
887 object faq;
888 string text;
889
Zesstra60d9e252019-05-21 20:02:56 +0200890 if (!objectp(player) || !interactive(player)) {
MG Mud User88f12472016-06-24 23:31:02 +0200891 tell_room(environment(), sprintf("Merlin sagt: Na, wo ist denn %s "
892 "hin?\n", plname));
893 busy = 0;
894 return;
895 }
896 if (environment() != environment(player))
897 move(environment(player), M_TPORT);
898
899 tell_object(player,break_string("\n\nEs macht *PUFF* und eine Schwefelwolke "
900 +"steigt um Dich herum auf.\n\nDie Aura "
901 +"verschwindet langsam und Du fuehlst Dich "
902 +"nun viel erfahrener.", 78,0,1));
903 tell_room(environment(),
904 break_string(sprintf(
905 "\n\nEs macht *PUFF* und eine Schwefelwolke steigt "
906 +"um %s herum auf.\n\nDie Aura verschwindet langsam.\n",
907 plname),78,0,1), ({player}));
908
bugfixd94d0932020-04-08 11:27:13 +0200909 if (({int})"secure/master"->advance_wizlevel(geteuid(player),1)<=0)
MG Mud User88f12472016-06-24 23:31:02 +0200910 {
911 write("Merlin sagt: Da geht was schief ... sag mal Zook Bescheid.\n");
912 say("Merlin sagt: Da geht was schief ... sag mal Zook Bescheid.\n");
913 busy = 0;
914 return;
915 }
916 playername = geteuid(player);
bugfixd94d0932020-04-08 11:27:13 +0200917 ({int})"secure/master"->renew_player_object(player);
MG Mud User88f12472016-06-24 23:31:02 +0200918 player = find_player(playername);
919 text = sprintf(" ist jetzt ein%s Seher%s!\n",
bugfixd94d0932020-04-08 11:27:13 +0200920 ((({int})player->QueryProp(P_GENDER))==2?"e":""),
921 ((({int})player->QueryProp(P_GENDER))==2?"in":""));
MG Mud User88f12472016-06-24 23:31:02 +0200922 write("Merlin ruft: "+capitalize(playername)+text);
923 shout("Merlin ruft: "+capitalize(playername)+text);
Vanion50652322020-03-10 21:13:25 +0100924 PostSeher(capitalize(playername),({int})player->QueryProp(P_GENDER));
MG Mud User88f12472016-06-24 23:31:02 +0200925 if(!catch(
926 faq=clone_object("/d/seher/haeuser/special/seherfaqmobil") ;publish))
927 {
bugfixd94d0932020-04-08 11:27:13 +0200928 ({int})faq->move(player,M_NOCHECK);
MG Mud User88f12472016-06-24 23:31:02 +0200929 tell_object(player, "Aus dem Nichts erscheint eine kleine Belohnung fuer Dich.\n");
930 }
931
932 tell_object(player, "\n\nDu laechelst gluecklich in die Runde.\n\n");
933 tell_room(environment(), sprintf("\n\n%s laechelt gluecklich in die Runde.\n\n", plname), ({player}));
934
935 busy=0;
936}
937
Zesstrab16348b2019-05-21 19:41:36 +0200938void seer_sequenz2(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200939{
Zesstra60d9e252019-05-21 20:02:56 +0200940 if (!objectp(player) || !interactive(player)) {
MG Mud User88f12472016-06-24 23:31:02 +0200941 tell_room(environment(), sprintf(
942 "Merlin sagt: Na, wo ist denn %s hin?\n",
943 plname));
944 busy = 0;
945 return;
946 }
947 if (environment() != environment(player))
948 move(environment(player), M_TPORT);
949
zesstra70a0a3e2016-07-06 20:35:40 +0200950 tell_object(player, break_string("\nMerlin hebt die Arme "
MG Mud User88f12472016-06-24 23:31:02 +0200951 +"und macht einige beschwoerende Gesten. Um Dich herum erscheint "
952 +"eine gelbliche Aura, die immer heller wird, bis Du Deine "
953 +"Umwelt kaum mehr erkennen kannst.\n\n",
954 78,0,1));
955 tell_room(environment(),
956 break_string(sprintf("\nMerlin hebt die Arme und macht einige "
957 +"beschwoerende Gesten. Um %s erscheint eine "
958 +"gelbliche Aura, die immer heller wird, bis "
959 +"man %s kaum mehr erkennen kann.\n\n",
960 plname, plname),78,0,1), ({player}));
961
962 call_out("seer_sequenz3", 7, player, plname);
963}
964
Zesstrab16348b2019-05-21 19:41:36 +0200965void seer_sequenz1(object player, string plname)
MG Mud User88f12472016-06-24 23:31:02 +0200966{
Zesstra60d9e252019-05-21 20:02:56 +0200967 if (!objectp(player) || !interactive(player))
MG Mud User88f12472016-06-24 23:31:02 +0200968 return;
969
970 move(environment(player), M_TPORT);
971
972 tell_room(environment(),
973 break_string(sprintf("Das ist eine grosse Freude. %s hat sich "
974 "tapfer durch das "MUDNAME" geschlagen und mittlerweile alle "
975 "Anforderungen erfuellt, um %s zu werden.",
bugfixd94d0932020-04-08 11:27:13 +0200976 plname, (({int})player->QueryProp(P_GENDER))==1?"Seher":"Seherin"),
MG Mud User88f12472016-06-24 23:31:02 +0200977 78, "Merlin sagt: "));
978
979 call_out("seer_sequenz2", 4, player, plname);
980}
981
982
Zesstrab16348b2019-05-21 19:41:36 +0200983static int create_seer(object player)
MG Mud User88f12472016-06-24 23:31:02 +0200984{
Zesstra60d9e252019-05-21 20:02:56 +0200985 if (!objectp(player) || !interactive(player))
MG Mud User88f12472016-06-24 23:31:02 +0200986 return 0;
987 if (IS_SEER(player))
988 {
989 write(break_string("Du bist doch schon kein normaler Spieler mehr, "
990 +"was soll es also?", 78, "Merlin teilt Dir mit: "));
991 return 1;
992 }
993
994 if (!QueryBedingungen(player,"Seher"))
995 return -1;
996
997
998 write(break_string("Grosse Freude! Du hast alle Anforderungen "
999 "erfuellt. Warte einen Moment...", 78,
1000 "Merlin teilt Dir mit: "));
1001 busy=1;
bugfixd94d0932020-04-08 11:27:13 +02001002 call_out("seer_sequenz1",4,player, ({string})player->Name());
MG Mud User88f12472016-06-24 23:31:02 +02001003 return(0); //non-void funktion
1004}
1005
1006static void give_help(mixed player)
1007{
1008 if (!objectp(player))
1009 return;
1010
1011 tell_object(player,
1012 break_string("Ich weiss nicht, was ich fuer Dich tun kann. "
1013 +"Ich kann Dich zum Seher oder zum Magier "
1014 +"machen, wenn Du mich darum bittest.", 78,
1015 "Merlin teilt Dir mit: "));
1016}
1017
1018
1019void reset()
1020{
1021}
1022
1023public int remove(int silent) {
bugfixd94d0932020-04-08 11:27:13 +02001024 ({int})EVENTD->UnregisterEvent(EVT_LIB_LOGIN, ME);
1025 ({int})EVENTD->UnregisterEvent(EVT_LIB_PLAYER_CREATION, ME);
MG Mud User88f12472016-06-24 23:31:02 +02001026 destruct(this_object());
1027 return 1;
1028}
1029
1030void wandern()
1031{
MG Mud User88f12472016-06-24 23:31:02 +02001032 while (remove_call_out("wandern")>=0);
1033 call_out("wandern",45+random(100));
1034 if (busy) return;
1035 if (delay)
1036 {
1037 delay=0;
1038 return;
1039 }
Zesstra1b6b7362019-04-25 14:08:02 +02001040 if (!environment())
MG Mud User88f12472016-06-24 23:31:02 +02001041 {
1042 move("/gilden/abenteurer",0);
MG Mud User88f12472016-06-24 23:31:02 +02001043 }
1044 //ueber Inv iterieren, ob da ein nicht-idelnder Spieler mit genug XP
Zesstra1b6b7362019-04-25 14:08:02 +02001045 //rumhaengt. In diesem Raum bleiben, wenn ja.
1046 foreach(object ob: all_inventory(environment()))
1047 {
1048 if (interactive(ob) && query_idle(ob)<180
bugfixd94d0932020-04-08 11:27:13 +02001049 && ({int})ob->QueryProp(P_XP)>999999)
MG Mud User88f12472016-06-24 23:31:02 +02001050 return;
1051 }
Zesstra1b6b7362019-04-25 14:08:02 +02001052 // Ausgaenge durchsuchen
Arathornd5c9c022020-01-08 22:04:28 +01001053 mapping ex=({mapping})environment()->QueryProp(P_EXITS);
MG Mud User88f12472016-06-24 23:31:02 +02001054 if (!mappingp(ex))
1055 return;
Zesstra1b6b7362019-04-25 14:08:02 +02001056 mapping rooms = m_allocate(sizeof(ex));
1057 foreach(string cmd, string|closure dest, string msg : ex)
MG Mud User88f12472016-06-24 23:31:02 +02001058 {
Zesstra1b6b7362019-04-25 14:08:02 +02001059 object ob;
1060 // nur normale Ausgaenge benutzen
1061 if (!stringp(dest)
1062 || dest = object_name(environment()))
MG Mud User88f12472016-06-24 23:31:02 +02001063 continue;
Zesstra1b6b7362019-04-25 14:08:02 +02001064 rooms += ([dest]);
MG Mud User88f12472016-06-24 23:31:02 +02001065 }
Zesstra1b6b7362019-04-25 14:08:02 +02001066 if (!sizeof(rooms))
1067 return;
1068
1069 // Und nicht zuruecklatschen, wenn moeglich.
MG Mud User88f12472016-06-24 23:31:02 +02001070 if (prev_room && sizeof(m_indices(rooms))>1)
1071 rooms-=([prev_room]);
Zesstra1b6b7362019-04-25 14:08:02 +02001072 prev_room=object_name(environment());
1073
1074 string *raeume=m_indices(rooms);
1075 move(raeume[sizeof(raeume)],0);
MG Mud User88f12472016-06-24 23:31:02 +02001076}
1077
1078string int_short()
1079{
1080 return "Du bist im allseits beliebten Wizclub \"Zum lustigen Merlin\".\n";
1081}
1082
1083string int_long(object who,mixed where)
1084{
1085 string descr;
1086
bugfixd94d0932020-04-08 11:27:13 +02001087 if( IS_LEARNER(who) && ({int})who->QueryProp( P_WANTS_TO_LEARN ) )
MG Mud User88f12472016-06-24 23:31:02 +02001088 descr = "[" + object_name(ME) + "]\n";
1089 else
1090 descr = "";
1091 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";
bugfixd94d0932020-04-08 11:27:13 +02001092 if ( ({int})who->QueryProp(P_SHOW_EXITS) )
MG Mud User88f12472016-06-24 23:31:02 +02001093 descr += "Es gibt 2 sichtbare Ausgaenge: raus und gilde.\n";
1094 descr += make_invlist(who, all_inventory(ME) - ({ who }));
1095 if( environment())
1096 descr += "\nAusserhalb siehst Du:\n"
bugfixd94d0932020-04-08 11:27:13 +02001097 + ({string})environment()->int_short(who,ME);
MG Mud User88f12472016-06-24 23:31:02 +02001098 return descr;
1099}
1100
1101string make_invlist(object viewer,object *inv)
1102{
1103 int i, iswiz;
1104 string descr;
1105
1106 descr = "";
bugfixd94d0932020-04-08 11:27:13 +02001107 iswiz = IS_LEARNER( viewer ) && ({int})viewer->QueryProp(P_WANTS_TO_LEARN);
MG Mud User88f12472016-06-24 23:31:02 +02001108
1109 for (i = 0; i < sizeof(inv); i++)
1110 {
1111 string sh;
Arathornd5c9c022020-01-08 22:04:28 +01001112 sh = ({string})inv[i]->short();
MG Mud User88f12472016-06-24 23:31:02 +02001113 if (iswiz)
1114 {
1115 if (sh) sh = sh[0..<2] + " ["+object_name(inv[i])+"]\n";
1116 else sh = "["+object_name(inv[i])+"]\n";
1117 }
1118 if (sh) descr += sh;
1119 }
1120 return descr;
1121}
1122
1123void init()
1124{
1125 if (interactive(this_player()) && environment(this_player())==ME)
1126 add_action("gehen","",1);
1127 add_action("befoerdere","befoerder",1);
1128}
1129
1130int befoerdere(string str)
1131{
1132 string wen;
1133 int ret,stufe,l;
1134
1135 if (!LORD_SECURITY) return 0;
1136 if (!str||sscanf(str,"%s auf stufe %d",wen,stufe)<2)
1137 {
1138 notify_fail("Syntax: befoerdere <name> auf stufe <stufe>\n");
1139 return 0;
1140 }
1141 if (stufe>29)
1142 {
1143 write("Maximum ist Stufe 29!\n");
1144 return 1;
1145 }
1146 l=query_wiz_level(wen);
1147 if (l<25)
1148 {
1149 printf("%s muss mindestens zwecks Weiterbefoerderung mindestens Stufe 25 haben.\n",
1150 capitalize(wen));
1151 return 1;
1152 }
1153 if (l>=stufe)
1154 {
1155 printf("%s ist schon Stufe %d.\n",capitalize(wen),l);
1156 return 1;
1157 }
Arathornd5c9c022020-01-08 22:04:28 +01001158 ret=({int})"secure/master"->advance_wizlevel(wen,stufe);
MG Mud User88f12472016-06-24 23:31:02 +02001159 if (ret<=0)
1160 printf("Errorcode %d\n",ret);
1161 else
1162 write("ok\n");
1163 return 1;
1164}
1165
1166int sag(mixed str)
1167{
1168 int i;
1169
1170 if (str==0)
1171 str="";
1172 str = old_explode(break_string(str, 60 ), "\n");
1173 if (busy) {
1174 tell_room(ME, "Merlin mault: Ich bin beschaeftigt.\n");
1175 return 0;
1176 }
1177 for (i = 0; i < sizeof(str); i++)
1178 {
1179 if (!str[i])
1180 str[i]="";
1181 tell_room(environment(),"Merlin sagt: "+str[i]+"\n");
1182 tell_room(ME,"*Merlin sagt: "+str[i]+"\n");
1183 }
1184 return 1;
1185}
1186
1187void show_exits()
1188{
bugfixd94d0932020-04-08 11:27:13 +02001189 printf("%s",({string})environment()->GetExits());
MG Mud User88f12472016-06-24 23:31:02 +02001190}
1191
1192int gehen(string str)
1193{
MG Mud User88f12472016-06-24 23:31:02 +02001194 if (busy) {
1195 write("Merlin mault: Ich bin beschaeftigt.\n");
1196 return 0;
1197 }
1198
Arathornd5c9c022020-01-08 22:04:28 +01001199 str=({string})this_interactive()->_unparsed_args();
Zesstra1b6b7362019-04-25 14:08:02 +02001200 switch (query_verb())
MG Mud User88f12472016-06-24 23:31:02 +02001201 {
1202 case "gilde":
bugfixd94d0932020-04-08 11:27:13 +02001203 ({int})this_player()->move("/gilden/abenteurer",M_GO,"in die Gilde");
MG Mud User88f12472016-06-24 23:31:02 +02001204 return 1;
1205 case "raus":
bugfixd94d0932020-04-08 11:27:13 +02001206 ({int})this_player()->move(environment(),M_GO,"raus");
MG Mud User88f12472016-06-24 23:31:02 +02001207 return 1;
1208 }
1209 if (!IS_WIZARD(this_interactive()))
1210 return 0;
Zesstra1b6b7362019-04-25 14:08:02 +02001211 if (query_verb()!="merlin")
MG Mud User88f12472016-06-24 23:31:02 +02001212 return 0;
1213 delay=1;
Arathornd5c9c022020-01-08 22:04:28 +01001214 mapping exits=({mapping})environment()->QueryProp(P_EXITS);
MG Mud User88f12472016-06-24 23:31:02 +02001215 if (!str||str=="")
1216 {
bugfixd94d0932020-04-08 11:27:13 +02001217 printf(({string})environment()->int_short(ME,ME));
MG Mud User88f12472016-06-24 23:31:02 +02001218 show_exits();
1219 return 1;
1220 }
1221 if (old_explode(str," ")[0]=="sag")
1222 return sag(implode(old_explode(str," ")[1..]," "));
1223 if (str[0]==';')
1224 {
1225 tell_room(environment(ME),"Merlins "+str[1..]+"\n");
1226 tell_room(ME,"*Merlins "+str[1..]+"\n");
1227 return 1;
1228 }
1229 if (str[0]==':')
1230 {
1231 tell_room(environment(ME),"Merlin "+str[1..]+"\n");
1232 tell_room(ME,"*Merlin "+str[1..]+"\n");
1233 return 1;
1234 }
1235 if (str[0]=='*')
1236 {
1237 goto(str[1..]);
bugfixd94d0932020-04-08 11:27:13 +02001238 printf(({string})environment()->int_short(ME,ME));
MG Mud User88f12472016-06-24 23:31:02 +02001239 show_exits();
1240 return 1;
1241 }
1242 if (!exits[str])
1243 return 0;
1244 move(exits[str],0);
1245 write("Merlin sagt: Jawoll, Chef.\n");
bugfixd94d0932020-04-08 11:27:13 +02001246 printf(({string})environment()->int_short(ME,ME));
MG Mud User88f12472016-06-24 23:31:02 +02001247 show_exits();
1248 return 1;
1249}
1250
1251int goto(mixed dest)
1252{
1253 object ob;
1254 string path;
1255 mixed ret;
1256
1257 if (busy) {
1258 write("Merlin mault: Ich bin beschaeftigt.\n");
1259 return 1;
1260 }
1261
1262 if (!dest) {
1263 write("Wohin moechtest Du Merlin bringen ?\n");
1264 return 1;
1265 }
1266 ob = find_living(dest);
1267 if (ob) {
1268 ob = environment(ob);
1269 move(object_name(ob),0);
1270 return 1;
1271 }
Arathornd5c9c022020-01-08 22:04:28 +01001272 path = ({string})master()->make_path_absolute(dest);
MG Mud User88f12472016-06-24 23:31:02 +02001273 ret=catch(load_object(path);publish);
1274 if (ret && file_size(path)<0)
1275 {
1276 dest=match_living(dest,1);
1277 if (stringp(dest))
1278 {
1279 ob = environment(find_living(dest));
1280 move(object_name(ob),M_TPORT|M_NOCHECK);
1281 return 1;
1282 }
1283 printf("Fehler beim Teleport nach %O: No such file.\n",path);
1284 return 1;
1285 }
1286 if (ret)
1287 printf("Fehler beim Teleport nach %O: %O\n",dest,ret);
1288 ret=catch(move(path,M_TPORT|M_NOCHECK);publish);
1289 if (stringp(ret))
1290 ret=implode(old_explode(ret,"\n"),"");
1291 if (ret)
1292 printf("Fehler beim Teleport nach %O: %O\n",dest,ret);
1293 return 1;
1294}
1295
1296mixed locate_objects(string complex_desc)
1297{
1298 object ob;
1299
1300 if (complex_desc=="alles" || complex_desc=="alle")
1301 return filter_objects(all_inventory(this_object()),"short");
1302 if (ob = present(complex_desc,this_object()) )
1303 return ({ ob });
1304 return ({}) ;
1305}
1306
1307void MBanishInsert(string name, string grund, object wer)
1308{
1309 if ( !name || !stringp(name) || !sizeof(name) ||
1310 !grund || !stringp(grund) || !sizeof(grund) ||
1311 !wer || !objectp(wer) || getuid(wer) != secure_euid() ||
1312 !IS_DEPUTY(wer) )
1313 return;
1314
1315 MBanishListe += ([name:grund;getuid(wer)]);
1316 save_object(SAVEFILE);
1317}
1318
1319mapping MBanishList()
1320{
1321 if ( !IS_DEPUTY(secure_euid()) )
1322 return 0;
1323
1324 return deep_copy(MBanishListe);
1325}
1326
1327void MBanishDelete(string name)
1328{
1329 if ( !name || !stringp(name) || !sizeof(name) || !ARCH_SECURITY )
1330 return 0;
1331
1332 MBanishListe = m_copy_delete( MBanishListe, name );
1333 save_object(SAVEFILE);
1334}
1335
1336string _query_noget()
1337{
1338 return "Merlin mag das nicht!\n";
1339}
1340