blob: a7cc64eb3e1068359fe58b4b9497d23fe1a01d8b [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// death_room.c -- Der Todesraum
4//
5// $Id: death_room.c 9138 2015-02-03 21:46:56Z Zesstra $
6
7
Zesstra3882c2d2020-07-27 22:37:17 +02008#pragma strong_types,rtt_checks
MG Mud User88f12472016-06-24 23:31:02 +02009
10#include <defines.h>
11#include <properties.h>
12#include <moving.h>
13#include <language.h>
14#include <wizlevels.h>
15#include <daemon.h>
16#include <new_skills.h>
17
18inherit "/std/room";
Zesstra39d1d2b2020-09-28 23:53:04 +020019nosave variables inherit "/std/channel_supervisor";
MG Mud User88f12472016-06-24 23:31:02 +020020
21mixed *players;
22mapping msgCache;
23
24
25private void flush( int unusedOnly );
26private string expand( string table, int value );
27private string parseText( string msg, object pl );
28private void do_remove();
29private varargs mixed get_sequence( string str );
30void add_player( object pl );
31static int filter_ldfied( string str );
32public int SmartLog( string creat, string myname, string str, string date );
33public mixed hier_geblieben( mixed dest, int methods, string direction,
34 string textout, string textin );
Arathorn306aa032018-08-29 22:18:28 +020035
36public varargs void init(object oldenv)
MG Mud User88f12472016-06-24 23:31:02 +020037{
38 this_player()->move("/room/death/virtual/death_room_"+getuid(this_player()),
39 M_NOCHECK|M_SILENT|M_NO_SHOW);
40 return;
41}
42
43public void create()
44{
Zesstra39d1d2b2020-09-28 23:53:04 +020045 if (IS_CLONE(this_object())) return;
MG Mud User88f12472016-06-24 23:31:02 +020046 ::create();
Zesstra39d1d2b2020-09-28 23:53:04 +020047 ch_read_init_file();
48
MG Mud User88f12472016-06-24 23:31:02 +020049 players = ({});
50 flush(0);
51
52 SetProp( P_NAME, "Lars" );
53 SetProp( P_GENDER, MALE );
54 SetProp( P_ARTICLE, 0 );
55 SetProp( P_LIGHT,1 );
56 SetProp( P_NO_TPORT, NO_TPORT_OUT );
57 SetProp( P_LOG_FILE, "TOD/Todesraum" );
58 SetProp( P_INT_SHORT, "Arbeitszimmer des Todes" );
59 SetProp( P_INT_LONG, break_string(
60 "Ein dunkler Raum, erleuchtet von dunklem Licht, das sich der "
61 "Dunkelheit nicht so sehr zu widersetzen scheint, indem es "
62 "leuchtet, als dass es der dunkelste Punkt in einer weniger "
63 "dunklen Umgebung ist. Im seltsamen Licht erkennst Du einen "+
64 "zentral aufgestellten Schreibtisch, der mit Diagrammen und "
65 "Buechern bedeckt ist. Die Waende verschwinden hinter Regalen, "
66 "die gefuellt sind mit in Leder gebundenen, dunklen Waelzern, "
67 "von denen geheimnisvolle Runen leuchten.\nTod.", 78, 0, 1 ) );
68}
69
Zesstra39d1d2b2020-09-28 23:53:04 +020070public varargs string name(int casus,int demon)
71{
72 return room::name(casus, demon);
73}
74
75public varargs string Name(int casus, int demon)
76{
77 return room::Name(casus, demon);
78}
MG Mud User88f12472016-06-24 23:31:02 +020079
80public void reset()
81{
82 ::reset();
83 flush(1);
84}
85
86private void flush( int unusedOnly )
87{
88 string *mi;
89 int i;
90
91 if ( unusedOnly ){
92 if ( i = sizeof(mi = m_indices(msgCache)) ){
93 for ( ; i--; )
94 if ( msgCache[mi[i], 1] )
95 msgCache[mi[i], 1] = 0;
96 else
97 msgCache = m_copy_delete( msgCache, mi[i] );
98 }
99 }
100 else
101 msgCache = ([]);
102}
103
104
105private string expand( string table, int value )
106{
107 int sz, wert, i;
108 string *texte;
109
110 sz = sizeof( texte = explode( table, "##" ) - ({""}) );
111
112 for ( i = 0; i < sz; i++ )
113 if ( i%2 ){
114 sscanf( texte[i], "%d", wert );
115
116 if ( value < wert )
117 break;
118 }
119 else
120 table = texte[i];
121
122 return table;
123}
124
125
126#define TOS(s) s[<1]
127#define STOS(s) s[<2]
128#define PUSH(x,s) (s+= ({ x }))
129#define POP(s) (s=s[0..<2])
130
131// ziemlich vom htmld abgekupfert ;)
132private string
133parseText( string msg, object pl )
134{
135 string *words, *texte, *todo, *done;
136 int endFlag;
137
138 int sz = sizeof( words = regexplode(msg, "[<][^>]*[>]") );
139 todo = ({ });
140 done = ({""});
141
142 for ( int i=1; i<sz; i+=2 ){
143 string cmd = words[i][1..<2];
144 TOS(done) += words[i-1];
145
146 if ( cmd[0] == '/' ){
147 endFlag = 1;
148 cmd = cmd[1..];
149 }
150 else
151 endFlag = 0;
152
153 switch( cmd[0] ){
154 case 'A': /*** Alignment ersetzen ***/
155 if (!endFlag){
156 PUSH( cmd, todo );
157 PUSH( "", done );
158 }
159 else
160 if ( todo[<1] == "A" ){
Zesstra3882c2d2020-07-27 22:37:17 +0200161 STOS(done) += expand(TOS(done), ({int}) pl->QueryProp(P_ALIGN));
MG Mud User88f12472016-06-24 23:31:02 +0200162 done = done[0..<2];
163 todo = todo[0..<2];
164 }
165 break;
166
167 case 'D': /*** Tode ersetzen ***/
168 if ( !endFlag ){
169 PUSH( cmd, todo );
170 PUSH( "", done );
171 }
172 else
173 if ( todo[<1] == "D" ){
Zesstra3882c2d2020-07-27 22:37:17 +0200174 STOS(done) += expand(TOS(done), ({int}) pl->QueryProp(P_DEADS));
MG Mud User88f12472016-06-24 23:31:02 +0200175 POP(done);
176 POP(todo);
177 }
178 break;
179
180 case 'L': /*** Level ersetzen ***/
181 if ( !endFlag ){
182 PUSH( cmd, todo );
183 PUSH( "", done );
184 }
185 else
186 if ( todo[<1] == "L" ){
Zesstra3882c2d2020-07-27 22:37:17 +0200187 STOS(done) += expand(TOS(done), ({int}) pl->QueryProp(P_LEVEL));
MG Mud User88f12472016-06-24 23:31:02 +0200188 POP(done);
189 POP(todo);
190 }
191 break;
192
193 case 'Z': /*** Zufall ersetzen ***/
194 if ( !endFlag ){
195 PUSH( cmd, todo );
196 PUSH( "", done );
197 }
198 else{
199 if ( todo[<1][0] == 'Z'){
200 int cnt, rnd, wert, sz2;
201
202 if ( !sscanf(todo[<1], "Z=%d", rnd) )
203 STOS(done) += "\n###\n### Syntax Error in <Z>!\n###\n\n";
204 else {
205 rnd = random(rnd);
206 sz2 = sizeof( texte = explode(TOS(done), "##") );
207 wert=0;
208 cnt=0;
209
210 for ( int k = 1; k < sz2; k += 2 ){
211 sscanf( texte[k], "%d", wert );
212 cnt += wert;
213 if ( rnd < cnt ) {
214 STOS(done) += texte[k+1];
215 break;
216 }
217 }
218 }
219 POP(done);
220 POP(todo);
221 }
222 }
223 break;
224
225 case 'G': /*** Gender ersetzen ***/
226 if ( !endFlag ){
227 PUSH( cmd, todo );
228 PUSH( "", done );
229 }
230 else{
231 if( sizeof( texte = regexplode(TOS(done), ":") ) == 3 )
Zesstra3882c2d2020-07-27 22:37:17 +0200232 STOS(done) += texte[2*(({int}) pl->QueryProp(P_GENDER)
MG Mud User88f12472016-06-24 23:31:02 +0200233 == FEMALE)];
234 POP(done);
235 POP(todo);
236 }
237 break;
238
239 case 'R': /*** Rasse ersetzen ***/
240 if ( !endFlag ){
241 PUSH( cmd, todo );
242 PUSH( "", done );
243 }
244 else{
245 int race;
246
247 texte = regexplode( TOS(done), "\\|" );
248 race = 2 * (member( ({ "Mensch", "Elf", "Zwerg", "Hobbit",
249 "Feline", "Dunkelelf" }),
Zesstra3882c2d2020-07-27 22:37:17 +0200250 ({string}) pl->QueryProp(P_RACE) ) + 1);
MG Mud User88f12472016-06-24 23:31:02 +0200251
252 if ( race >= sizeof(texte) )
253 race = 0;
254
255 STOS(done) += texte[race];
256 POP(done);
257 POP(todo);
258 }
259 break;
260
261 case 'n': /*** Name, normal geschrieben ***/
Zesstra3882c2d2020-07-27 22:37:17 +0200262 TOS(done) += (string) (({string})pl->name(RAW));
MG Mud User88f12472016-06-24 23:31:02 +0200263 break;
264
265 case 'N': /*** Name, in Grossbuchstaben ***/
Zesstra3882c2d2020-07-27 22:37:17 +0200266 TOS(done) += upperstring(({string})pl->name(RAW));
MG Mud User88f12472016-06-24 23:31:02 +0200267 break;
268 }
269 }
270 PUSH( words[<1], done );
271 return implode( done, "" );
272}
273
274
275public void heart_beat()
276{
277 for ( int j = sizeof(players); j--; )
278 if ( !objectp(players[j][0]) ||
279 environment(players[j][0]) !=
280 find_object("/room/death/virtual/death_room_"+getuid(players[j][0])) )
281 players[j] = 0;
282
283 players -= ({0});
284
285 if ( !sizeof(players) ) {
286 set_heart_beat(0);
287 return;
288 }
289
290 for ( int j = sizeof(players); j--; ) {
291 int nr;
292 string msg;
293
294 nr = ++players[j][1];
295
296 if ( mappingp(players[j][2]) )
297 msg = players[j][2][nr];
298 else
299 msg = 0;
300
301 if ( !msg )
302 msg = players[j][3][1][nr];
303
304 if ( msg )
305 tell_object( players[j][0], parseText( msg, players[j][0] ) );
306 }
307
308 do_remove();
309}
310
311private void
312do_remove()
313{
314 int res;
315 string prayroom;
316 object plobj, pl;
317
318 for ( int j = sizeof(players); j--; ){
319 if ( players[j][1] >= players[j][3][0]){
320 pl = players[j][0];
321 while ( plobj = present("\ndeath_mark", pl) )
322 plobj->remove();
323
324 if ( !(prayroom = (string) pl->QueryPrayRoom()) )
325 prayroom="/room/pray_room";
326
327 pl->Set( P_TMP_MOVE_HOOK, 0 );
328 pl->Set( P_NO_ATTACK, 0, F_QUERY_METHOD );
329 pl->Set( P_LAST_KILLER, 0 );
330 pl->Set( P_KILLER, 0 );
331 pl->Set( P_ENEMY_DEATH_SEQUENCE, 0 );
332 pl->Set( P_NEXT_DEATH_SEQUENCE, 0 );
333 pl->Set( P_POISON, 0, F_QUERY_METHOD );
334
335 if ( catch( res = (int) pl->move(prayroom, M_GO|M_SILENT|M_NOCHECK) )
336 || res < 1 )
337 pl->move( "/room/pray_room", M_GO|M_NOCHECK );
338
339 players[j] = 0;
340 }
341 }
342
343 players -= ({0});
344
345 if ( !sizeof(players) )
346 set_heart_beat(0);
347}
348
349private varargs mixed
350get_sequence( string str )
351{
352 string *sequences;
353 int i, len, cacheable;
354
355 if ( !stringp(str) || catch( len = file_size(str) ) || len <= 0 ){
356 sequences = get_dir( "/room/death/sequences/*" ) - ({ ".", "..", ".svn" });
357 str = "/room/death/sequences/" + sequences[random( sizeof(sequences) )];
358 }
359
360 if ( cacheable = ((sizeof(str) > 21) &&
361 (str[0..21] == "/room/death/sequences/")) ){
362 if ( member(msgCache, str) ){
363 msgCache[str, 1] = 1; // Touch it!
364 return ({ msgCache[str], str });
365 }
366 }
367
368 sequences = explode( read_file(str), "\n" );
369 sscanf( sequences[0], "%d", len );
370 string seq = implode( sequences[1..], "\n" );
371 sequences = regexplode( seq, "[0-9][0-9]*:" );
372 mapping m = ([]);
373
374 for ( i = 1; i < sizeof(sequences)-1; i += 2 )
375 m[(int) sequences[i]] = sequences[i+1];
376
377 if ( cacheable )
378 msgCache += ([ str: ({ len, m }); 1 ]);
379
380 return ({ ({ len, m }), str });
381}
382
383// Description: Adds a player to the list
384void add_player( object pl )
385{
386 int kart, kgen;
387 int escaped;
388 object kill_liv, kill_ob;
389 mixed dseq, act_seq, killer_name, killer_msg;
390
391 set_heart_beat(1);
392 kgen = MALE;
393
394 foreach(object prev : caller_stack(1)) {
395 if ( !objectp(prev) || prev == pl )
396 continue;
397
398 string fn = object_name(prev);
399
400 if ( fn[0..12] == "/secure/login" && !kill_liv ){
401 escaped = 1;
402 break;
403 }
404
405 if ( fn[0..7] == "/secure/" && fn[0..13] != "/secure/merlin" )
406 continue;
407
408 if ( fn[0..21] == "/room/death/death_mark" )
409 continue;
410
411 if ( living(prev) ){
412 kill_liv = prev; // Killer
413 break;
414 }
415
416 kill_ob = prev; // killendes Objekt
417 }
418
Arathorn6fa8c9e2020-08-05 13:29:02 +0200419 string|object pre = pl->QueryProp(P_KILLER);
MG Mud User88f12472016-06-24 23:31:02 +0200420 if ( objectp(pre) ) {
Zesstra3882c2d2020-07-27 22:37:17 +0200421 dseq = pre->QueryProp(P_ENEMY_DEATH_SEQUENCE);
MG Mud User88f12472016-06-24 23:31:02 +0200422
Zesstra3882c2d2020-07-27 22:37:17 +0200423 if( !(killer_name = pre->QueryProp(P_KILL_NAME)) ){
424 killer_name = pre->QueryProp(P_NAME);
MG Mud User88f12472016-06-24 23:31:02 +0200425 kart = (int) pre->QueryProp(P_ARTICLE);
426 kgen = (int) pre->QueryProp(P_GENDER);
427 }
428
Zesstra3882c2d2020-07-27 22:37:17 +0200429 killer_msg = pre->QueryProp(P_KILL_MSG);
MG Mud User88f12472016-06-24 23:31:02 +0200430 }
431
432 if ( !killer_name && kill_liv && function_exists( "QueryProp", kill_liv ) ){
Zesstra3882c2d2020-07-27 22:37:17 +0200433 dseq = kill_liv->QueryProp(P_ENEMY_DEATH_SEQUENCE);
MG Mud User88f12472016-06-24 23:31:02 +0200434
Zesstra3882c2d2020-07-27 22:37:17 +0200435 if( !(killer_name = kill_liv->QueryProp(P_KILL_NAME)) ){
436 killer_name = kill_liv->QueryProp(P_NAME);
MG Mud User88f12472016-06-24 23:31:02 +0200437 kart = (int) kill_liv->QueryProp(P_ARTICLE);
438 kgen = (int) kill_liv->QueryProp(P_GENDER);
439 }
440
Zesstra3882c2d2020-07-27 22:37:17 +0200441 killer_msg = kill_liv->QueryProp(P_KILL_MSG);
MG Mud User88f12472016-06-24 23:31:02 +0200442 pre = kill_liv;
443 }
444
445 if ( !killer_name && kill_ob && function_exists( "QueryProp", kill_ob ) ){
Zesstra3882c2d2020-07-27 22:37:17 +0200446 dseq = kill_ob->QueryProp(P_ENEMY_DEATH_SEQUENCE);
MG Mud User88f12472016-06-24 23:31:02 +0200447
Zesstra3882c2d2020-07-27 22:37:17 +0200448 if( !(killer_name = kill_ob->QueryProp(P_KILL_NAME)) ){
449 killer_name = kill_ob->QueryProp(P_NAME);
MG Mud User88f12472016-06-24 23:31:02 +0200450 kart = (int) kill_ob->QueryProp(P_ARTICLE);
451 kgen = (int) kill_ob->QueryProp(P_GENDER);
452 }
453
Zesstra3882c2d2020-07-27 22:37:17 +0200454 killer_msg = kill_ob->QueryProp(P_KILL_MSG);
MG Mud User88f12472016-06-24 23:31:02 +0200455 pre = kill_ob;
456 }
457
458 // falls keine Sequenz gesetzt, eventuelle eigene Todessequenz nehmen
459 if (!dseq)
Zesstra3882c2d2020-07-27 22:37:17 +0200460 dseq = ({<string|mapping|mixed*>})pl->QueryProp(P_NEXT_DEATH_SEQUENCE);
MG Mud User88f12472016-06-24 23:31:02 +0200461
462 act_seq = 0;
463
464 if ( mappingp(dseq) )
465 act_seq = get_sequence( "/room/death/sequences/lars" );
466 else if ( pointerp(dseq) ) // ganze Todessequenz...
467 act_seq = ({ dseq, 0 });
468 else if ( stringp(dseq) )
469 act_seq = get_sequence(dseq);
470
Zesstra3882c2d2020-07-27 22:37:17 +0200471 if(({int})pl->query_hc_play()>1)
MG Mud User88f12472016-06-24 23:31:02 +0200472 {
473 act_seq=({({22,([1:"Du faellst und faellst...\n",
474 5:"und faellst...\n",
475 10:"und faellst...\n",
476 12:"direkt in die Arme von TOD.\n",
477 14:"Triumphierend laechelt er Dich an.\n",
478 16:"NUN GEHOERST DU FUER IMMER MIR!\n",
479 18:"HAHHHAHAHAAAAAAAAAAHAAAAAAAAA!\n",
480 20:"TOD schlaegt Dir mit seiner Sense den Kopf ab.\n"])}),0});
481 }
482 if ( !act_seq )
483 act_seq = get_sequence();
484
485 if ( !mappingp(dseq) )
486 dseq = 0;
487
488 int i;
489 for ( i = sizeof(players); i--; )
490 if ( players[i][0] == pl )
491 break;
492
493 if ( i == -1 )
494 players += ({ ({ pl, 0, dseq, act_seq[0], act_seq[1], pre }) });
495 else
496 players[i][5] = pre;
497
498
499 if ( escaped ){
500 killer_name = "";
501 killer_msg = upperstring(getuid(pl)) + " VERSUCHTE, MIR ZU "
502 "ENTKOMMEN - JETZT HABE ICH WIEDER EXTRA-ARBEIT MIT "+
503 ((int) pl->QueryProp(P_GENDER) != 2 ? "IHM" : "IHR") +
504 " ...";
505 }
506 else if ( !killer_name ) {
507 if ( (string) pl->QueryProp(P_KILLER) == "gift" ){
508 killer_name = "Vergiftung";
509 kgen = FEMALE;
510 kart = 1;
511 }
512 else{
513 killer_name = "Etwas Geheimnisvolles und Unbekanntes";
514 kgen = NEUTER;
515 kart = 0;
516 }
517 }
518
519 if ( !pointerp(killer_msg) )
520 killer_msg = ({ killer_msg, 0, 0 });
521 else if ( sizeof(killer_msg) < 3 )
522 killer_msg += ({ 0, 0, 0 });
523
524 if ( stringp(killer_msg[0]) )
525 killer_msg[0] = sprintf( killer_msg[0], capitalize(getuid(pl)) );
526
527 SetProp( P_NAME, killer_name );
528 SetProp( P_ARTICLE, kart );
529 SetProp( P_GENDER, kgen );
530 string killname = Name(WER);
531 SetProp( P_NAME, "Lars" );
532 SetProp( P_ARTICLE, 0 );
533 SetProp( P_GENDER,MALE );
534
535 int magiertestie;
536 string testplayer = (string) pl->QueryProp(P_TESTPLAYER);
537 if (sizeof(testplayer))
538 {
539 if (testplayer[<5..<1]!="Gilde")
540 magiertestie = 1;
541 }
542
543 string kanal;
544 if (magiertestie || IS_LEARNING(pl))
545 kanal = "TdT";
546 else
547 kanal = "Tod";
548
549 CHMASTER->join( kanal, this_object() );
550
551 if ( (!stringp(killer_name) || killer_name != "") &&
552 (sizeof(killer_msg) < 4 || !killer_msg[3]) ){
553 if ( killer_msg[2] == PLURAL )
554 CHMASTER->send( kanal, this_object(),
555 killname + " haben gerade " +
556 capitalize(getuid(pl)) + " umgebracht." );
557 else
558 CHMASTER->send( kanal, this_object(),
559 killname + " hat gerade " +
560 capitalize(getuid(pl)) + " umgebracht." );
561 }
562
563 i = (int) pl->QueryProp(P_DEADS);
564 if ( i && (getuid(pl) == "key" || i%100 == 0 || i%250 == 0) ){
565 SetProp( P_NAME, "Tod" );
566 CHMASTER->send( kanal, this_object(),
567 sprintf( "DAS WAR SCHON DAS %dTE MAL!", i ) );
568 SetProp( P_NAME, "Lars" );
569 }
570
571 if( killer_msg[0] ){
572 if ( stringp(killer_name) && killer_name == "" ){
573 CHMASTER->send( kanal, this_object(),
574 break_string( funcall(killer_msg[0]), 78,
575 "["+kanal+":] " )[0..<2],
576 MSG_EMPTY );
577 return;
578 }
579 else {
580 if ( (killer_msg[1] < MSG_SAY) || (killer_msg[1] > MSG_GEMOTE) )
581 killer_msg[1] = MSG_SAY;
582
583 SetProp( P_NAME, killer_name );
584 SetProp( P_ARTICLE, kart );
585 SetProp( P_GENDER, kgen );
586 CHMASTER->send( kanal, this_object(), funcall(killer_msg[0]),
587 killer_msg[1] );
588 SetProp( P_NAME, "Lars" );
589 SetProp( P_ARTICLE, 0 );
590 SetProp( P_GENDER, MALE );
591 }
592 }
593
Zesstra3882c2d2020-07-27 22:37:17 +0200594 if ( pointerp(killer_msg = pl->QueryProp(P_DEATH_MSG)) &&
MG Mud User88f12472016-06-24 23:31:02 +0200595 sizeof(killer_msg) == 2 && stringp(killer_msg[0]) &&
596 intp(killer_msg[1]) ){
597 SetProp( P_NAME, capitalize(getuid(pl)) );
598 SetProp( P_ARTICLE, 0 );
Zesstra3882c2d2020-07-27 22:37:17 +0200599 SetProp( P_GENDER, ({int})pl->QueryProp(P_GENDER) );
MG Mud User88f12472016-06-24 23:31:02 +0200600 CHMASTER->send( kanal, this_object(), killer_msg[0],
601 killer_msg[1] );
602 SetProp( P_NAME, "Lars" );
603 SetProp( P_ARTICLE, 0 );
604 SetProp( P_GENDER, MALE );
605 }
606
Zesstra3882c2d2020-07-27 22:37:17 +0200607 if (({int})pl->query_hc_play()>1){
MG Mud User88f12472016-06-24 23:31:02 +0200608 SetProp( P_NAME, "Tod" );
609 CHMASTER->send( kanal, this_object(),"NUN GEHOERST DU FUER EWIG MIR!" );
610 SetProp( P_NAME, "Lars" );
611 }
612}
613
614public int
615SmartLog( string creat, string myname, string str, string date )
616{
617 int i;
618 string fn;
619
620 for ( i = sizeof(players); i--; )
621 if ( players[i][0] == this_player() )
622 break;
623
624 // Spieler (Magier?) ist in keiner Todessequenz -> normales Repfile
625 if ( i == -1 )
626 return 0;
627
628 if ( !(fn = players[i][4]) ){
629 // Spieler hat eine unbekannte Todessequenz (kein Filename, Sequenz
630 // wurde komplett in P_ENEMY_DEATH_SEQUENCE abgelegt)
631 creat = "TOD/unbekannt.rep";
632 fn = "unbekannte Todessequenz";
633 }
634 else
635 // Jede Sequenz mit nem eigenen Repfile
636 creat = "TOD/" + explode( fn, "/" )[<1] + ".rep";
637
638 log_file( creat, myname + " von " + getuid(this_interactive())
639 + " ["+fn+"] (" + date + "):\n" + str + "\n" );
640
641 return 1;
642}
643
644public mixed hier_geblieben( mixed dest, int methods, string direction,
645 string textout, string textin )
646{
647 // Magier duerfen Spieler heraustransen
648 if ( this_interactive() && IS_LEARNER(this_interactive()) &&
649 (this_interactive() != previous_object() ||
650 IS_DEPUTY(this_interactive())) ){
651 previous_object()->Set( P_TMP_MOVE_HOOK, 0 );
652 return ({ dest, methods, direction, textout, textin });
653 }
654
655 // Spieler haengt noch in der Todessequenz
656 for ( int i = sizeof(players); i--; )
657 if ( objectp(players[i][0]) && previous_object() == players[i][0] &&
658 environment(previous_object()) == find_object(
659 "/room/death/virtual/room_death_" + getuid(previous_object()))&&
660 interactive(previous_object()) ) {
661 // Move nur erlaubt, wenn das Ziel wieder der Todesraum ist.
662 // wenn mal fuer nen bestimmten Zwecks Bewegungen raus aus dem
663 // Todesraum erforderlich sind, sollten hier entsprechende
664 // Ausnahmen eingebaut werden.
665 if ( (stringp(dest) &&
666 dest == object_name(environment(previous_object()))) ||
667 (objectp(dest) &&
668 dest == environment(previous_object())) ) {
669 previous_object()->Set( P_TMP_MOVE_HOOK, 0 );
670 return ({ dest, methods, direction, textout, textin });
671 }
672 else
673 return -1;
674 }
675
676 // Spieler ist nicht mehr im Raum oder eingeschlafen
677 if ( previous_object() )
678 previous_object()->Set( P_TMP_MOVE_HOOK, 0 );
679
680 return ({ dest, methods, direction, textout, textin });
681}