diff --git a/secure/scoremaster.c b/secure/scoremaster.c
new file mode 100644
index 0000000..576a4b9
--- /dev/null
+++ b/secure/scoremaster.c
@@ -0,0 +1,1465 @@
+// MorgenGrauen MUDlib
+//
+// scoremaster.c - Verwaltung der eindeutigen Nummernvergabe fuer NPCs und
+//       MiniQuests sowie der Stufenpunkte, die sie geben  
+//
+// $Id: scoremaster.c 9170 2015-03-05 20:18:54Z Zesstra $
+#pragma strict_types
+#pragma no_clone
+#pragma no_shadow
+#pragma no_inherit
+#pragma verbose_errors
+#pragma combine_strings
+#pragma pedantic
+//#pragma range_check
+#pragma warn_deprecated
+
+#include "/secure/scoremaster.h"
+#include "/secure/wizlevels.h"
+#include <properties.h>
+#include <files.h>
+
+#define ZDEBUG(x) if (find_player("zesstra")) \
+  tell_object(find_player("zesstra"),sprintf("SCM: %s\n",x))
+
+// hoechste vergebene Nr.
+private int lastNum;
+
+// Liste alle EKs: ([obname: num; score; killcount])
+private mapping npcs = m_allocate(0,3);
+
+// Liste von Spielernamen-Wert-Paaren, die im Reset abgearbeitet wird:
+// ([plname: ({wert1, wert2, wert3, ...}) ]) 
+// wert > 0 bedeutet setzen des entsprechenden EKs, < 0 bedeutet loeschen.
+private mapping to_change = ([]);
+
+// Liste der EK-Tips: ([obname: Spruch])
+private mapping tipList = ([]);
+
+// Bit-Nr., die (wieder) vergeben werden duerfen.
+private int *free_num = ({});
+
+// zu entfernende EKs, Liste Bitnummern, also ints
+private int *to_be_removed = ({});
+
+// Liste von temporaeren EKs, die noch nicht bestaetigt wurden:
+// ([obname: ({plname1, plname2}) ])
+private mapping unconfirmed_scores = ([]);
+
+// alle Spieler kriegen diesen 
+// Nach Nr. sortierte NPC-Liste: ([num: key; score])
+private nosave mapping by_num = m_allocate(0,2);
+
+// Cache fuer EKs von Spielern: ([plname: scoresumme])
+private nosave mapping users_ek = ([]);
+
+// bitstring, der alle aktiven EKs als gesetztes Bit enthaelt.
+private nosave string active_eks="";
+
+// Prototypen
+public mapping getFreeEKsForPlayer(object player);
+public int addTip(mixed key,string tip);
+public int changeTip(mixed key,string tip);
+public int removeTip(mixed key);
+private string getTipFromList(mixed key);
+public string getTip(mixed key);
+
+public void CheckNPCs(int num);
+public void check_all_player(mapping allplayer);
+public varargs int DumpNPCs(int sortkey);
+
+private void make_num(string key, int num, int score) {
+  by_num += ([ num : key; score ]);
+  // fuer aktive EKs, die also einen Scorewert > 0 haben, wird das jeweilige
+  // Bit gesetzt. Wird spaeter zum Ausfiltern inaktiver EKs aus den Bitstrings
+  // in den Spieler gebraucht.
+  if (score>0 && !member(unconfirmed_scores,num))
+    active_eks = set_bit(active_eks, num);
+}
+
+private int allowed()
+{
+  if (previous_object() && geteuid(previous_object())==ROOTID)
+    return 1;
+  if (!process_call() && previous_object() && this_interactive() && ARCH_SECURITY)
+    return 1;
+  return 0;
+}
+
+protected void create()
+{
+  seteuid(getuid());
+  if (!restore_object(SCORESAVEFILE))
+  {
+    lastNum=0;
+    npcs=m_allocate(0,3);
+    to_change=m_allocate(0,1);
+    tipList=([]);
+  }
+  npcs-=([0]);
+  walk_mapping(npcs, #'make_num);
+}
+
+public int ClearUsersEKCache()
+{
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  users_ek = ([]);
+  return 1;
+}
+
+public mixed QueryUsersEKCache()
+{
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  return users_ek;
+}
+
+public mixed Query_free_num()
+{
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  return free_num;
+}
+
+public mixed Add_free_num(int what)
+{
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!what || !intp(what) || by_num[what])
+    return SCORE_INVALID_ARG;
+  if (member(free_num,what)==-1)
+    free_num+=({what});
+  save_object(SCORESAVEFILE);
+  write_file(SCORELOGFILE,sprintf("ADDFREENUM: %s %5d (%s, %O)\n",     
+  strftime("%d%m%Y-%T",time()),what,
+  geteuid(previous_object()), this_interactive()));
+
+  return free_num;
+}
+
+public mixed Remove_free_num(int what)
+{
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!what || !intp(what))
+    return SCORE_INVALID_ARG;
+  free_num-=({what});
+  save_object(SCORESAVEFILE);
+  write_file(SCORELOGFILE,sprintf("REMOVEFREENUM: %s %5d (%s, %O)\n",     
+  strftime("%d%m%Y-%T",time()),what,
+  geteuid(previous_object()),this_interactive()));
+  return free_num;
+}
+
+public mixed Query_to_change(string who)
+{
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!who)
+    return to_change;
+  if (who=="")
+    return m_indices(to_change);
+  return to_change[who];
+}
+
+public mixed Add_to_change(string who, int what)
+{
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!who || !stringp(who) || !what || !intp(what))
+    return SCORE_INVALID_ARG;
+  if (member(to_change,who))
+  {
+    to_change[who]-=({-what});
+    if (member(to_change[who],what)==-1)
+      to_change[who]+=({what});
+  }
+  else
+     to_change[who]=({what});
+  save_object(SCORESAVEFILE);
+  write_file(SCORELOGFILE,sprintf("ADDTOCHANGE: %s %s %5d (%s, %O)\n",
+         strftime("%d%m%Y-%T",time()),who,what,
+         geteuid(previous_object()), this_interactive()));
+  return to_change[who];
+}
+
+public mixed Remove_to_change(string who, int what)
+{
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!who || !stringp(who) || !what || !intp(what))
+    return SCORE_INVALID_ARG;
+  if (member(to_change,who))
+  {
+     to_change[who]-=({what});
+     if (!sizeof(to_change[who]))
+        m_delete(to_change,who);
+  }
+  save_object(SCORESAVEFILE);
+  write_file(SCORELOGFILE,sprintf("REMOVETOCHANGE: %s %s %5d (%s, %O)\n",
+         strftime("%d%m%Y-%T",time()),who,what,
+         geteuid(previous_object()), this_interactive()));
+  return to_change[who];
+}
+
+void reset()
+{
+  string *whop,who,ek;
+  mixed what;
+  int i,j,value,changed;
+
+  // falls EKs global entfernt werden sollen, schonmal den noetigen Callout
+  // starten.
+  if (sizeof(to_be_removed) && find_call_out(#'check_all_player) == -1)
+      call_out(#'check_all_player, 10, 0);
+  // EK-Mainteiner ueber unbestaetigte EKs informieren
+  if (sizeof(unconfirmed_scores)) {
+    foreach(string n: SCOREMAINTAINERS) {
+      if (objectp(find_player(n)))
+          tell_object(find_player(n),break_string(
+      "Es gibt unbestaetigte EKs im Scoremaster. Schau Dir die doch "
+      "mal an. ;-)",78, "Der Scoremaster teilt Dir mit: "));
+    }
+  }
+
+  i=sizeof(whop=m_indices(to_change))-1;
+  while (i>=0 && get_eval_cost()>100000)
+  {
+    ek = (string)(MASTER->query_ek(who=whop[i]) || "");
+    for (j=sizeof(what=to_change[who])-1;j>=0;j--) {
+      if ((value=what[j])>0) {
+    // Vergabestatistik hochzaehlen.
+    npcs[by_num[value,BYNUM_KEY],NPC_COUNT]++;
+    ek=set_bit(ek,value);
+      }
+      else {
+    // Vergabestatistik hochzaehlen.
+    npcs[by_num[-value,BYNUM_KEY],NPC_COUNT]++;
+    ek=clear_bit(ek,-value);
+      }
+      // if (find_player("rikus")) 
+      //tell_object(find_player("rikus"),"SCOREMASTER "+who+" "+erg+"\n");
+
+      write_file(SCOREAUTOLOG,
+  sprintf("SET_CLEAR_BIT (reset): %s %4d %s\n",
+    who, j, strftime("%d%m%Y-%T",time()) ));
+    }
+    MASTER->update_ek(who, ek);
+
+    if (member(users_ek, who))
+      m_delete(users_ek, who);
+    
+    m_delete(to_change,who);
+    changed=1;
+    i--;
+  }
+  if (changed) save_object(SCORESAVEFILE);
+}
+
+public varargs mixed QueryNPC(int score)
+{
+  string key;
+  int val;
+
+  if (!previous_object())
+    return SCORE_INVALID_ARG;
+  
+  key = load_name(previous_object());
+
+  // schon bekannter EK?
+  if (member(npcs,key))
+    return ({npcs[key,NPC_NUMBER],npcs[key,NPC_SCORE]});
+
+  if (score<=0 || 
+      member(inherit_list(previous_object()),"/std/living/life.c") < 0)
+    return SCORE_INVALID_ARG;
+
+  if (key[0..8]=="/players/") return SCORE_INVALID_ARG;
+
+  if (score>2) score=2;
+
+  if (sizeof(free_num)) {
+      val = free_num[0];
+      free_num -= ({val});
+  }
+  else val=++lastNum;
+
+  npcs[key,NPC_SCORE] = score;
+  npcs[key,NPC_NUMBER] = val;
+  npcs[key,NPC_COUNT] = 0;
+  by_num += ([val: key; score]);
+  // werden noch nicht als aktive EKs gewertet, damit sie nicht als Ek-Tips
+  // vergben werden.
+  //active_eks = set_bit(active_eks, val);
+
+  unconfirmed_scores += ([ val: ({}) ]);
+
+  ClearUsersEKCache();
+  save_object(SCORESAVEFILE);
+  write_file(SCOREAUTOLOG,sprintf(
+  "ADDNPC: %s %5d %4d %s (UID: %s, TI: %O, TP: %O)\n",
+  strftime("%d%m%Y-%T",time()),val,score,key,
+  getuid(previous_object()), this_interactive(), this_player()));
+
+  while(remove_call_out("DumpNPCs") != -1) ;
+  call_out("DumpNPCs",60);
+  return ({val,score});
+}
+
+public varargs mixed NewNPC(string key,int score)
+{
+  int val;
+
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!key || !stringp(key))
+    return SCORE_INVALID_ARG;
+  
+  key = load_name(key);
+  if (val=npcs[key,NPC_NUMBER])
+    return ({val,npcs[key,NPC_SCORE]});
+  if (score<=0)
+    return SCORE_INVALID_ARG;
+
+  if (sizeof(free_num)) {
+      val=free_num[0];
+      free_num=free_num[1..];
+  }
+  else val=++lastNum;
+
+  npcs[key,NPC_SCORE] = score;
+  npcs[key,NPC_NUMBER] = val;
+  npcs[key,NPC_COUNT] = 0;
+  by_num += ([val: key; score]);
+  active_eks = set_bit(active_eks, val);
+
+  ClearUsersEKCache();
+  save_object(SCORESAVEFILE);
+  write_file(SCORELOGFILE,sprintf("NEWNPC: %s %5d %4d %s (%s, %O)\n",
+         strftime("%d%m%Y-%T",time()),val,score,key,
+         geteuid(previous_object()), this_interactive()));
+ while(remove_call_out("DumpNPCs") != -1) ; 
+  call_out("DumpNPCs",60);
+  return ({val,score});
+}
+
+public varargs mixed AddNPC(string key,int score) { return NewNPC(key,score); }
+
+// restauriert die Daten eines frueher geloeschten, in den Spielern noch
+// enthaltenen EKs. Moeglich, wenn man Pfad, Nr. und Punkte noch kennt.
+public int RestoreEK(string key, int bit, int score) {
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!stringp(key) || !sizeof(key) 
+      || !intp(bit) || bit < 0
+      || !intp(score) || score < 0)
+      return SCORE_INVALID_ARG;
+
+  if (member(npcs,key) || member(by_num,bit))
+      return SCORE_INVALID_ARG;
+
+  npcs += ([key: bit;score;0 ]);
+  by_num += ([bit: key;score ]);
+
+  ClearUsersEKCache();
+  save_object(SCORESAVEFILE);
+  write_file(SCORELOGFILE,sprintf("RESTOREEK: %s %5d %4d %s (%s, %O)\n",
+         strftime("%d%m%Y-%T",time()), bit, score, key,
+         geteuid(previous_object()), this_interactive()));
+  while(remove_call_out("DumpNPCs") != -1) ;
+  call_out("DumpNPCs",60);
+  return 1;
+
+}
+
+public int ConfirmScore(mixed key) {
+  // Bits in den Spielern in unconfirmed_scores setzen und Statistik
+  // hochzaehlen
+  // Bit in active_eks setzen
+  // Eintrag aus unconfirmed_scores loeschen
+  int bit;
+
+  if (!allowed()) return SCORE_NO_PERMISSION;
+  if (stringp(key) && member(npcs,key)) {
+      bit = npcs[key, NPC_NUMBER];
+  }
+  else if (intp(key) && member(by_num,key)) {
+      bit = key;
+  }
+  else
+      return SCORE_INVALID_ARG;
+
+  if (!member(unconfirmed_scores, bit)) 
+      return SCORE_INVALID_ARG;
+
+  string obname = by_num[bit, BYNUM_KEY];
+  int score = by_num[bit,BYNUM_SCORE];
+  
+  foreach(string pl: unconfirmed_scores[bit]) {
+      string eks = (string)master()->query_ek(pl);
+      eks = set_bit(eks, bit);
+      master()->update_ek(pl, eks);
+      write_file(SCOREAUTOLOG, sprintf(
+    "SETBIT: %s %5d %s\n",
+    strftime("%d%m%Y-%T",time()), bit, pl));
+  }
+  //Vergabestatistik hochzaehlen...
+  npcs[obname,NPC_COUNT]+=sizeof(unconfirmed_scores[bit]);
+
+  m_delete(unconfirmed_scores, bit);
+  active_eks = set_bit(active_eks, bit);
+  save_object(SCORESAVEFILE);
+
+  write_file(SCORELOGFILE,sprintf(
+      "CONFIRMNPC: %s %5d Score %3d %s [%s, %O]\n",
+       strftime("%d%m%Y-%T",time()), bit, score, obname,
+       getuid(previous_object()),this_interactive()));
+
+  return 1;
+}
+
+public int RejectScore(mixed key) {
+  // Eintrag aus unconfirmed_scores, npcs, by_num loeschen
+  // Bit-Nr. in free_num eintragen
+  // evtl. EK-Spruch entfernen?
+  int bit;
+
+  if (!allowed()) return SCORE_NO_PERMISSION;
+  if (stringp(key) && member(npcs,key)) {
+      bit = npcs[key, NPC_NUMBER];
+  }
+  else if (intp(key) && member(by_num,key)) {
+      bit = key;
+  }
+  else
+      return SCORE_INVALID_ARG;
+
+  if (!member(unconfirmed_scores, bit)) 
+      return SCORE_INVALID_ARG;
+
+  string obname = by_num[bit, BYNUM_KEY];
+  int score = by_num[bit,BYNUM_SCORE];
+
+  m_delete(by_num, bit);
+  m_delete(npcs, obname);
+  m_delete(unconfirmed_scores,bit);
+  removeTip(obname);
+  free_num += ({bit});
+
+  save_object(SCORESAVEFILE);
+
+  write_file(SCORELOGFILE,sprintf(
+      "REJECTNPC: %s %5d Score %3d %s [%s, %O]\n",
+       strftime("%d%m%Y-%T",time()), bit, score, obname,
+       getuid(previous_object()),this_interactive()));
+  return 1;
+}
+
+// unbestaetigte NPCs in ein File ausgeben
+public void DumpUnconfirmedScores() {
+  if (!objectp(this_player())) return;
+ 
+  write(sprintf("%5s  %5s  %4s   %s\n",
+  "Nr.", "Cnt", "Sc", "Objekt"));
+  foreach(int bit, string *pls: unconfirmed_scores) {
+    write(sprintf("%5d  %5d  %4d   %s\n",
+  bit, sizeof(pls), by_num[bit,BYNUM_SCORE], by_num[bit,BYNUM_KEY]));
+  }
+}
+
+public mapping _query_unconfirmed() {
+  if (allowed()) return unconfirmed_scores;
+  return 0;
+}
+
+public varargs int SetScore(mixed key,int score)
+{
+  int num;
+  string ob;
+  int oldscore;
+
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!key) return SCORE_INVALID_ARG;
+
+  if (stringp(key) && sizeof(key)) {
+    ob = load_name(key);
+    if (!member(npcs, ob)) return SCORE_INVALID_ARG;
+    num = npcs[ob, NPC_NUMBER];
+    if (ob != by_num[num, BYNUM_KEY])
+  return SCORE_INVALID_ARG;
+  }
+  else if (intp(key) && member(by_num,key) ) {
+    num = key;
+    ob = by_num[num, BYNUM_KEY];
+    if (!member(npcs, ob) || (npcs[ob, NPC_NUMBER] != num))
+  return SCORE_INVALID_ARG;
+  }
+  else
+    return SCORE_INVALID_ARG;
+
+  oldscore = by_num[num,BYNUM_SCORE];
+  by_num[num,BYNUM_SCORE] = score;
+  npcs[ob, NPC_SCORE] = score;
+
+  if (score > 0)
+      active_eks = set_bit(active_eks, num);
+  else
+      active_eks = clear_bit(active_eks, num);
+
+  ClearUsersEKCache();
+  save_object(SCORESAVEFILE);
+  write_file(SCORELOGFILE,sprintf(
+  "SETSCORE: %s %5d %.3d OSc: %.3d %s (%s, %O)\n",
+         strftime("%d%m%Y-%T",time()),num,score,oldscore, ob,
+         geteuid(previous_object()), this_interactive()));
+ while(remove_call_out("DumpNPCs") != -1) ; 
+  call_out("DumpNPCs",60);
+  return 1;
+}
+
+// entfernt einen EK endgueltig und unwiderruflich und gibt die Nr. wieder
+// frei.
+// Technisch wird der EK erstmal in eine Liste eingetragen. Im Reset iteriert
+// der Master ueber alle SPieler-Savefiles und loescht den Ek aus alle
+// Spielern. Nach Abschluss wird der Eintrag in npcs geloescht und seine Nr.
+// in die Liste freier Nummern eingetragen.
+public int* MarkEKForLiquidation(mixed key) {
+  int bit;
+  if (!allowed())
+      return 0;
+  // nicht in to_be_removed aendern, wenn check_all_player() laeuft.
+  if (find_call_out(#'check_all_player) != -1)
+      return 0;
+
+  if (stringp(key) && sizeof(key)) {
+    if (!member(npcs,key)) return 0;
+    bit = npcs[key,NPC_NUMBER];
+  }
+  else if (intp(key) && key>=0) {
+    bit = key;
+  }
+  else
+    return 0;
+
+  if (member(to_be_removed,bit) == -1)
+    to_be_removed += ({bit});
+  write_file(SCORELOGFILE,sprintf("DELETEFLAG: %s %5d %s (%s, %O)\n",
+  strftime("%d%m%Y-%T",time()), bit, by_num[bit,BYNUM_KEY] || "NoName",
+  geteuid(previous_object()), this_interactive()));
+  
+  save_object(SCORESAVEFILE);
+  
+  return to_be_removed;
+}
+
+// geht nur, solange nach einem RemoveEK() noch kein reset() gelaufen ist!
+public int* UnmarkEKForLiquidation(mixed key) {
+  int bit;
+  if (!allowed())
+      return 0;
+  // nicht in to_be_removed aendern, wenn check_all_player() laeuft.
+  if (find_call_out(#'check_all_player) != -1)
+      return 0;
+
+  if (stringp(key) && sizeof(key)) {
+    if (!member(npcs,key)) return 0;
+    bit = npcs[key,NPC_NUMBER];
+  }
+  else if (intp(key) && key>=0) {
+    bit = key;
+  }
+  else
+    return 0;
+ 
+  to_be_removed -= ({bit});
+  write_file(SCORELOGFILE,sprintf("UNDELETEFLAG: %s %5d %s (%s, %O\n",
+  strftime("%d%m%Y-%T",time()),bit, by_num[bit, BYNUM_KEY] || "NoName",
+  geteuid(previous_object()), this_interactive()));
+  
+  save_object(SCORESAVEFILE);
+
+  return to_be_removed;
+}
+
+public int* QueryLiquidationMarks() {
+  if (allowed())
+      return to_be_removed;
+  else
+      return 0;;
+}
+
+// setzt nur den Scorewert auf 0, sonst nix. Solche EKs koennen dann spaeter
+// durch Angabe eines neues Scorewertes reaktiviert werden.
+public int RemoveScore(mixed key) {
+  int changed;
+  int oldscore;
+
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+
+  if (stringp(key) && member(npcs,key)) {
+    int num = npcs[key, NPC_NUMBER];
+    if ( key == by_num[num, BYNUM_KEY]) {
+      oldscore = by_num[num, BYNUM_SCORE];
+      npcs[key, NPC_SCORE] = 0;
+      by_num[num, BYNUM_SCORE] = 0;
+      active_eks = clear_bit(active_eks,num); 
+      write_file(SCORELOGFILE,sprintf(
+      "REMOVESCORE: %s %5d OSc: %.3d %s (%s, %O)\n",
+        strftime("%d%m%Y-%T",time()), num, oldscore, key, 
+        geteuid(previous_object()), this_interactive()));
+      changed = 1;
+    }
+  }
+  else if (intp(key) && member(by_num, key)) {
+    string obname = by_num[key, BYNUM_KEY];
+    if (key == npcs[obname, NPC_NUMBER]) {
+      oldscore = by_num[key, BYNUM_SCORE];
+      npcs[obname, NPC_SCORE] = 0;
+      by_num[key, BYNUM_SCORE] = 0;
+      active_eks = clear_bit(active_eks,key); 
+      write_file(SCORELOGFILE,sprintf(
+      "REMOVESCORE: %s %5d OSc: %.3d %s (%s, %O)\n",
+        strftime("%d%m%Y-%T",time()),key, oldscore, obname,
+        geteuid(previous_object()), this_interactive()));
+      changed = 1;
+    }
+  }
+
+  if (changed) {
+    ClearUsersEKCache();
+    save_object(SCORESAVEFILE);
+    while(remove_call_out("DumpNPCs") != -1) ;
+    call_out("DumpNPCs",60);
+    return 1;
+  }
+  return SCORE_INVALID_ARG;
+}
+
+public varargs int MoveScore(mixed oldkey, string newpath)
+{
+  int num,score;
+  string oldpath;
+  string tip;
+  
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  if (!stringp(newpath))
+    return SCORE_INVALID_ARG;
+
+  if (stringp(oldkey)) {
+    oldkey = load_name(oldkey); 
+    num=npcs[oldkey,NPC_NUMBER];
+  }
+  else if (intp(oldkey)) num=oldkey;
+  else return SCORE_INVALID_ARG;
+
+  if (!member(by_num,num)) return SCORE_INVALID_ARG;
+  
+  tip=getTipFromList(oldkey);
+  oldpath = by_num[num, BYNUM_KEY];
+  score = by_num[num, BYNUM_SCORE];
+
+  if (member(npcs, oldpath)) {
+    m_delete(npcs, oldpath);
+    removeTip(oldkey);
+    if(tip!="") addTip(newpath,tip);
+    npcs[newpath, NPC_SCORE] = score;
+    npcs[newpath, NPC_NUMBER] = num;
+  }
+  else return SCORE_INVALID_ARG;
+
+  by_num += ([num: newpath; score]);
+
+  ClearUsersEKCache();
+  save_object(SCORESAVEFILE);
+  write_file(SCORELOGFILE,sprintf("MOVESCORE: %s %s %s (%s, %O)\n",
+  strftime("%d%m%Y-%T",time()),oldpath,newpath,
+  geteuid(previous_object()),this_interactive()));
+
+  while(remove_call_out("DumpNPCs") != -1) ;
+  call_out("DumpNPCs",60);
+  return 1;
+}
+
+// liefert alle Kills des Spielers zurueck, auch solche, die momentan
+// ausgetragen/deaktiviet sind.
+public string QueryAllKills(string pl)
+{
+  return (MASTER->query_ek(pl) || "");
+}
+
+// filtert alle Eintraege aus dem Bitstring heraus, die fuer
+// ausgetragene/inaktive EKs stehen.
+public string QueryKills(string pl) {
+  string res = (string)MASTER->query_ek(pl) || "";
+  // vergleichen mit den aktiven EKs aus active_eks und nur jene Bits
+  // zurueckliefern, die in beiden Strings gesetzt sind.
+  return and_bits(res,active_eks);
+}
+
+public int QueryKillPoints(mixed pl) {
+  
+  if (!allowed() &&
+      (!previous_object() 
+       || strstr(object_name(previous_object()), "/gilden/") != 0) )
+     return 0;
+
+  if (!stringp(pl)) pl=getuid(pl);
+
+  if (member(users_ek,pl)) return users_ek[pl];
+
+  string s = (MASTER->query_ek(pl) || "");
+  
+  int p=-1;
+  int summe;
+  while ((p=next_bit(s,p)) != -1) {
+      summe+=by_num[p,BYNUM_SCORE];
+  }
+
+  users_ek += ([pl:summe]);
+  return summe;
+}
+
+public mixed *QueryNPCbyNumber(int num)
+{
+  if (!allowed())
+    return 0;
+
+  if (member(by_num, num))
+    return ({num, by_num[num, BYNUM_SCORE], by_num[num, BYNUM_KEY]});
+
+  return 0;
+}
+
+protected mixed *StaticQueryNPCbyNumber(int num)
+{
+  if (member(by_num, num))
+    return ({num, by_num[num, BYNUM_SCORE], by_num[num, BYNUM_KEY]});
+
+  return 0;
+}
+
+public mixed *QueryNPCbyObject(object o)
+{
+  string key;
+  int val;
+
+  key=load_name(o);
+  if (member(npcs,key)) {
+    val = npcs[key,NPC_NUMBER];
+    return ({val, by_num[val, BYNUM_SCORE], by_num[val, BYNUM_KEY]});
+  }
+  return 0;
+}
+
+public int GiveKill(object pl, int bit)
+{
+  mixed info;
+  object po;
+  int drin;
+  string pls, ek;
+
+
+  if (!pointerp(info = StaticQueryNPCbyNumber(bit)))
+    return -1;
+
+  if ((!po=previous_object()) 
+      || load_name(po) != info[SCORE_KEY])
+    return -2;
+
+  pls=getuid(pl);
+
+  // wenn unbestaetigt, Spieler fuer spaeter merken
+  if (member(unconfirmed_scores, bit)) {
+    if (member(unconfirmed_scores[bit], pls) == -1)
+  unconfirmed_scores[bit] += ({pls});
+  }
+  else {
+    // sonst wird das Bit direkt im Spieler gesetzt.
+    ek = (MASTER->query_ek(pls) || "");
+    if (test_bit(ek, bit))
+      return -3;
+    ek = set_bit(ek, bit);
+    MASTER->update_ek(pls, ek);
+    // Vergabestatistik hochzaehlen.
+    npcs[by_num[bit,BYNUM_KEY],NPC_COUNT]++;
+  }
+
+  if (member(users_ek, pls))
+    m_delete(users_ek, pls);
+
+  EK_GIVENLOG(sprintf("%s: %s", info[SCORE_KEY], pls)); 
+
+  return info[SCORE_SCORE];
+}
+
+public int HasKill(mixed pl, mixed npc)
+{
+  string fn, *pls;
+
+  if (!objectp(pl) && !stringp(pl) && 
+      !objectp(npc) && !stringp(npc) && !intp(npc))
+    return 0;
+  if (!stringp(pl)) 
+    pl=getuid(pl);
+
+  if (intp(npc))
+    npc=by_num[npc,BYNUM_KEY];
+  fn=load_name(npc);
+
+  if (!member(npcs, fn)) return 0;
+  
+  int bit = npcs[fn, NPC_NUMBER];
+  
+  if (pointerp(pls=unconfirmed_scores[bit]) &&
+      member(pls,pl) != -1)
+    return 1;
+
+  string eks = (MASTER->query_ek(pl) || "");
+
+  return test_bit(eks, bit);
+}
+
+private void WriteDumpFile(string *keys) {
+  int maxn;
+
+  if (!pointerp(keys)) return;
+
+  rm(SCOREDUMPFILE);
+
+  write_file(SCOREDUMPFILE,sprintf("%5s  %5s  %4s   %s\n",
+  "Nr.", "Cnt", "Sc", "Objekt"));
+  foreach(string key: keys) {
+    write_file(SCOREDUMPFILE,sprintf("%5d  %5d  %4d   %O\n",
+    npcs[key,NPC_NUMBER], npcs[key,NPC_COUNT],
+    npcs[key,NPC_SCORE], key));
+    maxn += npcs[key,NPC_SCORE];
+  }
+  write_file(SCOREDUMPFILE,sprintf(
+  "========================================================\n"
+  "NPCs gesamt: %d Punkte\n\n",maxn));
+}
+
+public varargs int DumpNPCs(int sortkey) {
+
+  if (extern_call() && !allowed()) return SCORE_NO_PERMISSION;
+  if (!intp(sortkey)) return SCORE_INVALID_ARG;
+
+  rm(SCOREDUMPFILE);
+
+  // sortieren
+  string *keys=sort_array(m_indices(npcs), function int (string a, string b) {
+        return(npcs[a,sortkey] < npcs[b,sortkey]); } );
+  call_out(#'WriteDumpFile, 2, keys);
+
+  return 1;
+}
+
+public int SetScoreBit(string pl, int bit)
+{
+  string ek;
+
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+
+  ek = (MASTER->query_ek(pl) || "");
+  ek = set_bit(ek, bit);
+  MASTER->update_ek(pl, ek);
+
+  // Vergabestatistik hochzaehlen.
+  npcs[by_num[bit,BYNUM_KEY],NPC_COUNT]++;
+
+  if (member(users_ek, pl))
+    m_delete(users_ek, pl);
+
+  write_file(SCORELOGFILE,sprintf("SETBIT: %s %s %5d Sc: %.3d %s (%s, %O)\n",
+         strftime("%d%m%Y-%T",time()),pl, bit,
+         by_num[bit,BYNUM_SCORE], by_num[bit,BYNUM_KEY],
+         geteuid(previous_object()), this_interactive()));
+  return 1;
+}
+
+public int ClearScoreBit(string pl, int bit)
+{
+  string ek;
+
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+
+  ek = (MASTER->query_ek(pl) || "");
+  ek = clear_bit(ek, bit);
+  MASTER->update_ek(pl, ek);
+
+  // Vergabestatistik runterzaehlen.
+  npcs[by_num[bit,BYNUM_KEY],NPC_COUNT]--;
+
+  if (member(users_ek, pl))
+    m_delete(users_ek, pl);
+
+  write_file(SCORELOGFILE,sprintf(
+  "CLEARBIT: %s %s %5d Sc: %.3d %s (%s, %O)\n",       
+  strftime("%d%m%Y-%T",time()),pl,bit,
+  by_num[bit,BYNUM_SCORE],by_num[bit,BYNUM_KEY],
+  geteuid(previous_object()), this_interactive()));
+  return 1;
+}
+
+private status ektipAllowed()
+{ 
+  status poOK;
+  string poName;
+  status ret;
+                
+  poName=load_name(previous_object());        
+  poOK=previous_object() &&     
+    ((previous_object()==find_object(EKTIPGIVER)) || (poName==EKTIPLIST) );
+
+  ret=allowed() || 
+    (this_player() && this_interactive() && previous_object() && 
+     this_interactive()==this_player() && poOK);
+  return ret;
+}
+
+// liefert alle EKs, die aktiv sind und die der Spieler noch nicht hat in
+// einem Mapping entsprechend npcs zurueck.
+public mapping getFreeEKsForPlayer(object player)
+{
+  if(!ektipAllowed() || !objectp(player) || !query_once_interactive(player)){
+      return ([]);
+  }
+  // alle EKs, die der Spieler hat
+  string eks = (string)master()->query_ek(getuid(player));
+  // als Tips kommen alle in Frage, die er nicht hat, vor dem Invertieren muss
+  // aber sichergestellt werden, dass eks min. so lang ist wie active_eks, da
+  // die Invertierung ja z.B. nur EKs 0-1700 beruecksichtigt, wenn 1700 der
+  // hoechste EK im Spieler ist und dann als Tips alle EKs ueber
+  // 1700 verlorengingen.
+  // hier wird das letzte Bit von active_eks ermittelt und das darauf folgende
+  // Bit im Spieler-EK-String gesetzt und wieder geloescht, woraufhin der
+  // EK-String min. so lang wie active_eks ist. (es ist egal, wenn er
+  // laenger ist, auch egal, wenn man ein Bit ueberschreibt, das faellt alles
+  // gleich beim and_bits() raus.
+  int lb = last_bit(active_eks) + 1;
+  eks = clear_bit(set_bit(eks, lb), lb);
+  // jetzt invertieren
+  string non_eks = invert_bits(eks);
+  // jetzt vorhande EK-Tips ausfiltern. Im Prinzip gleiches Spiel wie oben.
+  string ektips = (string)master()->query_ektips(getuid(player));
+  // jetzt alle nicht als Tip vergebenen NPC ermitteln, vor dem Invertieren
+  // wieder Laenge angleichen...
+  ektips = invert_bits(clear_bit(set_bit(ektips, lb), lb));
+  // verunden liefert EKs, die der Spieler nicht hat und nicht als Tip hat
+  ektips = and_bits(ektips, non_eks);
+
+  // und nun die inaktive EKs ausfiltern, nochmal verunden
+  ektips = and_bits(ektips, active_eks);
+
+  // mal Platz reservieren, entsprechend der Menge an Bits
+  mapping freeKills = m_allocate( count_bits(ektips), 2);
+  // durch alle jetzt gesetzten Bits laufen, d.h. alle EKs, die der Spieler
+  // nicht hat und ein Mapping a la npcs erstellen.
+  int p=-1;
+  while ( (p=next_bit(ektips, p)) != -1) {
+    freeKills += ([ by_num[p,0]: p; by_num[p,1] ]);
+  }
+
+  return freeKills;
+}
+
+public int addTip(mixed key,string tip)
+{
+  string fn;
+  
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+
+  if (!tip || (!objectp(key) && !stringp(key)))
+    return SCORE_INVALID_ARG;
+
+  fn=load_name(key);
+
+  if (!member(npcs, fn)) return SCORE_INVALID_ARG;
+  tipList+=([fn:tip]);
+  save_object(SCORESAVEFILE);
+    
+  return 1;
+}
+
+public int changeTip(mixed key,string tip)
+{
+    return addTip(key,tip);
+}
+
+public int removeTip(mixed key)
+{
+  string fn;
+  
+  if (!allowed())
+    return SCORE_NO_PERMISSION;
+  
+  if ((!objectp(key) && !stringp(key)))
+    return SCORE_INVALID_ARG;
+
+  fn=load_name(key);
+  
+  if (!member(tipList, fn)) return SCORE_INVALID_ARG;
+    
+  m_delete(tipList,fn);
+  save_object(SCORESAVEFILE);
+    
+  return 1;  
+}
+
+private string getTipFromList(mixed key)
+{
+  string fn;
+  
+  if (!ektipAllowed())
+    return "";
+  
+  if ((!objectp(key) && !stringp(key)))
+    return "";
+
+  fn=load_name(key);
+  
+  if (!member(tipList, fn)) return "";
+        
+  return tipList[fn];  
+}
+
+private string _getTip(mixed key)
+{
+  string fn;
+  string tip;
+  string* path;
+    
+  if ((!objectp(key) && !stringp(key)))
+    return "";
+
+  fn=load_name(key);
+  
+  if(!member(npcs,fn)) return "";
+  
+  tip=getTipFromList(fn);
+  if(!tip || tip==""){
+    path=explode(fn,"/")-({""});
+    if(sizeof(path)<3) return "";
+    if(path[0]=="players") {
+      string tiptext;
+      if ( path[1] == "ketos" )
+        tiptext = "Ketos im Gebirge";
+      else if ( path[1] == "boing" && path[2] == "friedhof" )
+        tiptext = "Boing im eisigen Polar";
+      else
+        tiptext = capitalize(path[1]);
+      return "Schau Dich doch mal bei "+tiptext+" um.";
+    }
+    
+    if(path[0]=="d")
+    {
+      tip+="Schau Dich doch mal ";
+    
+      if(file_size("/players/"+path[2])==-2)
+      {
+        tip+="bei "+capitalize(path[2]+" ");
+      }
+      if ( path[1]=="polar" && file_size("/players/"+path[3])==-2 )
+      {
+        tip+="bei "+capitalize(path[3])+" ";
+      }
+
+      if(path[1]=="anfaenger")
+        tip+="in den Anfaengergebieten ";
+      if(path[1]=="fernwest")
+        tip+="in Fernwest ";
+      if(path[1]=="dschungel")
+        tip+="im Dschungel ";
+      if(path[1]=="schattenwelt")
+        tip+="in der Welt der Schatten ";
+      if(path[1]=="unterwelt")
+        tip+="in der Unterwelt ";
+      if(path[1]=="gebirge")
+        tip+="im Gebirge ";
+      if(path[1]=="seher")
+        tip+="bei den Sehergebieten ";
+      if(path[1]=="vland")
+        tip+="auf dem Verlorenen Land ";
+      if(path[1]=="ebene")
+        tip+="in der Ebene ";
+      if(path[1]=="inseln")
+        tip+="auf den Inseln ";
+      if(path[1]=="wald")
+        tip+="im Wald ";
+      if(path[1]=="erzmagier")
+        tip+="bei den Erzmagiern ";
+      if(path[1]=="polar")
+      {
+        if (path[2]=="files.chaos")
+          tip+="in den Raeumen der Chaosgilde ";
+        tip+="im eisigen Polar ";
+      }
+      if(path[1]=="wueste")
+        tip+="in der Wueste ";
+      tip+="um.";
+    }
+    else if ( path[0]=="gilden" )
+    {
+      tip+="Schau Dich doch mal";
+      switch( path[1] )
+      {
+        case "mon.elementar": 
+          tip+=" unter den Anfuehrern der Elementargilde"; 
+          break;
+        case "files.dunkelelfen":
+          tip+=" unter den Anfuehrern der Dunkelelfengilde";
+          break;
+        case "files.klerus":
+          tip+=" beim Klerus"; 
+          break;
+        case "files.werwoelfe": 
+          tip+=" unter den Anfuehrern der Werwoelfe";
+          break;
+        case "files.chaos": 
+          tip+=" unter den Anfuehrern der Chaosgilde";
+          break;
+        default: 
+          tip+=" in einer der Gilden"; 
+          break;
+      }
+      tip+=" um.";
+    }
+    else if ( path[0] == "p" ) 
+    {
+      tip+="Schau Dich doch mal ";
+      switch( path[1] ) 
+      {
+        case "zauberer":
+          tip+="in der Zauberergilde zu Taramis";
+          break;
+        case "kaempfer":
+          tip+="bei den Angehoerigen des Koru-Tschakar-Struvs";
+          break;
+        case "katzenkrieger":
+          tip+="bei der Gilde der Katzenkrieger";
+          break;
+        case "tanjian":
+          tip+="unter den Meistern der Tanjiangilde";
+          break;
+      }
+      tip+=" um.";
+    }
+  }
+  return tip;
+}
+
+// return valid tips from database or existing 
+public string getTip(mixed key)
+{
+  string fn;
+  string tip;
+  string* path;
+  
+  if (!ektipAllowed())
+    return "";
+  
+  return _getTip(key);
+}
+
+// liefert ein Array mit allen Objekten zurueck, auf die bitstr verweist, also
+// eine Liste aller Objekte, die als Tip vergeben wurden.
+private string* makeTiplistFromBitString(string bitstr)
+{ 
+  string * ret= allocate(count_bits(bitstr));
+  // ueber alle gesetzten bits laufen und Array zusammensammeln
+  int i;
+  int p=-1;
+  while ((p=next_bit(bitstr,p)) != -1) {
+    ret[i] = by_num[p, 0];
+    i++;
+  }
+  // zur Sicherheit
+  ret -= ({0});
+
+  return ret;
+}
+
+// gibt die Objektnamen der EK-Tips vom jeweiligen Spieler zurueck.
+public string *QueryTipObjects(mixed player) {
+  
+  if (extern_call() && !allowed())
+      return 0;
+  if (objectp(player) && query_once_interactive(player))
+      player=getuid(player);
+  if (!stringp(player))
+    return 0;
+
+  string tipstr=(string)master()->query_ektips(player);
+  // jetzt EK-Tips ausfiltern, die erledigt sind. Dazu EK-Liste holen...
+  string eks=(string)master()->query_ek(player);
+  // als Tips kommen alle in Frage, die er nicht hat, vor dem Invertieren muss
+  // aber sichergestellt werden, dass eks min. so lang ist wie tipstr, da
+  // die Invertierung ja z.B. nur EKs 0-1700 beruecksichtigt, wenn 1700 der
+  // hoechste EK im Spieler ist und dann alle Tips ueber
+  // 1700 verlorengingen.
+  // hier wird das letzte Bit von tipstr ermittelt und das darauf folgende
+  // Bit im Spieler-EK-String gesetzt und wieder geloescht, woraufhin der
+  // EK-String min. so lang wie der Tipstring ist. (es ist egal, wenn er
+  // laenger ist, auch egal, wenn man ein Bit ueberschreibt, das faellt alles
+  // gleich beim and_bits() raus.
+  int lb = last_bit(tipstr) + 1;
+  eks = clear_bit(set_bit(eks, lb), lb);
+  // jetzt invertieren
+  string non_eks = invert_bits(eks);
+  // jetzt verunden und man hat die Tips, die noch nicht gehauen wurden.
+  tipstr = and_bits(tipstr, non_eks);
+  // noch inaktive EKs ausfiltern...
+  tipstr = and_bits(tipstr, active_eks);
+
+  return makeTiplistFromBitString(tipstr);
+}
+
+public string allTipsForPlayer(object player)
+{
+
+  if(!player || !this_interactive() || 
+      (this_interactive()!=player && !IS_ARCH(this_interactive())) )
+    return "";    
+ 
+  string *tips = QueryTipObjects(player);
+
+  tips = map(tips, #'_getTip);
+  tips -= ({0,""});
+
+  return implode(tips, "\n");
+}
+
+public status playerMayGetTip(object player)
+{
+  int numElegible;
+  int numReceived;
+  int lvl;
+  int i;
+  string tips;
+  
+  if(!ektipAllowed() || !player || !query_once_interactive(player))      
+      return 0;
+
+  if(!player || !query_once_interactive(player))    
+      return 0;
+  
+  lvl=(int)player->QueryProp(P_LEVEL);
+  numElegible=0;
+  i=sizeof(EKTIPS_LEVEL_LIMITS)-1;
+
+  if(lvl>EKTIPS_LEVEL_LIMITS[i])    
+      numElegible+=(lvl-EKTIPS_LEVEL_LIMITS[i]);
+
+  for(i;i>=0;i--){
+      if(lvl>=EKTIPS_LEVEL_LIMITS[i]) numElegible++;
+  }
+
+  tips=(string)MASTER->query_ektips(getuid(player)) || "";
+  // inaktive EKs ausfiltern.
+  tips = and_bits(tips, active_eks);
+  // und Gesamtzahl an Tips zaehlen. Hier werden erledigte Tips explizit nicht
+  // ausgefiltert!
+  numReceived=count_bits(tips);
+
+  return numElegible>numReceived;
+}
+
+public string giveTipForPlayer(object player)
+{
+  string* tmp;
+  mapping free;
+  string tip,pl,ektip;
+  int index;
+  
+  if(!ektipAllowed() || !player || 
+      !query_once_interactive(player) || !playerMayGetTip(player))  
+    return "";
+  
+  pl=getuid(player);
+  free=getFreeEKsForPlayer(player);
+
+  if(!mappingp(free) || sizeof(free)==0)
+    return "";
+
+  tmp=m_indices(free);
+
+  ektip=(string)MASTER->query_ektips(pl) || "";
+ 
+  foreach(int i: EKTIPS_MAX_RETRY) {
+      index=random(sizeof(tmp));
+      tip=getTip(tmp[index]);
+      if (stringp(tip) && sizeof(tip)) {
+    ektip=set_bit(ektip,npcs[tmp[index],NPC_NUMBER]);
+    MASTER->update_ektips(pl,ektip);
+    break; //fertig
+      }
+  }
+
+  return tip;  
+}
+
+// checkt NPCs auf Existenz und Ladbarkeit
+public void CheckNPCs(int num) {
+  string fn;
+  object ekob;
+  if (!num) rm(SCORECHECKFILE);
+  while (num <= lastNum && get_eval_cost() > 1480000) {
+    if (!by_num[num,1] || !by_num[num,0]) {
+      num++;
+      continue;
+    }
+    fn = by_num[num,0] + ".c";
+    if (file_size(fn) <= 0) {
+      // File nicht existent
+      write_file(SCORECHECKFILE, sprintf(
+    "EK %.4d ist nicht existent (%s)\n",num,fn));
+    }
+    else if (catch(ekob=load_object(fn)) || !objectp(ekob) ) {
+      // NPC offenbar nicht ladbar.
+      write_file(SCORECHECKFILE, sprintf(
+    "EK %.4d ist nicht ladbar (%s)\n",num,fn));
+    }
+    num++;
+  }
+  ZDEBUG(sprintf("%d NPC checked",num));
+  if (num <= lastNum)
+    call_out(#'CheckNPCs,4,num);
+  else
+    ZDEBUG("Finished!");
+}
+
+// liquidiert einen EK endgueltig. An diesem Punkt wird davon augegangen, dass
+// kein Spieler den EK mehr gesetzt hat!
+private void LiquidateEK(int bit) {
+
+  if (!intp(bit) || bit < 0) return;
+
+  string obname = by_num[bit, BYNUM_KEY];
+  int score = by_num[bit, BYNUM_SCORE];
+
+  if (member(npcs, obname) && (npcs[obname, NPC_NUMBER] == bit)) {
+    m_delete(by_num, bit);
+    m_delete(npcs, obname);
+    if (member(unconfirmed_scores,bit))
+      m_delete(unconfirmed_scores,bit);
+    active_eks = clear_bit(active_eks,bit);
+    removeTip(obname);
+    free_num += ({bit});
+    write_file(SCOREAUTOLOG,sprintf(
+    "LIQUIDATEEK: %s %5d Score %3d %s\n",
+    strftime("%d%m%Y-%T",time()), bit, score, obname));
+  }
+}
+
+private void check_player(string pl) {
+  int changed, changed2; 
+  
+  // EKs pruefen
+  string eks=(string)master()->query_ek(pl) || "";
+  string *opfer=allocate( (sizeof(eks)*6)+1, "");
+  int p=-1;
+  while ((p=next_bit(eks,p)) != -1) {
+    if (!member(by_num, p)) {
+  write_file(SCORECHECKFILE, sprintf(
+   "UNKNOWNEK %s %5d in %s gefunden.\n", 
+    strftime("%d%m%Y-%T",time()), p, pl));
+    }
+    // wenn das aktuelle Bit geloescht werden soll, also in to_be_removed
+    // steht...
+    if (member(to_be_removed,p) != -1) {
+  eks = clear_bit(eks,p);
+  changed=1;
+  write_file(EKCLEANLOG,sprintf(
+        "CLEARBIT: %s %O %5d %s\n",
+        strftime("%d%m%Y-%T",time()), pl, p, 
+        by_num[p,BYNUM_KEY] || "NoName"));
+    }
+    else {
+      // sonst statistikpflege
+      npcs[by_num[p,BYNUM_KEY],NPC_COUNT]++;
+      // loggen, welche NPC der Spieler hat
+      opfer[p]=to_string(p);
+    }
+  }
+  // und noch die Ek-Tips...
+  string ektips = (string)master()->query_ektips(pl) || "";
+  p = -1;
+  while ((p=next_bit(ektips,p)) != -1) {
+    if (!member(by_num, p)) {
+  write_file(EKCLEANLOG, sprintf(
+    "UNKNOWNEK %s %5d in %s (EKTips) gefunden - clearing.\n", 
+    strftime("%d%m%Y-%T",time()), p, pl));
+  ektips = clear_bit(ektips, p); // hier direkt loeschen.
+  changed2 = 1;
+    }
+    // wenn das aktuelle Bit geloescht werden soll, also in to_be_removed
+    // steht...
+    else if (member(to_be_removed,p) != -1) {
+  ektips = clear_bit(ektips,p);
+  changed2=1;
+  write_file(EKCLEANLOG,sprintf(
+        "CLEAREKTIP: %s %O %5d %s\n",
+        strftime("%d%m%Y-%T",time()), pl, p, 
+        by_num[p,BYNUM_KEY] || "NoName"));
+    }
+  }
+
+  if (changed) {
+      master()->update_ek(pl, eks);
+  }
+  if (changed2) {
+      master()->update_ektips(pl, ektips);
+  }
+  opfer-=({""});
+  write_file(WERKILLTWEN,sprintf("%s\n%=-78s\n\n",pl,CountUp(opfer)||""));
+}
+
+public void check_all_player(mapping allplayer) {
+ 
+  if (extern_call() && !allowed())
+      return;
+
+  if (!mappingp(allplayer)) {
+      foreach(string key: npcs) {
+  npcs[key,NPC_COUNT]=0;
+      }
+      allplayer=(mapping)master()->get_all_players();
+      rm(WERKILLTWEN);
+      call_out(#'check_all_player,2,allplayer);
+      return;
+  }
+
+  // offenbar fertig mit allen Spielern, jetzt noch den Rest erledigen.
+  if (!sizeof(allplayer)) {
+    foreach(int bit: to_be_removed) {
+      LiquidateEK(bit);
+    }
+    to_be_removed=({});
+    save_object(SCORESAVEFILE); 
+    ZDEBUG("Spielerchecks und EK-Liquidation fertig.\n");
+    return;
+  }
+
+  string dir=m_indices(allplayer)[0];
+  string *pls=allplayer[dir];
+  foreach(string pl: pls) {
+    if (get_eval_cost() < 1250000)
+      break; // spaeter weitermachen.
+    catch(check_player(pl) ; publish);
+    pls-=({pl});
+  }
+  allplayer[dir] = pls; 
+ 
+  if (!sizeof(allplayer[dir]))
+    m_delete(allplayer,dir);
+ 
+  call_out(#'check_all_player,2,allplayer);
+}
+
