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