blob: 8aed0f24281e9c7010c63ec406e91b8d07337506 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// corpse.c -- corpse standard object
4//
5// $Id: corpse.c 9391 2015-12-07 22:28:53Z Arathorn $
6
7// A corpse.
8//
9// Ekeltexte by Boing
10//
11// This is a decaying corpse. It is created automatically
12// when a player or monster dies.
13//
14// Erweiterung Raschaua:
15// - Kopieren von P_CLASS
16// - Teilweises aufessen
17#pragma strict_types
18#pragma save_types
19#pragma range_check
MG Mud User88f12472016-06-24 23:31:02 +020020
21//#define NEED_PROTOTYPES
22
Zesstra39d1d2b2020-09-28 23:53:04 +020023inherit "/std/container";
24nosave variables inherit "/std/channel_supervisor";
MG Mud User88f12472016-06-24 23:31:02 +020025
26#include <properties.h>
27#include <language.h>
28#include <defines.h>
29#include <moving.h>
30#include <wizlevels.h>
31#include <living/life.h>
32#include "/secure/scoremaster.h"
Zesstra72741252020-10-02 22:37:42 +020033#include "/p/daemon/channel.h"
MG Mud User88f12472016-06-24 23:31:02 +020034
35#define CORPSE_OBJ "/std/corpse.c"
36#define PILE_OBJ "/std/pile.c"
37
38nosave int _decay = 4;
39nosave string _name = "Unbekannt";
40nosave object moerder;
41private nosave int gespottet = 0;
42nosave int nahrung_gesamt = 1;
43nosave int nahrung_aktuell = 1;
44// Spielerleiche?
45private nosave status spielerleiche;
46
47void Identify( object ob );
48void do_decay();
49int QueryDecay();
50static int mampf( string str );
51static int spott(string str);
52void ChannelMessageJeer( mixed sender, string text, int flag );
53object _channel( object ob );
54void transform_into_pile();
55
Zesstra39d1d2b2020-09-28 23:53:04 +020056protected void create()
MG Mud User88f12472016-06-24 23:31:02 +020057{
58 if (object_name(ME) == __FILE__[0..<3]) {
59 set_next_reset(-1);
60 }
61 ::create();
62 if( clonep(this_object()) )
63 {
64 AddId(({ "leiche","\nleiche","rest","ueberrest"}));
65 SetProp( P_GENDER, FEMALE );
66 SetProp( P_NAME, "Leiche" );
67 SetProp( P_MATERIAL, ([ MAT_MISC_DEAD: 100 ]) );
68 SetProp( P_CORPSE_DECAY_TIME, 30 );
69 SetProp(P_NO_SCORE,1);
70 AddCmd(({"iss","verspeise"}),"mampf");
71 AddCmd("spotte","spott");
72 SetProp(P_ARTICLE, 1);
73 }
74 else
Zesstra39d1d2b2020-09-28 23:53:04 +020075 {
MG Mud User88f12472016-06-24 23:31:02 +020076 SetProp( P_ARTICLE, 0 );
Zesstra39d1d2b2020-09-28 23:53:04 +020077 ch_read_init_file();
Zesstra65d3c2b2020-10-02 21:14:24 +020078 SetProp(P_NAME, "Lars");
Zesstra39d1d2b2020-09-28 23:53:04 +020079 CHMASTER->join("moerder",this_object());
80 }
81}
82
Zesstra72741252020-10-02 22:37:42 +020083// Gerufen vom CHANNELD, um festzustellen, wer was auf -moerder tun darf.
Zesstradc9daae2020-10-02 20:57:37 +020084public int ch_check_access(string ch, object user, string cmd)
85{
Zesstra72741252020-10-02 22:37:42 +020086 // sich selber fuer alles erlauben (und dieses Objekt wird
87 // nur fuer -moerder gefragt).
Zesstradc9daae2020-10-02 20:57:37 +020088 if (user==this_object())
89 return 1;
Zesstra72741252020-10-02 22:37:42 +020090 // Der Moerder darf einmal verspotten, d.h. eine Meldunge auf der Ebene
91 // senden (das Kommando setzt gespottet dabei).
92 if (user==moerder && !gespottet && cmd == C_SEND)
93 return 1;
94 // Rest soll der Standard-SV entscheiden
Zesstradc9daae2020-10-02 20:57:37 +020095 return channel_supervisor::ch_check_access(ch, user, cmd);
96}
97
Zesstra39d1d2b2020-09-28 23:53:04 +020098public varargs string name(int casus,int demon)
99{
Zesstra39d1d2b2020-09-28 23:53:04 +0200100 return container::name(casus, demon);
101}
102
103public varargs string Name(int casus, int demon)
104{
Zesstra39d1d2b2020-09-28 23:53:04 +0200105 return container::Name(casus, demon);
MG Mud User88f12472016-06-24 23:31:02 +0200106}
107
108/* Damit die Leiche nicht voll wird... */
109int MayAddWeight( int weight ) { return 0; }
110int MayAddObject( object ob ) { return 1; }
111
112
113/* Humni, 2004-06-16: Entstatict */
114string _query_leichen_name()
115{ return _name; }
116
117/* Uebernehme den Namen von ob */
118void Identify( object ob )
119{
120 closure cl;
121 int i;
MG Mud User88f12472016-06-24 23:31:02 +0200122
123 spielerleiche = query_once_interactive(ob);
124 cl=symbol_function("QueryProp", ob);
Zesstra940e66d2020-03-05 19:58:48 +0100125 _name = ({string}) ob->name(WESSEN,0);
MG Mud User88f12472016-06-24 23:31:02 +0200126 SetProp( P_SHORT, "Die Leiche "+ _name );
127 SetProp( P_LONG, "Du siehst die sterblichen Ueberreste "+ _name + ".\n" );
128 _decay = 4;
bugfixd94d0932020-04-08 11:27:13 +0200129 SetProp( P_ORIG_NAME, ({string})ob->name(RAW) );
130 SetProp( P_PILE_NAME, ({string})ob->name(WEM) );
MG Mud User88f12472016-06-24 23:31:02 +0200131 AddId( "\nleiche "+ QueryProp(P_PILE_NAME) );
Zesstra940e66d2020-03-05 19:58:48 +0100132 SetProp( P_KILLER, ({<object|string>})funcall(cl, P_KILLER));
133 SetProp( P_ATTRIBUTES, ({mapping})funcall(cl, P_ATTRIBUTES));
134 SetProp( P_LAST_DAMTYPES, ({string*})funcall(cl, P_LAST_DAMTYPES) );
MG Mud User88f12472016-06-24 23:31:02 +0200135 SetProp( P_XP, to_int(funcall(cl, P_XP)) );
136 SetProp( P_SIZE, to_int(funcall(cl, P_SIZE)) );
137 SetProp( P_LEVEL, to_int(funcall(cl, P_LEVEL)) );
138 SetProp( P_MAX_HP, to_int(funcall(cl, P_MAX_HP)) );
139 SetProp( P_RACE, to_string(funcall(cl, P_RACE)) );
Zesstra940e66d2020-03-05 19:58:48 +0100140 SetProp( P_CLASS, ({string*})(funcall(cl, P_CLASS)) );
Bugfix2f15c562020-03-04 21:07:13 +0100141 SetProp( P_HANDS, ({<int|string|string*>*}) funcall(cl, P_HANDS) );
142 SetProp( P_WEIGHT, ({int}) funcall(cl, P_WEIGHT) );
MG Mud User88f12472016-06-24 23:31:02 +0200143 SetProp( P_ALIGN, to_int(funcall(cl, P_ALIGN)) );
144 SetProp( P_ORIG_FILE_NAME, object_name(ob) );
145 SetProp( P_HEAL, to_int(funcall(cl, P_HEAL)) );
146
147 // Saettigung der Leiche berechnen
148 // P_WEIGHT und P_SIZE werden verwendet, Mittel bilden
149 // Ein Saettigungspunkt fuer (konservative Rechnung):
150 // 5 kg
151 // 12 cm
152 // Beispiele:
153 // Mensch, 1.80 m gross, 75 kg schwer:
154 // 180/12 + 75/5 = 15 + 15 = 30
155 // Kuh, 1.50 m gross, 500 kg schwer:
156 // 150/12 + 500/5 = 12 + 100 = 112
157 // Drache, 5 m gross, 1500 kg schwer:
158 // 500/12 + 1500/5 = 41 + 300 = 341
159 nahrung_gesamt = QueryProp(P_WEIGHT)/5000 + QueryProp(P_SIZE)/12;
160 if (nahrung_gesamt <= 0)
161 nahrung_gesamt = 1;
162 nahrung_aktuell = nahrung_gesamt;
163
164 if ( intp(i = funcall(cl, P_CORPSE_DECAY_TIME)) && i > 2 )
165 SetProp( P_CORPSE_DECAY_TIME, i );
166
167 call_out( "do_decay", QueryProp(P_CORPSE_DECAY_TIME) );
168
169 if ( !query_once_interactive(ob) )
Zesstra940e66d2020-03-05 19:58:48 +0100170 moerder = ({object}) "/std/corpse"->_channel(ob);
MG Mud User88f12472016-06-24 23:31:02 +0200171}
172
173public int IsPlayerCorpse() { return spielerleiche; }
174
175public string QueryHealInfo()
176{
177 string info = "Solltest Du auf die aberwitzige Idee verfallen, diese "
178 "Leiche zu essen, ";
179 switch( QueryProp(P_HEAL) )
180 {
181 case -__INT_MAX__..-100:
182 info += "wird Dir das erheblichen Schaden zufuegen.";
183 break;
184 case -99..-11:
185 info += "ist das ausgesprochen ungesund fuer Dich.";
186 break;
187 case -10..-1:
188 info += "wird Dir sicher ein wenig uebel werden.";
189 break;
190 case 0..5:
191 info += "wird Dir nichts schlimmes passieren.";
192 break;
193 case 6..__INT_MAX__:
194 info += "koenntest Du sogar ein wenig geheilt werden.";
195 break;
196 }
197 return info;
198}
199
200private string knabber_text()
201{
202 string txt;
203 switch (nahrung_aktuell * 4 / nahrung_gesamt) {
204 case 4:
205 // Leiche noch komplett
206 txt = "";
207 break;
208 case 3:
209 // noch maximal 99%
210 txt = " mit Knabberspuren uebersaete";
211 break;
212 case 2:
213 // noch maximal 74%
214 txt = " angefressene";
215 break;
216 case 1:
217 // noch maximal 49%
218 txt = " schon halb aufgefutterte";
219 break;
220 default:
221 // noch maximal 24%
222 txt = " total abgenagte";
223 break;
224 }
225 return txt;
226}
227
228static string _query_short()
229{
230 string txt;
231 switch(_decay) {
232 case 4:
233 txt = "Die"+knabber_text()+" Leiche ";
234 break;
235 case 3:
236 txt = "Die bereits ziemlich stinkende"+knabber_text()+" Leiche ";
237 break;
238 case 2:
239 txt = "Die schimmelnde und halbverweste"+knabber_text()+" Leiche ";
240 break;
241 case 1:
242 txt = "Die verfaulten"+(sizeof(knabber_text()) ?
243 "n":"")+" Einzelteile ";
244 break;
245 }
246 txt += _name;
247 return txt;
248}
249
250void do_decay()
251{
252 _decay -= 1;
253
254 if ( _decay > 0 )
255 {
256 if ( (_decay == 2) && (QueryProp( P_HEAL ) >= -4) )
257 SetProp( P_HEAL, -4 );
258 call_out( "do_decay", QueryProp(P_CORPSE_DECAY_TIME) );
259 return;
260 }
261
262 transform_into_pile();
263 remove();
264}
265
266/* Haeh? Das move ins env macht der Master im prepare_destruct() doch eh? */
267/*
268varargs int remove()
269{
270 // units bekommen eine Chance zur Vereinigung...
271 filter_objects( all_inventory(ME), "move", environment(ME), M_SILENT );
272 return ::remove();
273}
274*/
275
276int QueryDecay() { return _decay; }
277
278static int * _query_nahrung()
279{ return ({nahrung_aktuell, nahrung_gesamt}); }
280
281private string mampf_heilung(int wieviel)
282{
283 int heal;
284 string msg;
285 heal = QueryProp(P_HEAL);
286 // Anteil an Gesamtheilung ausrechnen
287 heal = heal * wieviel / nahrung_gesamt;
288 if ( ( heal ) < 0 ) {
289 //
bugfixd94d0932020-04-08 11:27:13 +0200290 ({int})this_player()->do_damage( random(-heal), this_object() );
MG Mud User88f12472016-06-24 23:31:02 +0200291 msg = "Buah, diese Leiche war zweifellos nicht besonders gesund.\n";
292 } else {
bugfixd94d0932020-04-08 11:27:13 +0200293 ({int})this_player()->heal_self( random(heal) );
MG Mud User88f12472016-06-24 23:31:02 +0200294 msg = "Hmmm, lecker!\n";
295 }
296 return msg;
297}
298
299static int mampf( string str )
300{
301 int gegessen;
302
303 _notify_fail("Was moechtest Du essen?\n");
304
305 if ( !str || !id(str) )
306 return 0;
307
bugfixd94d0932020-04-08 11:27:13 +0200308 if (({int})this_player()->QueryProp(P_GHOST))
MG Mud User88f12472016-06-24 23:31:02 +0200309 {
Zesstra7c258092020-10-02 21:06:02 +0200310 _notify_fail("Das wuerde durch Dich hindurch fallen.\n");
311 return 0;
MG Mud User88f12472016-06-24 23:31:02 +0200312 }
313
314 // Das folgende ist nicht ganz sauber, da die Staerke bei eat_food nicht
315 // unbedingt dem Saettigungswert entsprechen muss (wegen FOOD_VALUE).
Zesstra940e66d2020-03-05 19:58:48 +0100316 gegessen = ({int}) this_player()->QueryProp(P_MAX_FOOD) -
317 ({int})this_player()->QueryProp(P_FOOD);
MG Mud User88f12472016-06-24 23:31:02 +0200318 if (gegessen <= 0) {
319 // Spieler ist proppenvoll, Meldung ausgeben
320 gegessen = 0;
321 write("Du bekommst von der Leiche nicht einen Bissen mehr runter.\n");
322 } else if (gegessen >= nahrung_aktuell) {
323 // spieler kann die gesamte Leiche essen, also entfernen.
bugfixd94d0932020-04-08 11:27:13 +0200324 ({int})this_player()->eat_food(nahrung_aktuell);
MG Mud User88f12472016-06-24 23:31:02 +0200325 // Verdammt. eat_food() kann TP umgebracht haben und im Falle eines NPC
326 // ist der dann weg.
327 if (objectp(this_player())) {
Zesstrad5b122d2018-08-01 21:18:20 +0200328 write(mampf_heilung(nahrung_aktuell));
329 say( sprintf("%s wird von %s voll Hingebung verspeist.\n",
MG Mud User88f12472016-06-24 23:31:02 +0200330 capitalize(name(WER)),
Zesstra940e66d2020-03-05 19:58:48 +0100331 ({string})this_player()->name(WEM)) );
MG Mud User88f12472016-06-24 23:31:02 +0200332 }
333 transform_into_pile();
334 remove();
335 } else {
336 // Auch teilweise Verspeisung ist moeglich, nahrung_aktuell anpassen
bugfixd94d0932020-04-08 11:27:13 +0200337 ({int})this_player()->eat_food(gegessen);
MG Mud User88f12472016-06-24 23:31:02 +0200338 if (objectp(this_player())) {
Zesstra7c258092020-10-02 21:06:02 +0200339 write(mampf_heilung(gegessen)+"Leider bist Du nicht in der Lage,"
MG Mud User88f12472016-06-24 23:31:02 +0200340 " alles aufzuessen.\n");
341 say( sprintf("%s knabbert an %s herum.\n",
Zesstra940e66d2020-03-05 19:58:48 +0100342 ({string})this_player()->name(),
MG Mud User88f12472016-06-24 23:31:02 +0200343 capitalize(name(WEM)) ) );
344 }
345 nahrung_aktuell -= gegessen;
346 }
347 return 1;
348}
349
350
351static int spott( string str )
352{
353 if ( !str )
354 return _notify_fail( "Syntax: spotte <text>\n" ), 0;
355
356 if ( !objectp(moerder) )
357 return _notify_fail( "Dieses Opfer ist den Spott nicht wert.\n" ), 0;
358
359 if ( PL != moerder )
360 return _notify_fail( "Du kannst nur Deine eigenen Opfer "
361 +"verspotten!\n" ), 0;
362
363 if ( gespottet )
364 return _notify_fail( "Du kannst Dein Opfer nur einmal verspotten!\n" )
365 , 0;
366
367 if ( _decay < 4 )
368 return _notify_fail( "Da solltest Du schon etwas spontaner sein.\n" )
369 , 0;
370
Zesstra940e66d2020-03-05 19:58:48 +0100371 str = ({string})PL->_unparsed_args();
Zesstra755c19b2020-10-02 23:13:41 +0200372
MG Mud User88f12472016-06-24 23:31:02 +0200373 switch ( str[0] )
Zesstra755c19b2020-10-02 23:13:41 +0200374 {
375 case ':':
376 ({void})"/std/corpse"->ChannelMessageJeer(PL, str[1..], MSG_EMOTE);
377 break;
378 case ';':
379 ({void})"/std/corpse"->ChannelMessageJeer(PL, str[1..], MSG_GEMOTE);
380 break;
381 default:
382 ({void})"/std/corpse"->ChannelMessageJeer(PL, str, MSG_SAY);
383 break;
384 }
385
MG Mud User88f12472016-06-24 23:31:02 +0200386 gespottet = 1;
387 write( "Du verspottest Dein totes Opfer.\n" );
Zesstra755c19b2020-10-02 23:13:41 +0200388
MG Mud User88f12472016-06-24 23:31:02 +0200389 return 1;
390}
391
Zesstra755c19b2020-10-02 23:13:41 +0200392// Wird in der Blueprint von den Clones (oder erbenden Objekten) gerufen, um
393// die Spott-Meldung von einem Spieler zu senden.
MG Mud User88f12472016-06-24 23:31:02 +0200394void ChannelMessageJeer( mixed sender, string text, int flag )
395{
396 if (member(inherit_list(previous_object()),CORPSE_OBJ)>-1)
Zesstra755c19b2020-10-02 23:13:41 +0200397 {
398 // Der Aufrufer hat, wenn es das originale spott() ist, geprueft, ob PL ==
399 // moerder ist. D.h. wir merken uns jetzt in moerder den PL. (wenn das
400 // jemand missbraucht, um beliebig auf -moerder zu senden, gibts Aerger)
401 moerder = PL;
402 ({int})CHMASTER->send( "Moerder", sender, text, flag );
403 }
MG Mud User88f12472016-06-24 23:31:02 +0200404}
405
MG Mud User88f12472016-06-24 23:31:02 +0200406// _channel() --
407#define KILL_MESSAGES \
408"Jetzt hat mich doch glatt %s erwischt :(", \
409"Wie soll das noch enden, %s?", \
410"Unglaublich, wie hat %s das geschafft?", \
411"RACHE! Bringt %s um!", \
412"%s ist staerker als ich dachte.", \
413"Wenn ich Dich erwische, %s!", \
414"%s hat mich ermordet!", \
415"Welche Schmach! %s hat mich besiegt.", \
416"Huetet Euch vor %s!", \
417"Warum hat mir niemand gegen %s geholfen?", \
418"%s, Du Monsterschaender!", \
419"Monster aller Regionen, vereinigt Euch gegen %s!", \
420"Danke, %s, Du hast mich von dieser schrecklichen, " \
421"sterblichen Huelle befreit.", \
422"%s? Ich bin dann jetzt weg.", \
423"Macht Euch keine Muehe, %s hat mich mal kurz zu " \
424"Gevatter Tod geschickt.", \
425"Oh nein, %s hat mich schon wieder kaltgemacht!", \
426"Sheriff! Verhafte %s!", \
427"Hilfe! Diebe! Moerder! Halsabschneider! %s!", \
428"Wieder mal an %s gestorben, find ich albern!", \
429"%s, probier das bei Anne!", \
430"Und wieder ein Drittel Erfahrung weg wegen %s...", \
431"Oh waer ich doch ein Spieler, dann duerfte mich "\
432"%s nicht mehr toeten!", \
433"Wenn Du das noch oefter machst, %s, dann spiele "\
434"ich hier nicht mehr!", \
435"%s, wieso redet der Kerl hier in Grossbuchstaben "\
436"zu mir? CAPS-LOCK kaputt?", \
437"%s ist schuld!",\
438"So schaff ich's wohl nie, Seher zu werden, %s :(",\
439"Musste das WIRKLICH sein, %s?",\
440"Wuenscht mir ne kurze Todessequenz, ich hab sie "\
441"%s zu verdanken...",\
442"Naechstes Mal bring mir lieber Post statt mich "\
443"zu ermorden, %s!",\
444"%s, wieso sagt der Typ: KOMM MIT MIR, STERBLICHER?",\
445"Ich glaub, jetzt kenne ich ALLE Todessequenzen, %s!",\
446"Was, %s hat mir WIE VIELE Lebenspunkte abgezogen???",\
447"Verdammt, %s wollte nicht sterben...",\
448"Tod den Monsterschaendern! Straft %s!",\
449"Naechstes Mal werde ICH siegen, %s!",\
450"Findest Du das fair, %s?",\
451"Das war ein gemeiner Tiefschlag, %s!",\
452"Wenn ich mal gross bin, zahl ich Dir das alles "\
453"heim, %s!",\
454"ALAAAAAARM! %s IST AUSGEBROCHEN!",\
455"Ein Koenigreich fuer den, der mir den Kopf von "\
456"%s bringt!",\
457"Suche Killer, zahle gut, Zielperson %s.",\
458"Das sag ich alles Boing, %s!",\
459"Das sag ich alles Rumata, %s!",\
460"Das sag ich alles Jof, %s!",\
461"Das sag ich alles dem Sheriff, %s!",\
462"Komm Du mir nur wieder, %s!",\
463"Ich fordere Revanche, %s!",\
464"Sheriff! Unternimm was gegen %s!",\
465"%s, wer hat DICH denn eingeladen?",\
466"NAECHSTES MAL NEHM ICH DICH AUCH MIT, %s!",\
467"Haetten wir das nicht ausdiskutieren koennen, %s?",\
468"Dich merk ich mir, %s!",\
469"Na prima, schon wieder dieser dunkle Typ! Und "\
470"alles nur wegen %s.",\
471"Hallo? Hat jemand meinen Koerper gesehen? Muesste "\
472"irgendwo bei %s liegen!",\
473"%s, waer jetzt nicht eigentlich Vorlesung?",\
474"Lern lieber, statt unschuldige Monster zu er"\
475"morden, %s!",\
476"Ohne dieses Lag haette mich %s nicht umgebracht!",\
477"In spaetestens einer Stunde komme ich wieder, %s!",\
478"Na warte %s, beim naechsten Mal trete ich Dir "\
479"kraeftig in den Gedan-Bereich!",\
480"SCHIEBUNG, der letzte Schlag von %s war nicht "\
481"regelgerecht!",\
482"Lieber eine H2O-Vergiftung, als von %s ermordet "\
483"zu werden!",\
484"Die Ehre werd ich %s nicht antun, und hier "\
485"herumposaunen, wer mich umgenietet hat!",\
486"Is mir doch egal %s, ich glaube an "\
487"die Wiedergeburt!",\
488"Aber vorsicht, %s isch kuuul maen!",\
489"Ok, %s, Du wirst von meiner Erwarteliste gestrichen!",\
490"Das naechste Mal sieht man unsere beiden Namen auf [Tod:], %s!",\
491"Magier zu mir, hier ist ein Bug: %s ist immer noch nicht tot!",\
492"Morgen frueh um halb sechs in der Arena, %s! Ich hab die Wahl der Waffen.",\
493"%s ist schlimmer als das Mensaessen. Absolut toedlich.",\
494"Mist, meine Vorsicht hat versagt! Und das bei %s!",\
495"%s, die Hydra ist mir lieber...",\
496"So, meine Ignoriereliste ist schon wieder um einen Namen laenger, %s."
497
498#define KILL_MESSAGES2 \
499"Feierabend! Danke, %s!",\
500"Toll! GENAU das hab ich jetzt gebraucht! Super, %s! :(",\
501"Schon wieder ein Tag versaut wegen %s!",\
502"Ihr sagt, ICH sei ein Monster? Ihr kennt %s nicht!!!",\
503"Sperrt %s mal in's Polargebiet! Gaebe ein gutes Untier ab...",\
504"Freiheit fuer Nicht-Spieler! Vernichtet %s!",\
505"Merlin, mach %s zum Magier!",\
506"%s ist NICHT zu meiner Beerdigung eingeladen!",\
507"Ich hab keine Angst vor Dir, %s!",\
508"%s ist doof und stinkt!",\
509"Moegest Du im Lag verrotten, %s!",\
510"%s wird gleich das Spiel verlassen, um meiner Rache zu entgehen!",\
511"Der Todestag von %s wird fuer mich ein Feiertag sein!",\
512"%s ist ein Metzelskript, ich hab's genau gesehen!", \
513"Waer ich Tanjian, haettest Du das nicht geschafft, %s!", \
514"Das naechste Mal komme ich als Kaempfer wieder, %s!", \
515"Ich lass' mich aufwerten und werde Zauberer, %s!", \
516"Gildenbalance! %s ist viel zu stark!", \
517"Jetzt ist mir das Kleingeld zum Tanken ausgegangen, %s...", \
518"%s hat ein Zap-Tool!", \
519"%s, Du <zensiert>!", \
520"%s, das ist doch Hullepanz. (c) Catweazle", \
521"Bald bin ich SuperSeher, %s!", \
522"Mit Dir 'piel ich nich' mehr, %s, Du hast in mein Foermssen depinkelt!", \
523"Verdammt, %s muss mir den Feenring geklaut haben...", \
524"Nie ist ein Kleriker in der Naehe, wenn man ihn braucht, %s...", \
525"Menno, %s, wo war hier noch mal die Heilstelle?", \
526"Hoffentlich werde ich naechstes Mal als Kuh wiedergeboren, %s...", \
527"Wenn Du sonst noch Probleme hast, %s, geh' zu Marvin und red' " \
528"mit ihm darueber.", \
529"Du, %s, Gewalt ist keine Loesung, lass uns darueber diskutieren.", \
530"Das naechste Mal zeig' ich Dir meine Mateteesammlung, %s.", \
531"%s eunt domum!", \
532"%s, ist es so kalt hier oder bin ich das?", \
533"Ich war schon wieder zur falschen Zeit am falschen Ort, %s...", \
534"Danke, %s. Im Namen des Mondes werde ich Dich bestrafen!", \
535"Das war mal wieder ein Schuss in den Ofen, %s...", \
536"Kannst Du das mit Deinem Gewissen vereinbaren, %s?", \
537"Und Kandri sprach: Mein ist die Rache, %s!", \
538"%s, Du haettest meine Leiche nicht auch noch schaenden muessen...", \
539"%s, ich kann so nicht arbeiten!", \
540"%s, ich geb' Dir mal 2 Muenzen, dann kannst Du Deine Sorgen " \
541"jemand anderem erzaehlen...", \
542"Manchmal verspeist Du den Baer, %s, manchmal verspeist " \
543"der Baer Dich...", \
544"Das naechste Mal betrittst _Du_ die Welt des Schmerzes, %s!", \
545"Wenn ich wiederkomme, %s, werde ich erst Dich toeten, dann " \
546"Deinen Partner, dann Deine Brueder und Schwestern und jeden " \
547"der Dich kennt!", \
548"Oh nein, %s! Schon wieder diese ewig lange Todessequenz mit der " \
549"Drachenschule!", \
550"%s, wo bekomme ich jetzt einen neuen Koerper her?", \
551"Lass Dir meine Leiche schmecken, %s.", \
552"Haeh?", \
553"Ja, aber wieso das denn? Och menno, %s!", \
554"So ein Mist, %s, ich hatte 'nen Disconnect...", \
555"*winkewinke*, %s!", \
556"Heute ist nicht alle Tage, ich komm' wieder, keine Frage.", \
557"Lass das, %s!", \
558"Niemand! Niemand nennt mich eine feige Sau, %s!", \
559"Da hab' ich jetzt wohl verloren, %s...", \
560"%s, ich kann nicht metzeln, ich kann nur sterben...", \
561"Hattest Du ueberhaupt einen Termin, %s?", \
562"Du warst gar nicht an der Reihe, %s!", \
563"Aetsch, %s, der Kill zaehlt nicht!", \
564"Jetzt noch mal mit Gefuehl, %s.", \
565"Tschuess erstmal, %s.", \
566"Ich weiss nicht ob Du es gemerkt hast, %s, aber " \
567"ich bin schon tot...", \
568"%s, ich haette nicht gedacht, dass ich noch mal sterbe " \
569"bevor Taramis angeschlossen wird...", \
570"Ich wollte sowieso grade gehen, %s.", \
571"Shit happens, %s.", \
572"Dazu faellt mir jetzt nix mehr ein, %s."
573
574#define KILL_MESSAGES3 \
575"Was heisst denn \"Dein Teddy knuddelt Dich ein letztes Mal\", %s?", \
576"Ich bin beeindruckt, %s.", \
577"Ok, Dein Gesicht merke ich mir, %s!", \
578"Kaum da, haut mich %s schon wieder tot... *grummel*", \
579"Ich werde Dich verfolgen, %s! Ich werde in Deine Traeume eindringen " \
580"und Dich in den Wahnsinn treiben! Du wirst diesen Tag noch verfluchen!", \
581"Ich geh ja schon, %s.", \
582"Auf den ersten Blick sieht %s gar nicht so gefaehrlich aus.", \
583"Von %s besiegt - wie peinlich.", \
584"Mist. Einmal nicht aufgepasst, schon wird man von %s ermordet.", \
585"Das war ein Glueckstreffer, %s!", \
586"Hah, das ist doch nur eine Fleischwunde! Gibst Du etwa schon auf, %s?", \
587"%s macht gerade eine destruktive Phase durch.", \
588"Zum Glueck ist das ja nur ein Spiel, %s. Sonst waere ich jetzt wirklich " \
589"boese.", \
590"Begrabe mich wenigstens anstaendig, %s.", \
591"Hm, die Flatrate brauch' ich dann wohl doch nicht, %s.", \
592"Na warte, %s! Zur Strafe werde ich gleich das Mud crashen!", \
593"Ich sollte nicht mehr soviel mudden. Dann muesste ich mich auch nicht mehr " \
594"ueber %s aergern.", \
595"Auf am Boden Liegende einzuschlagen! Schaem Dich, %s!", \
596"Einigen wir uns auf unentschieden, %s?", \
597"Ich sagte doch \"Ich ergebe mich!\", %s.", \
598"Aeh, %s, koennte das unter uns bleiben? Ich habe schliesslich einen " \
599"Ruf zu verlieren...", \
600"Du bist vielleicht staerker, %s, aber dafuer bin ich schoener.", \
601"Die Rechnung fuer die Behandlung meiner Minderwertigkeitskomplexe geht " \
602"an %s.", \
603"Ab und zu muss man %s ja gewinnen lassen, sonst gibt es wieder Traenen.", \
604"Bis eben war mir %s noch sympathisch.", \
605"Geht's Dir jetzt besser, %s?", \
606"Macht kaputt, was mich kaputt macht! Toetet %s!", \
607"Beim naechsten Mal mach' ich es Dir nicht mehr so einfach, %s!", \
608"Weisst Du, %s, ich habe nur verloren, weil Du... aeh, weil ich... " \
609"aeh... weil Du gewonnen hast.", \
610"Jo, immer feste druff, %s. Ist ja nur ein dummer NPC. *grummel*", \
611"Ich muss sagen, %s kann feste schlagen.", \
612"Also %s! Kommst hier rein, haust mich um und tust dann so, als sei nichts " \
613"gewesen...", \
614"In welcher Gilde konnte man nochmal \"befriede\" lernen, %s?", \
615"Tja, %s, aus diesem Kampf bist Du wohl nur als Vorletzter hervorgegangen" \
616"...", \
617"Vorsicht, %s greift immer von hinten an!", \
618"Was meint %s mit \"Sparringspartner\"?", \
619"Ich habe mir bei Dir nur deshalb keine Muehe gegeben, %s, weil Du eh nicht " \
620"stupst.", \
621"Huch, ich bin ja schon wieder auf -Moerder!", \
622"Ich spuck' Dir in's Auge und blende Dich, %s!", \
623"Huch, wo seid ihr alle hin?", \
624"Wer war das?", \
625"Moegest Du in interessanten Zeiten leben, %s.", \
626"Ich sehe was, was Du nicht siehst, %s, und es ist... schwarz.", \
627"Hey Maedels! Ratet, wen ich gerade getroffen habe!", \
628"%s?", \
629"Noch einmal sowas, %s, und ich lasse Deine Gilde abwerten. Ich kann das!", \
630"Was bedeutet 'Jemand beschwoert Dein Bild herauf.'? Warst Du das, %s?"
631
632private string *moerder_msgs = ({KILL_MESSAGES, KILL_MESSAGES2, KILL_MESSAGES3,
633"Sterben ist schoen, Sterben ist toll - Ach waer ich wie ein Kaempfer voll!",
634"Lauschige Nacht - ich geh mir die Sterne anschauen. Bis spaeter!",
635"Echt %s, das war 0815, keine Kreativitaet beim Toeten!",
636"%s, Du kannst ja gar ni... Verdammt!",
637"Kaempfer, Zauberer, Tanjian, alles Luschen! Ich werde Abenteurer, da ist "
638 "wenigstens Thrill!",
639"Toeten, Toeten, Toeten. Ist das alles, was Du kannst, %s?",
640"Ach geh doch Bluemchen pfluecken %s!",
641"Mein Tod war KEIN FP %s... HA!",
642"Lars gibt mir nen Whisky, wenn ich komme. Und Dir?",
643"Geh lernen, Depp!",
644"Auf der naechsten Mud-Party haut Dich mein Magier zurueck!",
645"Lass gut sein, tat eh nicht weh!",
646"Ich lass Dich von Zook abhaengen, %s!",
647"Koennen wir naechstes Mal nicht lieber einen trinken gehen, %s?",
648"Verdammt, meine neue Gilde ist ja noch gar nicht angeschlossen!",
649"Yohoho und ne Buddel voll Rum!",
650"Beim Kartenspiel haettest Du keine Chance gehabt %s!",
651"%s, Du hast echt keine Ahnung von stilvollem Metzeln...",
652"Was muss ich noch tun fuer Deinen Aufstieg, %s? *seufz*",
653"EK-Poser!",
654"Leistung ist was anderes, %s!",
655"Lass mich leeeeeeb... Arrrrggggh!",
656"Hast Du sonst nix in der Drachenschule gelernt, %s?",
657"Und wer kuemmert sich jetzt um meine Haustiere, %s?",
658"Ich musste sterben, Du willst mich nur beerben. Ich gehe "
659 "mit Stil, Du findest nicht viel.",
660"Ich habe nun mehr Tode als Du, %s. Topp mich, wenn Du kannst!",
661"Ok, dann geh ich halt WOW spielen.",
662"Toll, freut sich der Naechste. Wieder ne Todesfolge, %s.",
663"Du gucktest so traurig, %s, ich machte Dir meinen Tod zum Geschenk. "
664 "Sollst ja auch mal 'n Erfolgserlebnis haben!",
665"Nun reiche ich den letzten Becher, trinke den Wein, erkenne Dein Sein.",
666"%s hat nicht einmal getroffen. Ich habe mich wortwoertlich totgelacht.",
667"Lass mich nachdenken, %s. Ich starb fuer nen EK?",
668"Ich kann nicht glauben, dass das gerade passiert ist!",
669"Du Suender. Du sollst _nicht_ toeten!",
670"%s, mein Testament steckt im rechten Schuh!",
671"Sterben und sterben lassen, mein Freund. Wir sehen uns wieder!",
672"Und ich sag noch, %s... Das ist KEINE Schwertscheide... Aber Du musst "
673 "ja alles selbst ausprobieren.",
674"Soll das jetzt alles gewesen sein, %s?",
675"In meinem Code ist ein Fehler und gleich gibt's 'nen Crash.",
676"Ach, auch egal, %s. Ist eh gleich Schichtwechsel.",
677"Jofverdammt... warst Du gut, %s!",
678"Duelle von Killern enden meist fuer einen toedlich und das wirst "
679 "Du s... Argh!",
680"Bist Du sicher, dass Du den EK bekommen hast, %s?",
681"Danke %s! Weisst Du, ich hatte mit Zook gewettet, wer mich "
682 "toetet. Und ich habe eine Wiedergeburt gewonnen!",
683"Nun bin ich sicher vor Dir, %s!",
684"Ich mache jetzt Urlaub und habe Zook gebeten, meinen Reset "
685 "um einen Monat zu verschieben. Gluecklich, %s?",
686});
687
688
689int _query_kma() { return sizeof(moerder_msgs); }
690
MG Mud User88f12472016-06-24 23:31:02 +0200691object _channel( object ob )
692{
Arathornb3051452021-05-13 21:13:03 +0200693 int m_FMM, m_HP, m_WC, m_AC;
MG Mud User88f12472016-06-24 23:31:02 +0200694 object rueck;
695
696 if (member(inherit_list(previous_object()),CORPSE_OBJ)>-1)
Zesstra7c258092020-10-02 21:06:02 +0200697 {
698 string killer;
699 int i, x, y, z, nr;
700 closure m_q, s_q;
701
702 while( previous_object(i) &&
703 !query_once_interactive(previous_object(i)) )
704 i++;
705
706 if( !previous_object(i) || IS_LEARNER(previous_object(i)) )
707 return rueck;
708
709 killer = ({string}) previous_object(i)->name();
710
711 if ( lower_case(killer) != getuid(previous_object(i)) )
712 killer = capitalize(getuid(previous_object(i)));
713
714 m_q = symbol_function( "QueryProp", ob ); // Monster
715 s_q = symbol_function( "QueryProp", previous_object(i) ); // Spieler
716
717 if ( (m_FMM = ({int}) funcall( m_q, P_FORCE_MURDER_MSG )) >= 0 )
Zesstra4cfedc02020-10-02 21:08:04 +0200718 if ( (m_FMM > 0) ||
719 (nr = (random(100) >= 99) ? 1 : 0 ) ||
720 (nr = ((x = (m_HP = ({int}) funcall( m_q, P_MAX_HP )) *
Zesstra7c258092020-10-02 21:06:02 +0200721 ((m_WC = ({int}) funcall( m_q, P_TOTAL_WC )) +
722 (m_AC = ({int}) funcall( m_q, P_TOTAL_AC ))))
723 > 200000) ? 2 : 0) ||
724 (nr = (((y = m_HP * (m_WC + m_AC)) >
Arathornb3051452021-05-13 21:13:03 +0200725 (z = 5 * (({int}) funcall( s_q, P_MAX_HP )) *
726 ((({int}) funcall( s_q, P_TOTAL_WC )) +
727 (({int}) funcall( s_q, P_TOTAL_AC )))))
Zesstra7c258092020-10-02 21:06:02 +0200728 ? 3 : 0)))
MG Mud User88f12472016-06-24 23:31:02 +0200729 {
Zesstra7c258092020-10-02 21:06:02 +0200730 SetProp( P_NAME, "Geist "+({string}) ob->name(WESSEN, 0) );
MG Mud User88f12472016-06-24 23:31:02 +0200731
Arathorn5587e5d2020-11-14 14:30:40 +0100732 string|closure msg = ({string|closure}) ob->QueryProp(P_MURDER_MSG);
733 if (!msg)
Zesstra7c258092020-10-02 21:06:02 +0200734 msg = moerder_msgs[random(sizeof(moerder_msgs))];
MG Mud User88f12472016-06-24 23:31:02 +0200735
Zesstra7c258092020-10-02 21:06:02 +0200736 if ( stringp(msg) )
737 msg = sprintf( msg, killer || "Moerder" );
MG Mud User88f12472016-06-24 23:31:02 +0200738
Zesstra7c258092020-10-02 21:06:02 +0200739 ({int})CHMASTER->send( "Moerder", this_object(), funcall(msg) );
Zesstra3775d0f2020-10-02 21:11:37 +0200740 // Name wieder auf Lars stellen fuer SV-Funktionalitaet.
741 SetProp(P_NAME, "Lars");
Zesstra7c258092020-10-02 21:06:02 +0200742 rueck = previous_object(i);
MG Mud User88f12472016-06-24 23:31:02 +0200743 }
Zesstra7c258092020-10-02 21:06:02 +0200744 log_file( "moerder.log",
745 sprintf("MON(%O) COND(%d) NPC(%d), DIFF(%d,%d)\n",
746 ob, nr, x, y, z) );
747 }
MG Mud User88f12472016-06-24 23:31:02 +0200748 return rueck;
749}
750
Zesstra7c258092020-10-02 21:06:02 +0200751void transform_into_pile()
752{
753 if( ({int})environment()->QueryProp(P_PREVENT_PILE) ) return;
754 object* inv = all_inventory();
755 if( sizeof(inv)<2 ) return;
756 object p = clone_object(PILE_OBJ);
757 filter_objects( inv, "move", p, M_SILENT | M_NOCHECK );
758 ({int})p->move( environment(), M_SILENT | M_NOCHECK );
MG Mud User88f12472016-06-24 23:31:02 +0200759}
Arathorn0d093f62018-01-09 22:08:29 +0100760
761// Verhindert die Zerstoerung im reset() von Containern, die mit
762// remove_multiple() nach identischen Objekten suchen, um Muell zu
763// reduzieren. Das ist aber nur dann sinnvoll, wenn nach dem Zerstoeren
764// nicht mehr Muell rumliegt als vorher, daher geben wir 0 zurueck, wenn
765// die Leiche mehr als ein Objekt enthaelt. Weiterhin raeumt sich die Leiche
766// im Lauf der Zeit selber auf/weg.
767// Objekte, die 0 zurueckgeben, werden in remove_multiple() uebersprungen.
768public string description_id()
769{
770 if ( sizeof(all_inventory(this_object())) > 1 )
771 {
772 return 0;
773 }
774 return ::description_id();
775}