// 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 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 = ({int|string})victim->QueryProp(P_NO_ATTACK)) {
    if (stringp(no_attack))
      ({int})caster->ReceiveMsg(
        no_attack,
        MT_NOTIFICATION,
        MA_FIGHT);
    else
      ({int})caster->ReceiveMsg(
        ({string})victim->Name(WER,1)+" laesst sich nicht angreifen!",
        MT_NOTIFICATION,
        MA_FIGHT);
    return 0;
  }
  if (({int})victim->QueryProp(P_GHOST)) {
    ({int})caster->ReceiveMsg(
      ({string})victim->Name(WER,1)+" ist ein Geist!",
      MT_NOTIFICATION,
      MA_FIGHT);
    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]  : "")))
      && !({int})caster->IsEnemy(victim)
      && !({int})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) {
  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 (!({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?
    ({void})caster->LearnSkill(SK_CASTING,1+(res-MAX_ABILITY)/2000);
  return res;
}

int
CanTrySpell(object caster, mapping sinfo) {
  if (({int})caster->QueryProp(P_GHOST)) {
    ({int})caster->ReceiveMsg(
      "Als Geist kannst Du nicht zaubern.",
      MT_NOTIFICATION,
      MA_SPELL);
    return 0;
  }
  string res;
  mapping rmap=sinfo[SI_SKILLRESTR_USE];
  if (mappingp(rmap)
      && (res=check_restrictions(caster,rmap)))
  {
    ({int})caster->ReceiveMsg(res, MT_NOTIFICATION|MSG_DONT_WRAP, MA_SPELL);
    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);
  ({void})caster->LearnSkill(spell,val,diff);
}

void
Erfolg(object caster, string spell, mapping sinfo) {
  object env;
  if(env=environment(caster))
     ({void})env->SpellInform(caster,spell,sinfo);
}

void
Misserfolg(object caster, string spell, mapping sinfo) {
  ({int})caster->ReceiveMsg(
    "Der Zauberspruch ist missglueckt.\n"
    "Du lernst aus Deinem Fehler.\n",
    MT_NOTIFICATION|MSG_DONT_WRAP,
    MA_SPELL);
  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 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 (({int})caster->QueryProp(P_SP) < (cost=GetFValueO(SI_SPELLCOST,ski,caster))) {
    if(txt=ski[SI_SP_LOW_MSG])
      ({int})caster->ReceiveMsg(
        txt,
        MT_NOTIFICATION,
        MA_SPELL);
    else
      ({int})caster->ReceiveMsg(
      "Du hast zu wenig Zauberpunkte fuer diesen Spruch.",
      MT_NOTIFICATION,
      MA_SPELL);
    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)) {
        ({int})caster->ReceiveMsg(
          ski[SI_TIME_MSG] || 
          "Du bist noch zu erschoepft von Deinem letzten Spruch.",
          MT_NOTIFICATION,
          MA_SPELL);
      return 1;
    }
  }
  else {
    if (({int})caster->CheckSpellFatigue()) {
        ({int})caster->ReceiveMsg(
          ski[SI_TIME_MSG] ||
          "Du bist noch zu erschoepft von Deinem letzten Spruch.",
          MT_NOTIFICATION,
          MA_SPELL);
      return 1;
    }
  }

  // Auf P_NO_ATTACK pruefen (Default), es sei denn, das ist im Skill nicht
  // gewuenscht.
  if (!(ski[SI_NO_ATTACK_BUSY]&NO_ATTACK_BUSY_QUERY) &&
      ({int})caster->QueryProp(P_ATTACK_BUSY)) {
    if (txt=ski[SI_ATTACK_BUSY_MSG])
      ({int})caster->ReceiveMsg(
        txt,
        MT_NOTIFICATION,
        MA_SPELL);
    else
      ({int})caster->ReceiveMsg(
        "Du bist schon zu sehr beschaeftigt.",
        MT_NOTIFICATION,
        MA_SPELL);
    return 1;
  }

  // Spruchvorbereitung
  if (pointerp(ps=({<int|mapping|string>*})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";
        ({int})caster->ReceiveMsg(
          txt,
          MT_NOTIFICATION,
          MA_SPELL);
        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
        ({<int|mapping|string>*})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
      ({<int|mapping|string>*})caster->SetProp(P_PREPARED_SPELL,({time()+fat,spell,ski[SI_SKILLARG]}));
      prepare_spell(caster,spell,ski);
      return 1;
    }
  }
  if (ps)
    ({<int|mapping|string>*})caster->SetProp(P_PREPARED_SPELL,0);
  
  // Funktion kann anderen Namen haben als Spell
  if (!(fname=sinfo[SI_SKILLFUNC]))
    fname=sname;

  if((ski[SI_NOMAGIC] < ({int})environment(caster)->QueryProp(P_NOMAGIC)) &&
      random(100) < ({int})environment(caster)->QueryProp(P_NOMAGIC)) {
    if (txt=ski[SI_NOMAGIC_MSG])
      ({int})caster->ReceiveMsg(
        txt,
        MT_NOTIFICATION,
        MA_SPELL);
    else
      ({int})caster->ReceiveMsg(
        "Dein Zauberspruch verpufft im Nichts.",
        MT_NOTIFICATION,
        MA_SPELL);
    res=ABGEWEHRT;
  }
  else {
    // Spruch ausfuehren.
    res=funcall(symbol_function(fname,ME),caster,ski);
  }
  if (!res || !caster)
    return 1;

  if(res==NICHT_ZUSTAENDIG)
    return 0;

  // P_NO_ATTACK setzen (Default), es sei denn, das ist vom Skill nicht
  // gewuenscht.
  if (!(ski[SI_NO_ATTACK_BUSY]&NO_ATTACK_BUSY_SET))
  	{
	if (!ski[SI_ATTACK_BUSY_AMOUNT])  
    		({int})caster->SetProp(P_ATTACK_BUSY,1);
	else
		({int})caster->SetProp(P_ATTACK_BUSY,ski[SI_ATTACK_BUSY_AMOUNT]);
  	}

  ({void})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;
    ({int})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 (({int})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 && !({int})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*((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)
    ({int})pl->ReceiveMsg(
      msg,
      MT_NOTIFICATION,
      MA_SPELL);
  return vic;
}
varargs object
FindLivingVictim(string wen, object pl, string msg) {
  object vic;

  if (!(vic=FindVictim(wen,pl,msg)))
    return 0;
  if (!living(vic) || ({int})vic->QueryProp(P_GHOST)) {
    ({int})pl->ReceiveMsg(
      ({string})vic->Name()+" lebt doch nicht!",
      MT_NOTIFICATION,
      MA_SPELL);
    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 = ({int|string})vic->QueryProp(P_NO_ATTACK)) {
    if (stringp(no_attack))
      ({int})pl->ReceiveMsg(
        no_attack,
        MT_NOTIFICATION,
        MA_FIGHT);
    else
      ({int})pl->ReceiveMsg(
        ({string})vic->Name(WER,1)+" laesst sich nicht angreifen.",
        MT_NOTIFICATION,
        MA_FIGHT);
    return 0;
  }
  if (vic==pl) {
    ({int})pl->ReceiveMsg(
      "Du koenntest Dir dabei wehtun.",
      MT_NOTIFICATION,
      MA_FIGHT);
    return 0;
  }
  if (stringp(func)) {
    switch(func) {
    case "SelectNearEnemy":
      if (({int})pl->PresentPosition()>1) {
        ({int})pl->ReceiveMsg(
          "Du stehst nicht in der ersten Kampfreihe.",
          MT_NOTIFICATION,
          MA_FIGHT);
        return 0;
      }
      if (({int})vic->PresentPosition()>1) {
        ({int})pl->ReceiveMsg(
          ({string})vic->Name(WER,1)+" ist in einer hinteren Kampfreihe.",
          MT_NOTIFICATION,
          MA_FIGHT);
        return 0;
      }
      break;
    case "SelectFarEnemy":
      if (row=({int})vic->PresentPosition())
        row--;
      if (row>=min && row<=max)
        break;
      if (row<min)
        ({int})pl->ReceiveMsg(
          ({string})vic->Name(WER,1)+" ist zu nahe.",
          MT_NOTIFICATION,
          MA_FIGHT);
      else if (row>max)
        ({int})pl->ReceiveMsg(
          ({string})vic->Name(WER,1)+" ist zu weit weg.",
          MT_NOTIFICATION,
          MA_FIGHT);
      else
        ({int})pl->ReceiveMsg(
          ({string})vic->Name(WER,1)+" ist unerreichbar.",
          MT_NOTIFICATION,
          MA_FIGHT);
      return 0;
    default:;
    }
  } else if (pointerp(func)) {
    if (member(func,vic)<0) {
      ({int})pl->ReceiveMsg(
        ({string})vic->Name(WER,1)+" ist unerreichbar.",
        MT_NOTIFICATION,
        MA_FIGHT);
      return 0;
    }
  }

  if (!({int})pl->IsEnemy(vic)) // War es bisher kein Feind?
    ({int})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>=({int})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>=({int})ob->SpellDefend(caster,sinfo))
      ({int})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;
}
