diff --git a/std/spellbook.c b/std/spellbook.c
new file mode 100644
index 0000000..24f824f
--- /dev/null
+++ b/std/spellbook.c
@@ -0,0 +1,785 @@
+// MorgenGrauen MUDlib
+//
+// spellbook.c -- Grundlegende Funktionen fuer Zaubersprueche
+//
+// $Id: spellbook.c 9142 2015-02-04 22:17:29Z Zesstra $
+#pragma strict_types
+#pragma save_types
+#pragma no_shadow
+#pragma no_clone
+#pragma pedantic
+#pragma range_check
+
+//#define NEED_PROTOTYPES
+inherit "/std/thing";
+inherit "/std/restriction_checker";
+inherit "/std/player/pklog";
+
+#include <thing/properties.h>
+#include <properties.h>
+#include <wizlevels.h>
+#include <new_skills.h>
+#include <spellbook.h>
+#define ME this_object()
+
+void create() {
+  seteuid(getuid());
+  // diese Prop sollte von aussen nicht direkt geaendert werden koennen.
+  Set(P_SB_SPELLS,([]),F_VALUE);
+  Set(P_SB_SPELLS,PROTECTED,F_MODE_AS);
+
+  ::create();
+}
+
+mapping _query_sb_spells() {
+    // Kopie liefern, da sonst versehentlich schnell eine Aenderung des
+    // originalen Mappings hier passieren kann.
+    return(deep_copy(Query(P_SB_SPELLS, F_VALUE)));
+}
+
+mapping QuerySpell(string spell) {
+  mapping spi;
+
+  //Query-Methode umgehen, damit nur ein Spellmapping kopiert werden muss und
+  //nicht das ganzen Mapping mit allen Spells.
+  if (!spell
+      || !(spi=Query(P_SB_SPELLS))
+      || !(spi=spi[spell]))
+    return 0;
+  return deep_copy(spi);
+}
+
+varargs int
+AddSpell(string verb, int kosten, mixed ski) {
+  int level;
+  mapping spells;
+
+  if (!verb || kosten<0)
+    return 0;
+  
+  verb=lower_case(verb);
+  level=(intp(ski))?ski:0;
+
+  if (!mappingp(ski)) ski=([]);
+  // Zur Sicherheit eine Kopie machen, wer weiss, was da uebergeben wird, bzw.
+  // was der Setzende mit ski hinterher noch macht.
+  else ski=deep_copy(ski);
+
+  ski=AddSkillMappings(QueryProp(P_GLOBAL_SKILLPROPS),ski);
+  ski+=([SI_SPELLCOST:kosten]);
+  // SI_SPELL-Submapping hinzufuegen, wenn nicht da.
+  if (!member(ski,SI_SPELL))
+      ski+=([SI_SPELL:([]) ]);
+  // ski[SI_SPELL][SP_NAME] ergaenzen, ggf. aus ski verschieben
+  if (!stringp(ski[SI_SPELL][SP_NAME]) && stringp(ski[SP_NAME])) {
+      ski[SI_SPELL][SP_NAME] = ski[SP_NAME];
+      m_delete(ski, SP_NAME);
+  }
+  else if (!stringp(ski[SI_SPELL][SP_NAME])) {
+      ski[SI_SPELL][SP_NAME] = verb;
+  }
+  if (stringp(ski[SP_NAME])) {
+      m_delete(ski, SP_NAME);
+  }
+
+  if (level)
+    ski=AddSkillMappings(ski,([SI_SKILLRESTR_LEARN:([P_LEVEL:level])]));
+  
+  // Abfrage per Query(), um das Mapping als Referenz, nicht als Kopie zu
+  // bekommen, das spart etwas Zeit.
+  if (!(spells=Query(P_SB_SPELLS,F_VALUE))) {
+    spells=([]);
+    SetProp(P_SB_SPELLS,spells);
+  }
+  // Spell setzen...
+  spells[verb]=ski;
+  // Set() nicht noetig, da Query() an spell das Originalmapping geliefert hat
+  // und dieses bereits jetzt geaendert wurde. ;-)
+  //Set(P_SB_SPELLS,spells+([verb:ski]),F_VALUE);
+
+  // hat wohl geklappt...
+  return(1);
+}
+
+int
+TryAttackSpell(object victim, int damage, mixed dtypes,
+               mixed is_spell, object caster, mapping sinfo) {
+  mixed no_attack;
+  int nomag;
+
+  if (no_attack = (mixed)victim->QueryProp(P_NO_ATTACK)) {
+    if (stringp(no_attack))
+      write(no_attack);
+    else
+      write(victim->Name(WER,1)+" laesst sich nicht angreifen!\n");
+    return 0;
+  }
+  if (victim->QueryProp(P_GHOST)) {
+    write(victim->Name(WER,1)+" ist ein Geist!\n");
+    return 0;
+  }
+
+  damage=(damage*(int)caster->QuerySkillAttribute(SA_DAMAGE))/100;
+
+  // ggf. Loggen von PK-Versuchen und ggf. ausserdem Angriff abbrechen.
+  // BTW: Aufruf von InsertEnemy() gibt 0 zurueck, wenn der Gegner nicht
+  // eingetragen wurde. Allerdings tut es das auch, wenn der Gegner schon
+  // Feind war. Daher muss noch geprueft werden, ob nach dem InsertEnemy() die
+  // beiden Spieler Feinde sind. Wenn nicht, wird der Spell auch abgebrochen
+  // und eine Meldung ausgegeben.
+  if (query_once_interactive(caster) && query_once_interactive(victim)
+      && CheckPlayerAttack(caster, victim, 
+        sprintf("Spellbook: %O, Spell: %O\n",
+                object_name(this_object()),
+                ((mappingp(sinfo) && is_spell) ? sinfo[SP_NAME]  : "")))
+      && !caster->IsEnemy(victim)
+      && !caster->InsertEnemy(victim)
+      )
+  {
+    tell_object(ME, "Ein goettlicher Einfluss schuetzt Deinen Gegner.\n");
+    return 0;
+  }
+
+  nomag=(int)victim->QueryProp(P_NOMAGIC);
+  if ((sinfo[SI_NOMAGIC] < nomag) &&
+      nomag*100 > random(100)*(int)caster->QuerySkillAttribute(SA_ENEMY_SAVE)) {
+    printf("%s wehrt Deinen Zauber ab.\n", capitalize((string)victim->name(WER, 1)));
+    return 0;
+  }
+  else {
+    return (int)victim->Defend(damage, dtypes, is_spell, caster);
+  }
+}
+
+varargs int
+TryDefaultAttackSpell(object victim, object caster, mapping sinfo, 
+                      mixed si_spell) {
+  object team;
+  int row;
+  
+  if (!si_spell) si_spell=sinfo[SI_SPELL];
+  // Wenn der Spieler in einem Team ist, die Teamreihen-Boni
+  // beruecksichtigen. Wenn nicht, eben nicht.
+  if (!team=((object)caster->QueryProp(P_TEAM)))
+  return TryAttackSpell(victim,
+                        GetRandFValueO(SI_SKILLDAMAGE,sinfo,caster),
+                        GetData(SI_SKILLDAMAGE_TYPE,sinfo,caster),
+                        si_spell,
+                        caster,
+                        sinfo);
+  else
+  {
+	  row=(int)caster->PresentPosition();
+	  return TryAttackSpell(victim,
+		  GetRandFValueO(SI_SKILLDAMAGE,sinfo,caster)+
+		  // Nur wenn SI_SKILLDAMAGE_BY_ROW ein mapping ist, 
+		  // randomisiert addieren
+		  (mappingp(sinfo[SI_SKILLDAMAGE_BY_ROW])?
+		   random(sinfo[SI_SKILLDAMAGE_BY_ROW][row]):0)+
+		  // Nur wenn das OFFSET davon ein mapping ist,
+		  // nicht randomisiert addieren.
+		  (mappingp(sinfo[OFFSET(SI_SKILLDAMAGE_BY_ROW)])?
+		   sinfo[OFFSET(SI_SKILLDAMAGE_BY_ROW)][row] : 0),
+		   GetData(SI_SKILLDAMAGE_TYPE,sinfo,caster),
+		   si_spell,caster,sinfo);
+   }
+}
+
+#define SMUL(x,y) ((x<0 && y<0)?(-1*x*y):(x*y))
+int
+SpellSuccess(object caster, mapping sinfo) {
+  int cval,abil,res;
+
+  abil=sinfo[SI_SKILLABILITY];
+  cval=(int)caster->UseSkill(SK_CASTING);
+  res=abil + (SMUL(abil,cval)) / MAX_ABILITY - random(MAX_ABILITY);
+  if (cval && res>MAX_ABILITY) // besonders gut gelungen?
+    caster->LearnSkill(SK_CASTING,1+(res-MAX_ABILITY)/2000);
+  return res;
+}
+
+int
+CanTrySpell(object caster, mapping sinfo) {
+  mapping rmap;
+  string res;
+
+  if (caster->QueryProp(P_GHOST)) {
+    write("Als Geist kannst Du nicht zaubern.\n");
+    return 0;
+  }
+  if ((rmap=sinfo[SI_SKILLRESTR_USE])
+      && (res=check_restrictions(caster,rmap))) {
+    write(res);
+    return 0;
+  }
+  return 1;
+}
+
+void
+Learn(object caster, string spell, mapping sinfo) {
+  int val,diff,attval;
+  mapping attr;
+ 
+  // gar nicht lernen?
+  if (sinfo[SI_NO_LEARN])
+    return;
+
+ // Attribut sollte int sein, wenn nicht anders angegeben
+ if (mappingp(sinfo[SI_LEARN_ATTRIBUTE]))
+ {
+	attr=sinfo[SI_LEARN_ATTRIBUTE];
+	// Direkt in einem durch berechnen.
+	// Ich gehe davon aus, dass wir nie nie nie
+	// ein weiteres Attribut ins MG einfuegen.
+	// Wir berechnen den Mittelwert
+	attval=((int)caster->QueryAttribute(A_INT)*attr[A_INT]+
+		(int)caster->QueryAttribute(A_DEX)*attr[A_DEX]+
+		(int)caster->QueryAttribute(A_STR)*attr[A_STR]+
+		(int)caster->QueryAttribute(A_CON)*attr[A_CON])
+		/(attr[A_CON]+attr[A_INT]+attr[A_STR]+attr[A_DEX]);
+		
+	 
+ } else {
+	 attval=(int)caster->QueryAttribute(A_INT);
+ }
+
+  
+  val=((attval/2)*GetFValue(SI_SKILLLEARN,sinfo,caster)+
+       GetOffset(SI_SKILLLEARN,sinfo,caster));
+  if (!(diff=GetFValueO(SI_DIFFICULTY,sinfo,caster)))
+    diff=GetFValueO(SI_SPELLCOST,sinfo,caster);
+  caster->LearnSkill(spell,val,diff);
+}
+
+void
+Erfolg(object caster, string spell, mapping sinfo) {
+  object env;
+  if(env=environment(caster))
+     env->SpellInform(caster,spell,sinfo);
+}
+
+void
+Misserfolg(object caster, string spell, mapping sinfo) {
+  write("Der Zauberspruch ist missglueckt.\n");
+  write("Du lernst aus Deinem Fehler.\n");
+  Learn(caster,spell,sinfo);
+}
+
+string
+SelectSpell(string spell, mapping sinfo) {
+  if (sinfo && sinfo[SI_SKILLFUNC])
+    return sinfo[SI_SKILLFUNC];
+  return spell;
+}
+
+varargs void
+prepare_spell(object caster, string spell, mapping sinfo) {
+  string txt;
+
+  if (!caster || !spell) return ;
+  if (!mappingp(sinfo) || !stringp(txt=sinfo[SI_PREPARE_MSG]))
+    txt="Du bereitest Dich auf den Spruch ``%s'' vor.\n";
+  tell_object(caster,sprintf(txt,spell));
+}
+
+varargs int
+UseSpell(object caster, string spell, mapping sinfo) {
+  mapping ski,tmp;
+  string spellbook,sname,fname,txt;
+  int res,fat,cost;
+  mixed ps;
+
+  if (!caster || !spell)
+    return 0;
+  // Spell kann in der Gilde anderen Namen haben
+  sname=SelectSpell(spell,sinfo);
+  if (!(ski=QuerySpell(sname))) // Existiert dieser Spell?
+    return 0;
+  // Gildeneigenschaften sollen Spelleigenschaften ueberschreiben koennen
+  ski=AddSkillMappings(ski,sinfo);
+  // Fuer verschiedene Rassen unterschiedliche Eigenschaften
+  ski=race_modifier(caster,ski);
+
+  // printf("Spellinfo: %O\n",ski);
+
+  if (!CanTrySpell(caster, ski))
+    return 1;
+
+  if (caster->QueryProp(P_SP) < (cost=GetFValueO(SI_SPELLCOST,ski,caster))) {
+    if(txt=ski[SI_SP_LOW_MSG])write(txt);
+    else write("Du hast zu wenig Zauberpunkte fuer diesen Spruch.\n");
+    return 1;
+  }
+  // printf("cost: %d\n",cost);
+
+  if (mappingp(ski[SI_X_SPELLFATIGUE])) {
+    // fuer jeden Key die Spellfatigue pruefen, wenn das Mapping hinterher
+    // nicht leer ist, ist man zu erschoepft.
+    tmp = filter(ski[SI_X_SPELLFATIGUE],
+        function int (string key, int val)
+        { return (int)caster->CheckSpellFatigue(key); } );
+    if (sizeof(tmp)) {
+        write(ski[SI_TIME_MSG] ||
+            "Du bist noch zu erschoepft von Deinem letzten Spruch.\n");
+      return 1;
+    }
+  }
+  else {
+    if (caster->CheckSpellFatigue()) {
+        write(ski[SI_TIME_MSG] ||
+            "Du bist noch zu erschoepft von Deinem letzten Spruch.\n");
+      return 1;
+    }
+  }
+
+  if (!(ski[SI_NO_ATTACK_BUSY]&NO_ATTACK_BUSY_QUERY) &&
+      caster->QueryProp(P_ATTACK_BUSY)) {
+    if (txt=ski[SI_ATTACK_BUSY_MSG]) write(txt);
+    else write("Du bist schon zu sehr beschaeftigt.\n");
+    return 1;
+  }
+
+  // Spruchvorbereitung
+  if (pointerp(ps=(mixed)caster->QueryProp(P_PREPARED_SPELL)) // Ausstehender Spruch
+      && sizeof(ps)>=3 && intp(ps[0] && stringp(ps[1]))) {
+    if (ps[1]==spell) { // Dieser Spruch wird noch vorbereitet
+      if (time()<ps[0]) {
+        if (!stringp(txt=ski[SI_PREPARE_BUSY_MSG]))
+          txt="Du bist noch mit der Spruchvorbereitung beschaeftigt.\n";
+        write(txt);
+        return 1;
+      }
+    }
+    else { // Andere Sprueche brechen die Vorbereitung ab
+      if (!mappingp(tmp=QuerySpell(ps[1])) || // richtige Meldung holen...
+          !stringp(txt=tmp[SI_PREPARE_ABORT_MSG]))
+        txt="Du brichst die Spruchvorbereitung fuer `%s' ab.\n";
+      printf(txt,ps[1]);
+      if (fat=GetValue(SI_PREPARE_TIME,ski,caster)) {
+        // Spruch braucht vorbereitungszeit
+        caster->SetProp(P_PREPARED_SPELL,({time()+fat,spell,ski[SI_SKILLARG]}));
+        prepare_spell(caster,spell,ski);
+        return 1;
+      }
+    }
+  }
+  else {
+    if (fat=GetValue(SI_PREPARE_TIME,ski,caster)) {
+      // Spruch braucht vorbereitungszeit
+      caster->SetProp(P_PREPARED_SPELL,({time()+fat,spell,ski[SI_SKILLARG]}));
+      prepare_spell(caster,spell,ski);
+      return 1;
+    }
+  }
+  if (ps)
+    caster->SetProp(P_PREPARED_SPELL,0);
+  
+  // Funktion kann anderen Namen haben als Spell
+  if (!(fname=sinfo[SI_SKILLFUNC]))
+    fname=sname;
+
+  if((ski[SI_NOMAGIC] < environment(caster)->QueryProp(P_NOMAGIC)) &&
+      random(100) < environment(caster)->QueryProp(P_NOMAGIC)) {
+    if (txt=ski[SI_NOMAGIC_MSG])
+      write(txt);
+    else
+      write("Dein Zauberspruch verpufft im Nichts.\n");
+    res=ABGEWEHRT;
+  }
+  else {
+    // Spruch ausfuehren.
+    res=(int)call_other(this_object(),fname,caster,ski);
+  }
+  // TODO: Wenn die ausgefuehrte Spellfunktion eine 0 zurueckgibt, sollen jetzt
+  // noch notify_fails zum Zuge kommen koennen. Daher in diesem Fall auch 0
+  // zurueckgeben.
+  if (!res || !caster)
+    return 1;
+
+  if (!(ski[SI_NO_ATTACK_BUSY]&NO_ATTACK_BUSY_QUERY))
+  	{
+	if (!ski[SI_ATTACK_BUSY_AMOUNT])  
+    		caster->SetProp(P_ATTACK_BUSY,1);
+	else
+		caster->SetProp(P_ATTACK_BUSY,ski[SI_ATTACK_BUSY_AMOUNT]);
+  	}
+
+  caster->restore_spell_points(-1*cost);
+
+  if (mappingp(ski[SI_X_SPELLFATIGUE])) {
+    // fuer jeden Key die Spellfatigue setzen. Keys mit Dauer 0 loesen keine
+    // Spellfatigue aus.
+    filter(ski[SI_X_SPELLFATIGUE],
+        function int (string key, int val)
+        { return (int)caster->SetSpellFatigue(val, key); } );
+  }
+  else {
+    if ((fat=GetFValueO(SI_SPELLFATIGUE,ski,caster))<0)
+      fat=1;
+    caster->SetSpellFatigue(fat);
+  }
+
+
+  if (res==ERFOLG)
+    Erfolg(caster,spell,ski);
+  else
+  if (res==MISSERFOLG)
+    Misserfolg(caster,spell,ski);
+  return 1;
+}
+
+object *
+FindGroup(object pl, int who) {
+  object *res,ob,env,team;
+  int p1,p2;
+  closure qp;
+
+  res=({});
+  if (!pl || !(env=environment(pl))) return res;
+  p1 = query_once_interactive(pl) ? 1 : -1;
+  team=(object)pl->QueryProp(P_TEAM);
+  for (ob=first_inventory(env);ob;ob=next_inventory(ob)) {
+    if (!living(ob)) continue;
+    qp=symbol_function("QueryProp",ob);
+    if (pl->IsEnemy(ob)) // Feinde sind immer Gegner
+      p2=-1*p1;
+    else if (objectp(team) && funcall(qp,P_TEAM)==team)
+      p2=p1; // Teammitglieder sind immer auf Seite des Spielers
+    else
+      p2 = (query_once_interactive(ob)||funcall(qp,P_FRIEND)) ? 1 : -1;
+    if (p2>0 && !interactive(ob) && query_once_interactive(ob))
+      continue; // keine Netztoten.
+    if (funcall(qp,P_GHOST))
+      continue;
+    if ( who<0 && (funcall(qp,P_NO_ATTACK) || funcall(qp,P_NO_GLOBAL_ATTACK)) )
+      continue;
+    if (IS_LEARNING(ob) &&
+        (funcall(qp,P_INVIS) || (who<0 && !pl->IsEnemy(ob))))
+      continue;
+    if (p1*p2*who >=0)
+      res+=({ob});
+  }
+  return res;
+}
+
+object *
+FindGroupN(object pl, int who, int n) {
+  if (!pl) return ({});
+  n=(n*(int)pl->QuerySkillAttribute(SA_EXTENSION))/100;
+  if (n<1) n=1;
+  return FindGroup(pl,who)[0..(n-1)];
+}
+
+object *
+FindGroupP(object pl, int who, int pr) {
+  object *res,*nres;
+  int i;
+
+  nres=({});
+  if (!pl) return nres;
+  pr=(pr*(int)pl->QuerySkillAttribute(SA_EXTENSION))/100;
+  if (pr<0) return nres;
+  res=FindGroup(pl,who);
+  for (i=sizeof(res)-1;i>=0;i--)
+    if (pr>=random(100))
+      nres+=({res[i]});
+  return nres;
+}
+
+// Findet feindliche und freundliche GRUPPEN im angegebenen Bereich.
+varargs mixed
+FindDistantGroups(object pl, int dist, int dy, int dx) {
+  mapping pos;
+  object ob,enteam,myteam;
+  int p1,min,max,i;
+  mixed *b_rows,x;
+  closure is_enemy, qp;
+
+  if (!objectp(pl) || !environment(pl))
+    return ({({}),({})});
+  if (!dy) dy=100;
+  if (!dx) dx=MAX_TEAM_ROWLEN*100;
+  x=(int)pl->QuerySkillAttribute(SA_EXTENSION);
+  dx=(dx*x)/100;dy=(dy*x)/100;
+  dist=(dist*(int)pl->QuerySkillAttribute(SA_RANGE))/100;
+  min=dist-dy/2;
+  max=dist+dy/2;
+
+  pos=([]);
+  p1=query_once_interactive(pl) ? 1 : -1;
+  is_enemy=symbol_function("IsEnemy",pl); // zur Beschleunigung
+  myteam=(object)pl->QueryProp(P_TEAM);
+  for (ob=first_inventory(environment(pl));ob;ob=next_inventory(ob)) {
+    if (!living(ob)) continue;
+    qp=symbol_function("QueryProp",ob); // zur Beschleunigung
+
+    // Zuerst mal die Position feststellen:
+    if (!objectp(enteam=funcall(qp,P_TEAM)))
+      pos[ob]=1;
+    else if (!pos[ob] && mappingp(x=(mapping)ob->PresentTeamPositions()))
+      pos+=x;
+    // PresentTeamPositions wird nur einmal pro Team ausgerechnet, weil
+    // anschliessend jedes anwesende Teammitglied pos[ob]!=0 hat.
+
+    pos[ob]=(2*pos[ob])-1;
+    // Reihen sollen Abstand 2 haben, auch Reihen 1 und -1 (nach Umrechnung)
+
+    // Feindliche Reihen an Y-Achse spiegeln, also gegenueber hinstellen:
+    if (funcall(is_enemy,ob))
+      pos[ob]*=-1; // Ist auf jeden Fall Feind
+    else if (objectp(myteam) && myteam==enteam)
+        ;            // Teammitglieder sind immer auf eigener Seite
+    else
+      pos[ob]*=(p1*((int)(query_once_interactive(ob)||
+                          funcall(qp,P_FRIEND))?1:-1));
+
+    // Den Spieler auf keinen Fall entfernen
+    if (ob==pl)
+      continue;
+    // Netztote, Geister  und unsichtbare Magier nicht beruecksichtigen,
+    // nicht (global) angreifbare Monster und nicht-feindliche Magier
+    // von feindlicher Seite entfernen.
+    if ((!interactive(ob) && query_once_interactive(ob)) // Netztote raus
+        || funcall(qp,P_GHOST)
+        || (IS_LEARNING(ob) && funcall(qp,P_INVIS))   // Bin nicht da :-)
+        || (pos[ob]<0 && (funcall(qp,P_NO_GLOBAL_ATTACK) // Nicht angreifen
+                          || funcall(qp,P_NO_ATTACK)
+                          || (IS_LEARNING(ob) && !funcall(is_enemy,ob)))))
+      m_delete(pos,ob);
+  }
+
+  // Reihen aufstellen
+  // Kampfreihe: |   5     4     3     2     1 ||  1     2     3     4     5|
+  // Arrays:     |0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19|
+  //             |<----------- Freunde ------->||<--------- Feinde -------->|
+  b_rows=EMPTY_TEAMARRAY+EMPTY_TEAMARRAY+EMPTY_TEAMARRAY+EMPTY_TEAMARRAY;
+  x=m_indices(pos);
+  for (i=sizeof(x)-1;i>=0;i--) {
+    p1=2*MAX_TEAMROWS-pos[ob=x[i]];
+    pos[ob]=p1;
+    if (p1>=0 && p1<4*MAX_TEAMROWS) {
+      if (random(100)<50)             // Damit gut gemischt wird...
+        b_rows[p1]=b_rows[p1]+({ob}); // zufaellig hinten anfuegen
+      else
+        b_rows[p1]=({ob})+b_rows[p1]; // oder vorne anfuegen.
+    }
+  }
+
+  // Umrechnung von Min, Max auf Reihen
+  // ... -2: -124..-75, -1:-74..-25, 0:-24..24, 1:25..74 2:75..124 ...
+  // Das muss man machen, wenn man keine vernuenftige Rundungsfunktion hat:
+  if (min<0) min=-1*((25-min)/50); else min=(25+min)/50;
+  if (max<0) max=-1*((25-max)/50); else max=(25+max)/50;
+  // Relativ zur Position des Spielers verschieben:
+  p1=pos[pl];min+=p1;max+=p1;
+  // Umrechnung von Breite auf Anzahl:
+  dx=((dx+50)/100)-1;if (dx<0) dx=0;
+
+  x=({({}),({})});
+  for (i=0;i<2*MAX_TEAMROWS;i++)
+    if (i>=min && i<=max)
+      x[1]+=b_rows[i][0..dx]; // Freunde
+  for (i=2*MAX_TEAMROWS+1;i<4*MAX_TEAMROWS;i++)
+    if (i>=min && i<=max)
+      x[0]+=b_rows[i][0..dx]; // Feinde
+
+  return x;
+}
+
+// Findet feindliche oder freundliche Gruppe (oder Summe beider) im
+// angegebenen Bereich.
+varargs object *
+FindDistantGroup(object pl, int who, int dist, int dy, int dx) {
+  mixed *x;
+
+  x=FindDistantGroups(pl,dist,dy,dx);
+  if (who<0)
+    return x[0];
+  else if (who>0)
+    return x[1];
+  return x[0]+x[1];
+}
+
+
+static varargs object
+find_victim(string wen, object pl) {
+  object victim;
+
+  if (!pl) return 0;
+  if (!sizeof(wen)) {
+    if (victim = (object)pl->SelectEnemy())
+      return victim;
+    else
+      return 0;
+  }
+  if (victim = present(wen, environment(pl)))
+    return victim;
+  else if (victim = present(wen, pl))
+    return victim;
+  else
+    return 0;
+}
+varargs object
+FindVictim(string wen, object pl, string msg) {
+  object vic;
+
+  if (!(vic=find_victim(wen,pl)) && msg)
+    write(msg);
+  return vic;
+}
+varargs object
+FindLivingVictim(string wen, object pl, string msg) {
+  object vic;
+
+  if (!(vic=FindVictim(wen,pl,msg)))
+    return 0;
+  if (!living(vic) || vic->QueryProp(P_GHOST)) {
+    printf("%s lebt doch nicht!\n", capitalize((string)vic->name()));
+    return 0;
+  }
+  return vic;
+}
+
+private varargs object
+DoFindEnemyVictim(string wen, object pl, string msg,
+                  mixed func, int min, int max) {
+  object vic;
+  mixed no_attack;
+  int row;
+
+  if (!(vic=FindLivingVictim(wen,pl,msg))) {
+    if ((stringp(wen) && wen!="") || !objectp(pl))
+      return 0;
+    if (pointerp(func)) { // Soll einer DIESER Gegner genommen werden?
+      if (!(vic=(object)pl->SelectEnemy(func))) // Dann daraus auswaehlen
+        return 0;
+    } else {
+      if (!stringp(func))
+        func="SelectEnemy";
+      if (!(vic=(object)call_other(pl,func,0,min,max)))
+        return 0;
+    }
+    func=0; // kein zweites Mal pruefen.
+  }
+  if (no_attack = (mixed)vic->QueryProp(P_NO_ATTACK)) {
+    if (stringp(no_attack))
+      write(no_attack);
+    else
+      write(vic->Name(WER,1)+" laesst sich nicht angreifen.\n");
+    return 0;
+  }
+  if (vic==pl) {
+    write("Du koenntest Dir dabei wehtun.\n");
+    return 0;
+  }
+  if (stringp(func)) {
+    switch(func) {
+    case "SelectNearEnemy":
+      if (pl->PresentPosition()>1) {
+        write("Du stehst nicht in der ersten Kampfreihe.\n");
+        return 0;
+      }
+      if (vic->PresentPosition()>1) {
+        write(vic->Name(WER,1)+" ist in einer hinteren Kampfreihe.\n");
+        return 0;
+      }
+      break;
+    case "SelectFarEnemy":
+      if (row=(int)vic->PresentPosition())
+        row--;
+      if (row>=min && row<=max)
+        break;
+      if (row<min)
+        write(vic->Name(WER,1)+" ist zu nahe.\n");
+      else if (row>max)
+        write(vic->Name(WER,1)+" ist zu weit weg.\n");
+      else
+        write(vic->Name(WER,1)+" ist unerreichbar.\n");
+      return 0;
+    default:;
+    }
+  } else if (pointerp(func)) {
+    if (member(func,vic)<0) {
+      write(vic->Name(WER,1)+" ist unerreichbar.\n");
+      return 0;
+    }
+  }
+
+  if (!pl->IsEnemy(vic)) // War es bisher kein Feind?
+    pl->Kill(vic);       // Dann ist es jetzt einer.
+  return vic;
+}
+
+varargs object
+FindEnemyVictim(string wen, object pl, string msg) {
+  return DoFindEnemyVictim(wen,pl,msg,"SelectEnemy");
+}
+
+// Wie FindEnemyVictim, aber nur im Nahkampf erreichbare Feinde werden
+// gefunden.
+varargs object
+FindNearEnemyVictim(string wen, object pl, string msg) {
+  return DoFindEnemyVictim(wen,pl,msg,"SelectNearEnemy");
+}
+
+// Wie FindEnemyVictim, aber nur Feinde im Bereich der angegebenen Reihen
+// (min,max) werden gefunden.
+varargs object
+FindFarEnemyVictim(string wen, object pl, string msg,
+                   int min, int max) {
+  return DoFindEnemyVictim(wen,pl,msg,"SelectFarEnemy",min,max);
+}
+
+// Wie FindEnemyVictim, findet aber nur Feinde in
+// FindDistantGroup(GEGNER,entfernung,abweichung)
+varargs object
+FindDistantEnemyVictim(string wen, object pl, string msg,
+                       int dist, int dy) {
+  return DoFindEnemyVictim(wen,pl,msg,
+                           FindDistantGroup(pl,-1,dist,dy,10000));
+}
+
+varargs int
+TryGlobalAttackSpell(object caster, mapping sinfo, int suc,
+                     int damage, mixed dt, mixed is_spell,
+                     int dist, int depth, int width) {
+  int i;
+  mixed x,coldam;
+  object *obs,ob;
+
+  if (!suc) suc=random(sinfo[SI_SKILLABILITY]);
+  if (!dt) dt=GetData(SI_SKILLDAMAGE_TYPE,sinfo,caster);
+  if (!is_spell) is_spell=GetData(SI_SPELL,sinfo,caster);
+  if (!dist) dist=GetRandFValueO(SI_DISTANCE,sinfo,caster);
+  if (!depth) depth=GetRandFValueO(SI_DEPTH,sinfo,caster);
+  if (!width) width=GetRandFValueO(SI_WIDTH,sinfo,caster);
+
+  if (!depth && width) depth=width;
+  if (!width && depth) width=depth;
+  if (!mappingp(is_spell)) is_spell=([]);
+  is_spell[SP_GLOBAL_ATTACK]=1;
+
+  x=FindDistantGroups(caster,dist,depth,width);
+  sinfo[SI_NUMBER_ENEMIES]=sizeof(x[0]);
+  sinfo[SI_NUMBER_FRIENDS]=sizeof(x[1]);
+
+  obs=x[0];
+  for (i=sizeof(obs)-1;i>=0;i--)
+    if (objectp(ob=obs[i]) && suc>=ob->SpellDefend(caster,sinfo))
+      TryAttackSpell(ob,(damage?random(damage):
+                         GetRandFValueO(SI_SKILLDAMAGE,sinfo,caster)),
+                     dt,is_spell,caster,sinfo);
+
+  if (!intp(coldam=sinfo[SI_COLLATERAL_DAMAGE]) || !coldam)
+    return 1;
+  obs=x[1];
+  for (i=sizeof(obs)-1;i>=0;i--)
+    if (objectp(ob=obs[i]) && suc>=ob->SpellDefend(caster,sinfo))
+      ob->reduce_hit_points(((damage?random(damage):
+                              GetRandFValueO(SI_SKILLDAMAGE,sinfo,caster))
+                             *coldam)/10);
+  // 10 statt 100 ist Absicht, weil reduce_hit_points schon um Faktor
+  // 10 staerker wirkt als Defend.
+
+  return 1;
+}
