blob: aa82694d8b66dc6f24f6150f1dd77175a7ecafdd [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001/* Shutdown-Daemon -- die Messages muessen wohl nochmal ueberarbeitet werden */
2/*
3 * 04.04.2004 Vanion die() ueberschrieben, ignorierbar gemacht
4 * 15.01.2000 Tiamak aufgeraeumt, sicherer gemacht
5 * 15.02.1998 Wargon Armageddon teilt einem die Restzeit mit
6 * 07.01.1998 Rumata IS_ELDER ausgebaut.
7 *
8 * 23.07.1997 17.00 Yantro
9 * Ich hab mal die shouts Zeitabhaengig gemacht, also sie sollten
10 * heftiger werden mit Annaeherung an den Reboot. Deswegen gibt
11 * es nun 4 arrays mit messages und die Entsprechende Aufrufaenderung
12 * in ArmasShout()
13 */
14
15#pragma combine_strings
16#pragma strong_types
17#pragma strict_types
18#pragma no_inherit
19#pragma no_clone
20#pragma no_shadow
21
22inherit "std/npc";
23
24#define S_PRESAY 1
25#define S_IGNORE 2
26
27#include <properties.h>
28#include <defines.h>
29#include <language.h>
30#include <moving.h>
31#include "/secure/wizlevels.h"
32
33#define messages1 ({ \
34 "Wolken ballen sich am Himmel. Es scheint wohl ein Unwetter aufzuziehen. " \
35 "Du hast ein ungutes Gefuehl in Deiner Haut.", \
36 "Aus der Ferne hoerst Du ein Donnern ... ob das ein Gewitter ist?", \
37 "Wolken ziehen schnell vorbei und verdunkeln die Sonne und die Sterne. " \
38 "Dies scheint keines der normalen Unwetter zu sein, die Du schon erlebt " \
39 "hast.", \
40 "Das ferne Rauschen der Baeche und Fluesse wird lauter. Die Wassermassen " \
41 "scheinen nicht mehr kontrolliert zu fliessen und Du bekommst Angst!", \
42 "Der Himmel faerbt sich violett. Das Unwetter scheint gewaltiger zu " \
43 "werden als sonst. Dir laeuft ein Schauer ueber den Ruecken." \
44 })
45
46#define messages2 ({ \
47 "Die Wolken verdunkeln den Himmel. Es wird ueberall duester in der Welt " \
48 "und Du kannst kaum noch erkennen, was um Dich herum geschieht.", \
49 "Ein starker Wind weht durch alle Gegenden und zerrt an allem, was nicht " \
50 "fest ist. Hoffentlich wird das nicht noch schlimmer.", \
51 "Regen prasselt ueberall nieder und fuellt die Baeche und Seen, die das " \
52 "Wasser aber kaum noch halten koennen. Du versucht eine trockene Stelle " \
53 "zu finden.", \
54 "Der Himmel ist fast schwarz. Der Regen faellt in einer Menge, als haetten " \
55 "alle Schleusen der Welt geoeffnet, um sie fuer immer zu ertraenken.", \
56 "Die Luft scheint zu knistern! Das Ende des Unwetters ist sicher noch nicht "\
57 "in Sicht. Elektrizitaet entlaedt sich im Himmel zwischen den Wolken. " \
58 "Was fuer ein Lichtspiel!", \
59 "Blitz und Donner hallen durch die Welt. Es scheint keine Stelle zu geben, " \
60 "an der man sicher sein kann." \
61 })
62
63#define messages3 ({ \
64 "Du siehst, wie die Einwohner der Welt versuchen, sich panisch vor dem " \
65 "Unwetter zu retten, aber es ist fuer sie zu spaet.", \
66 "Blitze nie gesehener Gewalt schlagen rund um Dich ein. Feuer flammen auf " \
67 "und scheinen alles verbrennen zu wollen, was um Dich herum existiert.", \
68 "Dicke Wolken tuermen sich immer weiter auf und scheinen Dich erdruecken zu "\
69 "wollen. Sie sind nicht mehr schwarz, sondern blutrot wie das Wasser, was " \
70 "sie von sich geben.", \
71 "Die Fluesse und Meere der Welt treten ueber ihre Ufer und zerstoeren alles "\
72 "Leben. Das Wasser hat sich zu Blut gewandelt! Um Dich herum wird alles " \
73 "rot!", \
74 "Der Donner grollt mit roher Gewalt durch die Welt. Die Schallwellen " \
75 "schlagen mit aller Kraft gegen die Gebirge und scheinen sie reizen zu " \
76 "wollen. Du kriegst Angst!", \
77 "Der Regen faerbt sich rot! Das ist kein Wasser mehr, sondern Blut, was da " \
78 "auf Dich herabregnet. Dir schwinden kurz die Sinne beim Gedanken an das, " \
79 "was noch kommen mag." \
80 })
81
82#define messages4 ({ \
83 "Das Blut des Regens scheint Dich fortzuschwemmen. Ueberall ist das Blut " \
84 "ueber die Ufer getreten und sucht sich seinen toedlichen Weg.", \
85 "Die Vulkane der Welt brechen aus und die Lava verbrennt alles, was sich " \
86 "ihr in den Weg stellt. Sie bringt das Blut zum Verdampfen und erfuellt " \
87 "alles mit ihrer zerstoererischen, grausamen Hitze.", \
88 "Ploetzlich ist alles mit Feuer und Hitze erfuellt. Die Meere und " \
89 "Fluesse verdampfen und der Dampf treibt heiss ueber die Welt, um alles " \
90 "zu verbruehen, was sich nicht schuetzt!", \
91 "Von ueberall hoerst Du Schreie und Du erkennst panische Angst in den " \
92 "Augen der Eingeborenen. Elendig verenden sie in der Hitze zwischen Feuer " \
93 "und Lava. Dir wird uebel.", \
94 "Um Dich herum siehst Du nur brennende Truemmer. Die Welt scheint vor " \
95 "ihrem Untergang, denn ueberall oeffnet sich der Boden und spuckt Feuer. " \
96 "Heisses Magma quillt aus ihm heraus und mischt sich zischend mit dem Blut " \
97 "der Meere. Es gibt nun sicher kein Entrinnen mehr.", \
98 "Du kannst Dich kaum noch halten. Erdbeben erschuettern alles um Dich " \
99 "herum. Ueberall kannst Du nur noch Truemmer erkennen, wo einmal Haeuser " \
100 "standen. Alles ist erfuellt vom Geruch des Todes!" \
101 })
102
103static int restzeit;
104static string *ignorierer = ({});
105
106static int _query_restzeit() { return restzeit + find_call_out("NextStep"); }
107static string *_query_ignore() { return ignorierer; }
108
109public varargs void die(int poisondeath,int extern)
110{
111 object tp;
112 object room;
113
114 if (objectp(room=environment(this_object())))
115 if (!objectp(tp=this_player()))
116 tell_room(room,"Armageddon kratzt sich ratlos am Kopf.\n");
117 else
118 tell_room(room,
119 "Armageddon sagt: Ich weigere mich, einfach so zu sterben, "+
120 (tp->Name())+".\n");
121 return;
122}
123
124status access_check() {
125 //wer darf rebooten?
126
127 //in einem process_string() gar nicht.
128 if (process_call()) return(0);
129
130 //Master darf natuerlich. (->slow_shut_down(), vom Driver bei
131 //Speicherknappheit gerufen.)
132 if (previous_object() &&
133 previous_object()==find_object(__MASTER_OBJECT__))
134 return(1);
135
136 // rebooten duerfen ansonsten nur [W]+
137 if ( ELDER_SECURITY) {
138 return(1);
139 }
140
141 //andere nicht.
142 return(0);
143}
144
145public void create()
146{
147 ::create();
148
149 SetProp( P_NAME, "Armageddon" );
150 SetProp( P_GENDER, MALE );
151 SetProp( P_SHORT, "Armageddon, der Weltenvernichter" );
152 AddId( "armageddon" );
153 set_living_name( "armageddon" );
154 SetProp( P_ARTICLE, 0 );
155 SetProp( P_XP, 0 );
156 SetProp( P_NO_ATTACK,
157 "Armageddon grinst: Dein Ende kommt noch frueh genug!\n" );
158
159 if (!access_check()) {
160 destruct(this_object());
161 raise_error("Armageddon darf nur von W+ aktiviert werden!");
162 }
163}
164
165
166static varargs string text_time( int sec, int flag )
167{
168 string s;
169 int tage, stunden, minuten, sekunden;
170
171 sekunden = sec;
172 tage = sekunden / 86400;
173 stunden = (sekunden % 86400) / 3600;
174 minuten = (sekunden % 3600) / 60;
175 sekunden = sec % 60;
176 s = "";
177
178 if ( sec >= 86400 )
179 s += tage + " Tag" + (tage == 1 ? ", " : (flag ? "en, " : "e, "));
180
181 if ( sec >= 3600 )
182 s += stunden + " Stunde" + (stunden == 1 ? ", " : "n, ");
183
184 if ( sec >= 60 )
185 s += minuten + " Minute" + (minuten == 1 ? "" : "n");
186
187 s += (sec/60 ? " und " : " ") + sekunden + " Sekunde" +
188 (sekunden == 1 ? "" : "n");
189
190 return s;
191}
192
193
194public string _query_long()
195{
196 return break_string( "Dies ist Armageddon, der Weltenvernichter. Als Du "
197 "ihn ansiehst, blickt er auf und fluestert Dir zu: "
198 "Noch " + text_time(_query_restzeit()) +
199 " muessen vergehen, ehe ich die Welt vernichte.", 78 );
200}
201
202
203public string _query_short()
204{
205 return "Armageddon, der Weltenvernichter";
206}
207
208
209public int shut( mixed minutes )
210{
211 int a, b, c;
212
213 if (!access_check()) {
214 destruct(this_object());
215 raise_error("Armageddon darf nur von W+ aktiviert werden!");
216 return(-1); //never reached
217 }
218
219 a = b = c = 0;
220 move( "/gilden/abenteurer", M_GO );
221
222 if ( intp(minutes) )
223 c = minutes;
224 else if ( stringp(minutes) ){
225 if ( sscanf( minutes, "%d:%d:%d", a, b, c ) == 3 )
226 c += b * 60 + a * 24 * 60;
227 else if( sscanf( minutes, "%d:%d", b, c) == 2 )
228 c += b * 60;
229 else if( sscanf( minutes, "%d", c ) != 1 )
230 return -2;
231 }
232 else {
233 destruct(ME);
234 raise_error("Illegal argument type to shut()\n");
235 }
236
237 while ( remove_call_out("NextStep") >= 0 )
238 ;
239
240 restzeit = c * 60;
241 call_out( "NextStep", 0, restzeit );
242 return restzeit;
243}
244
245// Schickt die Meldung str an alle Spieler, die Armageddon nicht ignorieren
246// Flags: S_IGNORE - Shout kann von Spielern ignoriert werden.
247// S_PRESAY - Es wird ein "Armageddon ruft:" vorangestellt.
248static void SHOUT( string str, int flags )
249{
250 if (flags&S_PRESAY)
251 str = break_string(str, 78, "Armageddon ruft: ");
252 else
253 str = break_string(str, 78);
254
255 if (flags&S_IGNORE)
256 filter(
257 users()-filter_objects(users(),"TestIgnore",({"armageddon"}))
258 -map(ignorierer, #'find_player),
259 #'tell_object, str);
260 else
261 filter( users(), #'tell_object, str);
262}
263
264
265static void NextStep( int seconds )
266{
267 int neu;
268
269 if ( seconds <= 0 ){
270 SHOUT( "Ich starte das Spiel jetzt neu !", S_PRESAY);
271 shutdown("");
272 return;
273 }
274
275 if ( seconds <= 600 )
276 SHOUT( "Teile mir mit, wenn Du in den Laden gebracht werden willst!",
277 S_PRESAY|S_IGNORE);
278
279 if ( seconds > 2 * 86400 )
280 neu = seconds - 5 * 3600;
281 else if ( seconds > 4800 )
282 neu = seconds - 1800;
283 else
284 neu = seconds * 3 / 4 - 10;
285
286 restzeit = neu;
287 call_out( "NextStep", seconds-neu, neu );
288
289 SHOUT( "In " + text_time( seconds, 1 ) + " werde ich die Welt "
290 "zerstoeren und neu erschaffen!", S_PRESAY|S_IGNORE);
291
292 if ( neu < 900 && find_call_out("ArmasShout") == -1 )
293 call_out( "ArmasShout", random(60)+10 );
294}
295
296
297static void ArmasShout()
298{
299 int dauer;
300
301 dauer = _query_restzeit();
302 call_out( "ArmasShout", 40+random(40) );
303
304 if ( 701 < dauer )
305 SHOUT( messages1[ random(sizeof(messages1))], S_IGNORE);
306 else if ( 501 < dauer )
307 SHOUT( messages2[ random(sizeof(messages2))], S_IGNORE);
308 else if ( 251 < dauer )
309 SHOUT( messages3[ random(sizeof(messages3))], S_IGNORE);
310 else
311 SHOUT( messages4[ random(sizeof(messages4))], S_IGNORE);
312}
313
314
315public void catch_tell( string str )
316{
317 string who, what;
318 object ob;
319
320 if ( sscanf( str, "%s teilt Dir mit: %s", who, what ) != 2 ||
321 !this_player() )
322 return;
323
324 // Ein Spieler will fuer dieses Reboot ignoriert werden, oder
325 // das Ignoriere soll aufgehoben werden.
326 if (lower_case(what)[0..<2]=="ruhe"){
327 if (member(ignorierer, getuid(this_player()))>-1)
328 {
329 ignorierer -= ({ getuid(this_player()) });
330 tell_object( this_player(), break_string(
331 "Gut, ich notier's mir. Ab nun hast Du wieder am grossen Showdown "
332 "teil. Viel Spass dabei.\n", 78, "Armageddon teilt Dir mit: "));
333 } else {
334 ignorierer += ({ getuid(this_player()) });
335 tell_object( this_player(), break_string(
336 "Gut, ich notier's mir. Der Weltuntergang soll Dich beim Spielen "
337 "nicht weiter stoeren.\n", 78, "Armageddon teilt Dir mit: "));
338 }
339 return;
340 }
341
342 // In den Laden
343 if ( _query_restzeit() < 600 ){
344 this_player()->move( "/d/ebene/room/PortVain/laden", M_TPORT );
345 return;
346 }
347
348 tell_object( this_player(),
349 break_string( "Es ist noch zu frueh! Probier es 10 Minuten "
350 "vor dem Ende nochmal!\nIn " +
351 text_time( _query_restzeit(), 1 ) +
352 " ist es soweit!", 78,
353 "Armageddon teilt Dir mit: ", 1 ) );
354 return;
355}
356
357
358public varargs int remove()
359{
360 write( "Armageddon will nicht removed werden!\n" );
361 return 0;
362}
363
364
365public int do_damage( int dam, object enemy )
366{
367 return 0;
368}
369
370// Nicht jeder Magier darf Armageddon destructen.
371string NotifyDestruct(object caller) {
372 if( (caller!=this_object() && !ELDER_SECURITY) || process_call() ) {
373 return "Du darfst Armageddon nicht zerstoeren!\n";
374 }
375 return 0;
376}
377