blob: c563d9df5c47a907d7c989c972eb6f0b81456bba [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// players.c
4//
5// $Id: players.c 9551 2016-04-20 22:54:58Z Arathorn $
6#pragma strict_types
7#pragma save_types
8#pragma range_check
9#pragma no_clone
10#pragma pedantic
11
12#include <wizlevels.h>
13#include <ansi.h>
14#include <logging.h>
15#define NEED_PROTOTYPES
16#include <magier.h>
17#include <thing/properties.h>
18#include <thing/description.h>
19#include <living/comm.h>
20#include <player.h>
21#undef NEED_PROTOTYPES
22#include <properties.h>
23#include <moving.h>
24
25static mixed _query_localcmds()
26{
27 return ({({"zap","_zap",0,WIZARD_LVL}),
28 ({"verfolge","_verfolge",0,LEARNER_LVL}),
29 ({"trans","_trans",0,LEARNER_LVL}),
30 ({"peace","_frieden",0,LEARNER_LVL}),
31 ({"frieden","_frieden",0,LEARNER_LVL}),
32 ({"pwho","_pwho",0,WIZARD_LVL}),
33 ({"zwinge","_zwinge",0,WIZARD_LVL}),
34 ({"heal","_heile",0,WIZARD_LVL}),
35 ({"heil","_heile",1,WIZARD_LVL}),
36 ({"people","_people",0,LEARNER_LVL}),
37 ({"spieler","_spieler",0,WIZARD_LVL})});
38}
39
40// #######
41//################################ ZAP ##################################
42// #######
43
44private string _zap_message(string str, object obj)
45{
46 str=regreplace(str,"@@wer@@",(string)obj->name(WER,2),1);
47 str=regreplace(str,"@@wessen@@",(string)obj->name(WESSEN,2),1);
48 str=regreplace(str,"@@wem@@",(string)obj->name(WEM,2),1);
49 str=regreplace(str,"@@wen@@",(string)obj->name(WEN,2),1);
50 str=regreplace(str,"@@ich@@",name(WER,2),1);
51 return capitalize(str);
52}
53
54static int _zap(string str)
55{
56 object opfer;
57 string *message, dummy;
58 int spieler;
59
60 if (!str) return USAGE("zap <name>");
61 if (sscanf( str, "spieler %s", dummy ))
62 {
63 str = dummy;
64 spieler = 1;
65 }
66 if (opfer=present(str,environment()))
67 {
68 if ( !living(opfer) )
69 {
70 printf("%s ist doch gar kein Lebewesen!\n",capitalize(str) );
71 return 1;
72 }
73 if (query_once_interactive(opfer)&&!spieler )
74 {
75 printf( "Spieler kannst Du nur mit der Syntax 'zap spieler <name>' "
76 "toeten!\n" );
77 return 1;
78 }
79 else
80 if ( !query_once_interactive(opfer) && spieler )
81 {
82 printf( "Aber %s ist doch gar kein Spieler!\n",capitalize(str));
83 return 1;
84 }
85
86 message = QueryProp(P_ZAP_MSG);
87
88 if ( !pointerp(message) || sizeof(message) != 3 ){
89 tell_room(environment(),sprintf("%s beschwoert einen Blitz "
90 "vom Himmel.\n",capitalize(getuid())),({ this_object() }));
91 printf("Du toetest %s.\n",opfer->name( WEN,2));
92 }
93 else
94 {
95 printf(_zap_message(message[0],opfer));
96 tell_room(environment(),_zap_message(message[1],opfer),
97 ({this_player(),opfer}));
98 tell_object(opfer,_zap_message(message[2],opfer));
99 }
100
101 opfer->die();
102 return 1;
103 }
104 else{
105 printf("Sowas siehst Du hier nicht.\n");
106 return 1;
107 }
108}
109
110
111// ############
112//############################## VERFOLGE ################################
113// ############
114
115static int _verfolge(string str)
116{
117 // Wenn nichts eingegeben wurde, wird ver Verfolgungsmodus beendet, sofern
118 // er zuvor eingeschaltet war. Ansonsten wird eine Fehlermeldung
119 // ausgegeben.
120 if (!sizeof(str))
121 {
122 mixed *pur = Query(P_PURSUERS);
123 if ( pointerp(pur) && sizeof(pur) && objectp(pur[0]) )
124 {
125 pur[0]->RemovePursuer(this_object());
126 ReceiveMsg("Verfolgungsmodus abgeschaltet.", MT_NOTIFICATION);
127 }
128 else
129 {
130 ReceiveMsg("Du verfolgst doch ueberhaupt niemanden.", MT_NOTIFICATION);
131 }
132 return 1;
133 }
134 str=lower_case(str);
135
136 // match_living() erlaubt die Pruefung, ob die Angabe eindeutig war.
137 int|string lv = match_living(str);
138 if ( intp(lv) )
139 {
140 if ( lv == -2 )
141 ReceiveMsg("Kein solches Wesen gefunden.", MT_NOTIFICATION);
142 else
143 ReceiveMsg(sprintf("verfolge: '%s' ist nicht eindeutig.\n", str),
144 MT_NOTIFICATION);
145 return 1;
146 }
147
148 // Spieler zuerst auswaehlen, danach im Raum anwesende Lebewesen.
149 object ziel = find_player(lv) || present(lv, environment(this_player()));
150
151 // Wurde kein Lebewesen gefunden, wird das erste Element aus der Liste der
152 // Lebewesen dieses Namens gewaehlt, falls vorhanden. Nur Lebewesen mit
153 // Environment kommen in Frage, denn sonst gibt es keinen Raum, in den der
154 // neue Verfolger bewegt werden koennte.
155 if ( !objectp(ziel) ) {
156 object* eligible_livings = filter(find_livings(lv), #'environment);
157 if (sizeof(eligible_livings))
158 ziel = eligible_livings[0];
159 }
160
161 // Endlich etwas gefunden? Dann Verfolger eintragen und zum Ziel bewegen.
162 if ( objectp(ziel) )
163 {
164 if ( ziel == this_player() )
165 {
166 ReceiveMsg("Du kannst Dich nicht selbst verfolgen.", MT_NOTIFICATION);
167 }
168 else
169 {
170 ReceiveMsg(sprintf(
171 "Du verfolgst jetzt %s. [%s]", ziel->name(WEN), object_name(ziel)),
172 MT_NOTIFICATION, MA_MOVE);
173 ziel->AddPursuer(this_object());
174 ziel->TakeFollowers();
175 }
176 }
177 else
178 {
179 ReceiveMsg("Kein Wesen mit dem Namen '"+lv+"' gefunden, oder nur "
180 "solche ohne Environment.", MT_NOTIFICATION, 0, "verfolge: ");
181 }
182 return 1;
183}
184
185
186// #########
187//############################### TRANS #################################
188// #########
189
190static int _trans(string str)
191{
192 object living;
193
194 if (!sizeof(str))
195 return _notify_fail("Syntax: trans <spielername>\n"),0;
196 str=match_living(str,0);
197 if (intp(str))
198 switch (str)
199 {
200 case -1: write("Das war nicht eindeutig.\n"); return 1;
201 case -2: write("So ein Wesen gibt es nicht.\n"); return 1;
202 }
203 if(living=find_living(str))
204 {
205 if (living->move(object_name(environment()),
206 M_TPORT|M_NOCHECK)<=0)
207 {
208 printf("Teleportieren von %s fehlgeschlagen.\n",living->Name(WEM));
209 if (IS_LEARNER(living))
210 tell_object(living,sprintf("%s wollte Dich teleportieren, "
211 "hat aber versagt!\n",capitalize(getuid())));
212 return 1;
213 }
214 tell_object(living,sprintf(
215 "Ein seltsames Gefuehl ueberkommt Dich ...\n"
216 "Du verlierst die Orientierung ...\n"
217 +(QueryProp(P_INVIS)?"":"%s holt Dich zu sich.\n"),
218 capitalize(getuid())));
219 printf("%s wurde herbeizitiert.\n",living->Name(WER));
220 return 1;
221 }
222 printf("Das Lebewesen '%s' konnte nicht gefunden werden.\n",
223 capitalize(str));
224 return 1;
225}
226
227// ###########
228//############################## FRIEDEN #################################
229// ###########
230
231static int _frieden(string sname)
232{
233 object *enem,obj;
234 int i;
235 string him;
236
237 if (!sname)
238 {
239 enem=all_inventory(environment());
240 map_objects(enem,"StopHuntingMode");
241 tell_room(environment(),sprintf("%s stiftet Frieden.\n",capitalize(getuid())),
242 ({ this_object()}));
243 printf("Du stiftest Frieden.\n");
244 return 1;
245 }
246 else
247 {
248 if (!obj=find_living(sname))
249 return printf("Kein solches Lebewesen im Spiel.\n"),1;
250 him=(string)obj->name(WEM);
251 i=sizeof(enem=(object *)(((mixed *)obj->StopHuntingMode())[0]));
252 // Mistdriver ... object** waere richtig gewesen ... *seufz*
253 while(i--)
254 {
255 enem[i]->StopHuntFor(obj);
256 tell_object(obj,sprintf("%s beendet Deinen Kampf mit %s.\n",
257 capitalize(getuid()),enem[i]->Name(WEM)));
258 tell_object(enem[0],sprintf("%s beendet Deinen Kampf mit %s.\n",
259 capitalize(getuid()),him));
260 }
261 }
262 printf("%s und alle Gegner wurden befriedet.\n",obj->Name(WER));
263 return 1;
264}
265
266// ########
267//############################### PWHO ##################################
268// ########
269
270#if __VERSION__ < "3.2.9"
271private int _pwho_learner_test(object ob)
272{
273 return !IS_LEARNER(ob);
274}
275#endif
276
277static int _pwho()
278{
279 mixed* spieler, res, *hands;
280 int i;
281#if __VERSION__ < "3.2.9"
282 spieler = filter(users(),#'_pwho_learner_test);
283#else
284 spieler = filter(users(),(: return !IS_LEARNER($1); :));
285#endif
286 spieler = sort_array(spieler, function int (object a, object b)
287 { return a->QueryProp(P_LEVEL) > b->QueryProp(P_LEVEL); } );
288
289 res = "Lvl Name Erfahrung QP Int Str Dex Con WC "
290 "AC HANDS HP (max)\n"
291 "--------------------------------------------------------------"
292 "-----------------\n";
293 for (i=sizeof(spieler)-1; i>=0; i--)
294 res += sprintf("%3d %-12s %9d %5d %3d %3d %3d %3d %4d %4d %5d "
295 "%4d (%4d)\n",
296 spieler[i]->QueryProp(P_LEVEL),
297 capitalize(getuid(spieler[i])),
298 spieler[i]->QueryProp(P_XP),
299 spieler[i]->QueryProp(P_QP),
300 spieler[i]->QueryAttribute(A_INT),
301 spieler[i]->QueryAttribute(A_STR),
302 spieler[i]->QueryAttribute(A_DEX),
303 spieler[i]->QueryAttribute(A_CON),
304 spieler[i]->QueryProp(P_TOTAL_WC),
305 spieler[i]->QueryProp(P_TOTAL_AC),
306 (sizeof(hands=((int *)spieler[i]->QueryProp(P_HANDS)))?hands[1]:0),
307 spieler[i]->QueryProp(P_HP),
308 spieler[i]->QueryProp(P_MAX_HP));
309 More(res);
310 return 1;
311}
312
313// ##########
314//############################## ZWINGE #################################
315// ##########
316
317static int _zwinge(string str)
318{
319 object living;
320 string what, rest;
321 string living_name;
322
323 str = _unparsed_args();
324 if(!str|| sscanf( str, "%s %s", living_name, what ) != 2 )
325 return _notify_fail("Zwinge WEN zu WAS?\n"),0;
326 if( sscanf( what, "zu %s", rest ) == 1 ) what = rest;
327 if (!(living = find_living(living_name)))
328 return printf ("Ein Lebewesen namens '%s' konnte nicht gefunden werden!\n",
329 capitalize(living_name)),1;
330 if (living->command_me(what))
331 {
332 printf("Du zwingst %s zu \"%s\".\n",capitalize(living_name),what);
333 if (!IS_ARCH(this_object())&&getuid()!=(string)living->QueryProp(P_TESTPLAYER))
334 log_file(SHELLLOG("ZWINGE"),
335 sprintf("%s zwingt %s (%s) zu %s [%s]\n",
336 capitalize(getuid()),living->Name(),capitalize(getuid(living)),
337 what,dtime(time())));
338 }
339 else
340 write("Hat leider nicht geklappt!\n");
341 return 1;
342}
343
344// #########
345//############################### HEILE #################################
346// #########
347
348static int _heile(string name)
349{
350 object ob;
351 int lpv, mpv;
352
353 if (!name) return USAGE("heile <name>");
354 name = lower_case(name);
355 if ((!(ob = present(name,environment())))
356 ||!living(ob))
357 ob = find_living(name);
358 if (!ob)
359 {
360 printf("'%s' ist momentan nicht da.\n",capitalize(name));
361 return 1;
362 }
363 lpv = (int)ob->QueryProp(P_HP);
364 mpv = (int)ob->QueryProp(P_SP);
365 ob->heal_self(1000000);
366 if (!IS_LEARNER(ob) && (!ob->QueryProp(P_TESTPLAYER)||
367 (((string)ob->QueryProp(P_TESTPLAYER))[<5..<1]=="Gilde")))
368 log_file(SHELLLOG("HEAL"),
369 sprintf("%s heilt %s (%s) %s (LP: %d -> %d, MP: %d -> %d)\n",
370 capitalize(geteuid(this_player())),
371 call_other(ob,"name"), capitalize(geteuid(ob)),
372 dtime(time()), lpv, (int)ob->QueryProp(P_HP),
373 mpv,(int)ob->QueryProp(P_SP)));
374 tell_object(ob, QueryProp(P_NAME) + " heilt Dich.\n");
375 printf("Du heilst %s.\n",capitalize(name));
376 return 1;
377}
378
379// ##########
380//############################## PEOPLE #################################
381// ##########
382
383private string _people_filename(object obj)
384{
385 string str;
386 str=object_name(environment(obj));
387 if (!str) return 0;
388 if (str[0..2] == "/d/") return sprintf("+%s",str[3..<1]);
389 if (str[0..8] == "/players/") return sprintf("~%s",str[9..<1]);
390 return str;
391}
392
393static int _people()
394{
395 mixed *list, res;
396 int i,j, a;
397 string a_age,a_ipnum,a_name,a_level,a_idle,a_room,a_end, a_title;
398
399 switch(QueryProp("tty"))
400 {
401 case "vt100":
402 a_ipnum = ""; a_name = ANSI_BOLD;
403 a_level = ANSI_NORMAL; a_idle = ANSI_BLINK;
404 a_room = ANSI_NORMAL; a_end = ANSI_NORMAL;
405 a_title = ANSI_INVERS; a_age = ANSI_NORMAL;
406 break;
407 case "ansi":
408 a_ipnum = ANSI_BLUE; a_name = ANSI_BOLD;
409 a_level = ANSI_RED; a_idle = ANSI_BLACK+ANSI_BOLD;
410 a_room = ANSI_BOLD+ANSI_BLUE; a_end = ANSI_NORMAL;
411 a_title = ANSI_INVERS; a_age = ANSI_PURPLE;
412 break;
413 default:
414 a_title = a_ipnum = a_name = a_level = a_idle = a_room = a_end = "";
415 a_age = "";
416 }
417 list = sort_array(users(), function int (object a, object b) {
418 return query_ip_number(a)>query_ip_number(b);} );
419
420 j=sizeof(list);
421 a=0;res="";
422 for(i=0; i<sizeof(list); i++) {
423 string name_;
424 name_ = capitalize(list[i]->query_real_name()||"<logon>");
425 res += sprintf( "%s%-15s%s %s%-13s%s %s%3d%s %s %s %s%s%s%s %s%s\n",
426 a_ipnum, query_ip_number(list[i]),a_end,a_name,
427 (list[i]->QueryProp(P_INVIS)?"("+name_+")":name_),
428 a_end,a_level, MASTER->get_wiz_level(getuid(list[i])),
429 a_end,a_age,
430 time2string("%4x %0X",((int)list[i]->QueryProp(P_AGE))*2),
431 query_idle(list[i])>=300?(a++,(a_idle+"I")):" ",
432 a_end,
433 query_editing(list[i])?a_idle+"E"+a_end:" ",
434 query_input_pending(list[i])?a_idle+"M"+a_end:" ",
435 environment(list[i])?a_room+_people_filename(list[i]):"",
436 a_end);
437 }
438 if (a)
439 res = sprintf("%s%d Spieler anwesend (%d aktiv). %s%s\n",a_title,j,
440 (j-a),query_load_average(),a_end)+res;
441 else
442 res = sprintf("%s%d Spieler anwesend. %s%s\n",a_title,j,
443 query_load_average(),a_end)+res;
444 More(res);
445
446 return 1;
447}
448
449
450// ###########
451//############################## SPIELER #################################
452// ###########
453
454private string _spieler_time2string(int time)
455{
456 string ret;
457
458 ret="";
459 if (time>=86400)
460 {
461 ret+=time/86400+"d ";
462 time%=86400;
463 }
464 if(time<36000) ret+="0";
465 ret+=time/3600+":";
466 time%=3600;
467 if(time<600) ret+="0";
468 ret+=time/60+":";
469 time%=60;
470 if(time<10) ret+="0";
471 ret+=time+"";
472 return ret;
473}
474
475
476static int _spieler(string arg)
477{
478 string dummy,ip;
479 object *spieler,pl;
480 int i;
481
482 arg=_unparsed_args();
483 if(!sizeof(arg) || sscanf(arg,"aus ip %s",dummy)!=1)
484 return USAGE("spieler aus ip [von <spieler>|<ip>]");
485 arg=dummy;
486 if (sscanf(arg,"von %s",dummy)==1)
487 {
488 dummy=lower_case(dummy);
489 if (!(pl=find_player(dummy)))
490 return notify_fail(sprintf("Spieler '%s' konnte nicht gefunden "
491 "werden.\n",capitalize(dummy))),0;
492 ip=query_ip_number(pl);
493 }
494 else ip=arg;
495 ip=implode((explode(ip,".")-({""})+({"*","*","*","*"}))[0..3],".");
496if (catch(
497 spieler=filter(users(),
498 (: return sizeof(regexp(({query_ip_number($1)}),$2)); :),"^"+glob2regexp(ip)+"$")
499
500 ))
501 return printf("In der IP duerfen nur Zahlen(0-255), Punkte (.) und "
502 "Sterne (*) vorkommen.\n"),1;
503 if (!sizeof(spieler))
504 return printf("Es konnte kein Spieler mit der IP '%s' gefunden "
505 "werden.\n",ip),1;
506 arg=sprintf("\nFolgende Spieler haben die IP %s:\n"
507 "================================================================"
508 "===========\n"
509 "Name: Zweitie von: Eingeloggt: "
510 "Idle seit:\n"
511 "----------------------------------------------------------------"
512 "-----------\n",ip);
513 i=sizeof(spieler);
514 while(i--)
515 {
516 arg+=sprintf("%-11s %-17s %26s %-15s\n",
517 capitalize(getuid(spieler[i])),
518 ((dummy=(string)spieler[i]->QueryProp(P_SECOND))?
519 (sizeof((mixed *)call_other(master(),
520 "get_userinfo",dummy))?
521 capitalize(dummy):"*ungueltig*"):""),
522 dtime(spieler[i]->QueryProp(P_LAST_LOGIN)),
523 _spieler_time2string(query_idle(spieler[i])));
524 }
525 arg+="==============================================================="
526 "============\n\n";
527 More(arg);
528 return 1;
529}