spellbook.c-Dateireferenz

#include <thing/properties.h>
#include <wizlevels.h>
#include <new_skills.h>
#include <spellbook.h>
Include-Abhängigkeitsdiagramm für spellbook.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define ME   this_object()
#define SMUL(x, y)   ((x<0 && y<0)?(-1*x*y):(x*y))

Funktionen

void create ()
mapping _query_sb_spells ()
mapping QuerySpell (string spell)
varargs int AddSpell (string verb, int kosten, mixed ski)
int TryAttackSpell (object victim, int damage, mixed dtypes, mixed is_spell, object caster, mapping sinfo)
varargs int TryDefaultAttackSpell (object victim, object caster, mapping sinfo, mixed si_spell)
int SpellSuccess (object caster, mapping sinfo)
int CanTrySpell (object caster, mapping sinfo)
void Learn (object caster, string spell, mapping sinfo)
void Erfolg (object caster, string spell, mapping sinfo)
void Misserfolg (object caster, string spell, mapping sinfo)
string SelectSpell (string spell, mapping sinfo)
varargs void prepare_spell (object caster, string spell, mapping sinfo)
varargs int UseSpell (object caster, string spell, mapping sinfo)
object * FindGroup (object pl, int who)
object * FindGroupN (object pl, int who, int n)
object * FindGroupP (object pl, int who, int pr)
varargs mixed FindDistantGroups (object pl, int dist, int dy, int dx)
varargs object * FindDistantGroup (object pl, int who, int dist, int dy, int dx)
static varargs object find_victim (string wen, object pl)
varargs object FindVictim (string wen, object pl, string msg)
varargs object FindLivingVictim (string wen, object pl, string msg)
static private varargs object DoFindEnemyVictim (string wen, object pl, string msg, mixed func, int min, int max)
varargs object FindEnemyVictim (string wen, object pl, string msg)
varargs object FindNearEnemyVictim (string wen, object pl, string msg)
varargs object FindFarEnemyVictim (string wen, object pl, string msg, int min, int max)
varargs object FindDistantEnemyVictim (string wen, object pl, string msg, int dist, int dy)
varargs int TryGlobalAttackSpell (object caster, mapping sinfo, int suc, int damage, mixed dt, mixed is_spell, int dist, int depth, int width)

Variablen

inherit std thing
inherit std restriction_checker
inherit std player pklog

Makro-Dokumentation

#define ME   this_object()

Definiert in Zeile 23 der Datei spellbook.c.

#define SMUL ( x,
 )     ((x<0 && y<0)?(-1*x*y):(x*y))

Definiert in Zeile 177 der Datei spellbook.c.


Dokumentation der Funktionen

mapping _query_sb_spells (  ) 

Definiert in Zeile 34 der Datei spellbook.c.

Benutzt F_VALUE, P_SB_SPELLS und Query().

00034                            {
00035     // Kopie liefern, da sonst versehentlich schnell eine Aenderung des
00036     // originalen Mappings hier passieren kann.
00037     return(deep_copy(Query(P_SB_SPELLS, F_VALUE)));
00038 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

varargs int AddSpell ( string  verb,
int  kosten,
mixed  ski 
)

Definiert in Zeile 53 der Datei spellbook.c.

Benutzt AddSkillMappings(), F_VALUE, level, P_GLOBAL_SKILLPROPS, P_LEVEL, P_SB_SPELLS, Query(), QueryProp(), SetProp(), SI_SKILLRESTR_LEARN, SI_SPELL, SI_SPELLCOST und SP_NAME.

00053                                              {
00054   int level;
00055   mapping spells;
00056 
00057   if (!verb || kosten<0)
00058     return 0;
00059   
00060   verb=lower_case(verb);
00061   level=(intp(ski))?ski:0;
00062 
00063   if (!mappingp(ski)) ski=([]);
00064   // Zur Sicherheit eine Kopie machen, wer weiss, was da uebergeben wird, bzw.
00065   // was der Setzende mit ski hinterher noch macht.
00066   else ski=deep_copy(ski);
00067 
00068   ski=AddSkillMappings(QueryProp(P_GLOBAL_SKILLPROPS),ski);
00069   ski+=([SI_SPELLCOST:kosten]);
00070   // SI_SPELL-Submapping hinzufuegen, wenn nicht da.
00071   if (!member(ski,SI_SPELL))
00072       ski+=([SI_SPELL:([]) ]);
00073   // gleiches SP_NAME in Skillmapping und SI_SPELL-Mapping eintragen. *seufz*
00074   // Noetig, weil es in der Vergangenheit offenbar eine grosse Verwirrung
00075   // gegeben hat, wo SP_NAME hingehoert (in SI_SPELL) und min. das halbe Mud
00076   // falsch prueft. TODO: Wenn der Rest vom mud richtig prueft, sollte
00077   // sichergestellt werden, dass SP_NAME nur noch in SI_SPELL drinsteht.
00078   if (!stringp(ski[SP_NAME]) && !stringp(ski[SI_SPELL][SP_NAME])) {
00079       ski[SP_NAME] = verb;
00080       ski[SI_SPELL][SP_NAME] = verb;
00081   }
00082   else if (stringp(ski[SP_NAME]) && !stringp(ski[SI_SPELL][SP_NAME]) )
00083       ski[SI_SPELL][SP_NAME] = ski[SP_NAME];
00084   else if (stringp(ski[SI_SPELL][SP_NAME]) && !stringp(ski[SP_NAME]) )
00085       ski[SP_NAME] = ski[SI_SPELL][SP_NAME];
00086 
00087   if (level)
00088     ski=AddSkillMappings(ski,([SI_SKILLRESTR_LEARN:([P_LEVEL:level])]));
00089   
00090   // Abfrage per Query(), um das Mapping als Referenz, nicht als Kopie zu
00091   // bekommen, das spart etwas Zeit.
00092   if (!(spells=Query(P_SB_SPELLS,F_VALUE))) {
00093     spells=([]);
00094     SetProp(P_SB_SPELLS,spells);
00095   }
00096   // Spell setzen...
00097   spells[verb]=ski;
00098   // Set() nicht noetig, da Query() an spell das Originalmapping geliefert hat
00099   // und dieses bereits jetzt geaendert wurde. ;-)
00100   //Set(P_SB_SPELLS,spells+([verb:ski]),F_VALUE);
00101 
00102   // hat wohl geklappt...
00103   return(1);
00104 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

int CanTrySpell ( object  caster,
mapping  sinfo 
)

Definiert in Zeile 191 der Datei spellbook.c.

Benutzt check_restrictions(), P_GHOST und SI_SKILLRESTR_USE.

Wird benutzt von UseSpell().

00191                                           {
00192   mapping rmap;
00193   string res;
00194 
00195   if (caster->QueryProp(P_GHOST)) {
00196     write("Als Geist kannst Du nicht zaubern.\n");
00197     return 0;
00198   }
00199   if ((rmap=sinfo[SI_SKILLRESTR_USE])
00200       && (res=check_restrictions(caster,rmap))) {
00201     write(res);
00202     return 0;
00203   }
00204   return 1;
00205 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

void create (  ) 

Definiert in Zeile 25 der Datei spellbook.c.

Benutzt create(), F_MODE_AS, F_VALUE, P_SB_SPELLS, PROTECTED und Set().

00025               {
00026   seteuid(getuid());
00027   // diese Prop sollte von aussen nicht direkt geaendert werden koennen.
00028   Set(P_SB_SPELLS,([]),F_VALUE);
00029   Set(P_SB_SPELLS,PROTECTED,F_MODE_AS);
00030 
00031   ::create();
00032 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

static private varargs object DoFindEnemyVictim ( string  wen,
object  pl,
string  msg,
mixed  func,
int  min,
int  max 
) [static]

Definiert in Zeile 596 der Datei spellbook.c.

Benutzt FindLivingVictim(), no_attack(), P_NO_ATTACK und WER.

Wird benutzt von FindDistantEnemyVictim(), FindEnemyVictim(), FindFarEnemyVictim() und FindNearEnemyVictim().

00597                                                 {
00598   object vic;
00599   mixed no_attack;
00600   int row;
00601 
00602   if (!(vic=FindLivingVictim(wen,pl,msg))) {
00603     if ((stringp(wen) && wen!="") || !objectp(pl))
00604       return 0;
00605     if (pointerp(func)) { // Soll einer DIESER Gegner genommen werden?
00606       if (!(vic=(object)pl->SelectEnemy(func))) // Dann daraus auswaehlen
00607         return 0;
00608     } else {
00609       if (!stringp(func))
00610         func="SelectEnemy";
00611       if (!(vic=(object)call_other(pl,func,0,min,max)))
00612         return 0;
00613     }
00614     func=0; // kein zweites Mal pruefen.
00615   }
00616   if (no_attack = (mixed)vic->QueryProp(P_NO_ATTACK)) {
00617     if (stringp(no_attack))
00618       write(no_attack);
00619     else
00620       write(vic->Name(WER,1)+" laesst sich nicht angreifen.\n");
00621     return 0;
00622   }
00623   if (vic==pl) {
00624     write("Du koenntest Dir dabei wehtun.\n");
00625     return 0;
00626   }
00627   if (stringp(func)) {
00628     switch(func) {
00629     case "SelectNearEnemy":
00630       if (pl->PresentPosition()>1) {
00631         write("Du stehst nicht in der ersten Kampfreihe.\n");
00632         return 0;
00633       }
00634       if (vic->PresentPosition()>1) {
00635         write(vic->Name(WER,1)+" ist in einer hinteren Kampfreihe.\n");
00636         return 0;
00637       }
00638       break;
00639     case "SelectFarEnemy":
00640       if (row=(int)vic->PresentPosition())
00641         row--;
00642       if (row>=min && row<=max)
00643         break;
00644       if (row<min)
00645         write(vic->Name(WER,1)+" ist zu nahe.\n");
00646       else if (row>max)
00647         write(vic->Name(WER,1)+" ist zu weit weg.\n");
00648       else
00649         write(vic->Name(WER,1)+" ist unerreichbar.\n");
00650       return 0;
00651     default:;
00652     }
00653   } else if (pointerp(func)) {
00654     if (member(func,vic)<0) {
00655       write(vic->Name(WER,1)+" ist unerreichbar.\n");
00656       return 0;
00657     }
00658   }
00659 
00660   if (!pl->IsEnemy(vic)) // War es bisher kein Feind?
00661     pl->Kill(vic);       // Dann ist es jetzt einer.
00662   return vic;
00663 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

void Erfolg ( object  caster,
string  spell,
mapping  sinfo 
)

Definiert in Zeile 240 der Datei spellbook.c.

Benutzt env().

Wird benutzt von UseSpell().

00240                                                    {
00241   object env;
00242   if(env=environment(caster))
00243      env->SpellInform(caster,spell,sinfo);
00244 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

static varargs object find_victim ( string  wen,
object  pl 
) [static]

Definiert in Zeile 557 der Datei spellbook.c.

Wird benutzt von FindVictim().

00557                                    {
00558   object victim;
00559 
00560   if (!pl) return 0;
00561   if (!strlen(wen)) {
00562     if (victim = (object)pl->SelectEnemy())
00563       return victim;
00564     else
00565       return 0;
00566   }
00567   if (victim = present(wen, environment(pl)))
00568     return victim;
00569   else if (victim = present(wen, pl))
00570     return victim;
00571   else
00572     return 0;
00573 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

varargs object FindDistantEnemyVictim ( string  wen,
object  pl,
string  msg,
int  dist,
int  dy 
)

Definiert in Zeile 682 der Datei spellbook.c.

Benutzt DoFindEnemyVictim() und FindDistantGroup().

00683                                          {
00684   return DoFindEnemyVictim(wen,pl,msg,
00685                            FindDistantGroup(pl,-1,dist,dy,10000));
00686 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

varargs object* FindDistantGroup ( object  pl,
int  who,
int  dist,
int  dy,
int  dx 
)

Definiert in Zeile 544 der Datei spellbook.c.

Benutzt FindDistantGroups().

Wird benutzt von FindDistantEnemyVictim().

00544                                                                {
00545   mixed *x;
00546 
00547   x=FindDistantGroups(pl,dist,dy,dx);
00548   if (who<0)
00549     return x[0];
00550   else if (who>0)
00551     return x[1];
00552   return x[0]+x[1];
00553 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

varargs mixed FindDistantGroups ( object  pl,
int  dist,
int  dy,
int  dx 
)

Definiert in Zeile 445 der Datei spellbook.c.

Benutzt EMPTY_TEAMARRAY, i, IS_LEARNING, m_delete(), MAX_TEAM_ROWLEN, MAX_TEAMROWS, min, ob(), P_FRIEND, P_GHOST, P_NO_ATTACK, P_NO_GLOBAL_ATTACK, P_TEAM, qp, SA_EXTENSION, SA_RANGE und x.

Wird benutzt von FindDistantGroup() und TryGlobalAttackSpell().

00445                                                        {
00446   mapping pos;
00447   object ob,enteam,myteam;
00448   int p1,min,max,i;
00449   mixed *b_rows,x;
00450   closure is_enemy, qp;
00451 
00452   if (!objectp(pl) || !environment(pl))
00453     return ({({}),({})});
00454   if (!dy) dy=100;
00455   if (!dx) dx=MAX_TEAM_ROWLEN*100;
00456   x=(int)pl->QuerySkillAttribute(SA_EXTENSION);
00457   dx=(dx*x)/100;dy=(dy*x)/100;
00458   dist=(dist*(int)pl->QuerySkillAttribute(SA_RANGE))/100;
00459   min=dist-dy/2;
00460   max=dist+dy/2;
00461 
00462   pos=([]);
00463   p1=query_once_interactive(pl) ? 1 : -1;
00464   is_enemy=symbol_function("IsEnemy",pl); // zur Beschleunigung
00465   myteam=(object)pl->QueryProp(P_TEAM);
00466   for (ob=first_inventory(environment(pl));ob;ob=next_inventory(ob)) {
00467     if (!living(ob)) continue;
00468     qp=symbol_function("QueryProp",ob); // zur Beschleunigung
00469 
00470     // Zuerst mal die Position feststellen:
00471     if (!objectp(enteam=funcall(qp,P_TEAM)))
00472       pos[ob]=1;
00473     else if (!pos[ob] && mappingp(x=(mapping)ob->PresentTeamPositions()))
00474       pos+=x;
00475     // PresentTeamPositions wird nur einmal pro Team ausgerechnet, weil
00476     // anschliessend jedes anwesende Teammitglied pos[ob]!=0 hat.
00477 
00478     pos[ob]=(2*pos[ob])-1;
00479     // Reihen sollen Abstand 2 haben, auch Reihen 1 und -1 (nach Umrechnung)
00480 
00481     // Feindliche Reihen an Y-Achse spiegeln, also gegenueber hinstellen:
00482     if (funcall(is_enemy,ob))
00483       pos[ob]*=-1; // Ist auf jeden Fall Feind
00484     else if (objectp(myteam) && myteam==enteam)
00485         ;            // Teammitglieder sind immer auf eigener Seite
00486     else
00487       pos[ob]*=(p1*((int)(query_once_interactive(ob)||
00488                           funcall(qp,P_FRIEND))?1:-1));
00489 
00490     // Den Spieler auf keinen Fall entfernen
00491     if (ob==pl)
00492       continue;
00493     // Netztote, Geister  und unsichtbare Magier nicht beruecksichtigen,
00494     // nicht (global) angreifbare Monster und nicht-feindliche Magier
00495     // von feindlicher Seite entfernen.
00496     if ((!interactive(ob) && query_once_interactive(ob)) // Netztote raus
00497         || funcall(qp,P_GHOST)
00498         || (IS_LEARNING(ob) && funcall(qp,P_INVIS))   // Bin nicht da :-)
00499         || (pos[ob]<0 && (funcall(qp,P_NO_GLOBAL_ATTACK) // Nicht angreifen
00500                           || funcall(qp,P_NO_ATTACK)
00501                           || (IS_LEARNING(ob) && !funcall(is_enemy,ob)))))
00502       efun::m_delete(pos,ob);
00503   }
00504 
00505   // Reihen aufstellen
00506   // Kampfreihe: |   5     4     3     2     1 ||  1     2     3     4     5|
00507   // Arrays:     |0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19|
00508   //             |<----------- Freunde ------->||<--------- Feinde -------->|
00509   b_rows=EMPTY_TEAMARRAY+EMPTY_TEAMARRAY+EMPTY_TEAMARRAY+EMPTY_TEAMARRAY;
00510   x=m_indices(pos);
00511   for (i=sizeof(x)-1;i>=0;i--) {
00512     p1=2*MAX_TEAMROWS-pos[ob=x[i]];
00513     pos[ob]=p1;
00514     if (p1>=0 && p1<4*MAX_TEAMROWS) {
00515       if (random(100)<50)             // Damit gut gemischt wird...
00516         b_rows[p1]=b_rows[p1]+({ob}); // zufaellig hinten anfuegen
00517       else
00518         b_rows[p1]=({ob})+b_rows[p1]; // oder vorne anfuegen.
00519     }
00520   }
00521 
00522   // Umrechnung von Min, Max auf Reihen
00523   // ... -2: -124..-75, -1:-74..-25, 0:-24..24, 1:25..74 2:75..124 ...
00524   // Das muss man machen, wenn man keine vernuenftige Rundungsfunktion hat:
00525   if (min<0) min=-1*((25-min)/50); else min=(25+min)/50;
00526   if (max<0) max=-1*((25-max)/50); else max=(25+max)/50;
00527   // Relativ zur Position des Spielers verschieben:
00528   p1=pos[pl];min+=p1;max+=p1;
00529   // Umrechnung von Breite auf Anzahl:
00530   dx=((dx+50)/100)-1;if (dx<0) dx=0;
00531 
00532   x=({({}),({})});
00533   for (i=0;i<2*MAX_TEAMROWS;i++)
00534     if (i>=min && i<=max)
00535       x[1]+=b_rows[i][0..dx]; // Freunde
00536   for (i=2*MAX_TEAMROWS+1;i<4*MAX_TEAMROWS;i++)
00537     if (i>=min && i<=max)
00538       x[0]+=b_rows[i][0..dx]; // Feinde
00539 
00540   return x;
00541 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

varargs object FindEnemyVictim ( string  wen,
object  pl,
string  msg 
)

Definiert in Zeile 666 der Datei spellbook.c.

Benutzt DoFindEnemyVictim().

Wird benutzt von feuerball(), kampfschrei(), pfeil() und saeurestrahl().

00666                                                    {
00667   return DoFindEnemyVictim(wen,pl,msg,"SelectEnemy");
00668 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

varargs object FindFarEnemyVictim ( string  wen,
object  pl,
string  msg,
int  min,
int  max 
)

Definiert in Zeile 676 der Datei spellbook.c.

Benutzt DoFindEnemyVictim().

00677                                      {
00678   return DoFindEnemyVictim(wen,pl,msg,"SelectFarEnemy",min,max);
00679 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

object* FindGroup ( object  pl,
int  who 
)

Definiert in Zeile 387 der Datei spellbook.c.

Benutzt env(), IS_LEARNING, ob(), P_FRIEND, P_GHOST, P_NO_ATTACK, P_NO_GLOBAL_ATTACK, P_TEAM, qp und team.

Wird benutzt von FindGroupN() und FindGroupP().

00387                               {
00388   object *res,ob,env,team;
00389   int p1,p2;
00390   closure qp;
00391 
00392   res=({});
00393   if (!pl || !(env=environment(pl))) return res;
00394   p1 = query_once_interactive(pl) ? 1 : -1;
00395   team=(object)pl->QueryProp(P_TEAM);
00396   for (ob=first_inventory(env);ob;ob=next_inventory(ob)) {
00397     if (!living(ob)) continue;
00398     qp=symbol_function("QueryProp",ob);
00399     if (pl->IsEnemy(ob)) // Feinde sind immer Gegner
00400       p2=-1*p1;
00401     else if (objectp(team) && funcall(qp,P_TEAM)==team)
00402       p2=p1; // Teammitglieder sind immer auf Seite des Spielers
00403     else
00404       p2 = (query_once_interactive(ob)||funcall(qp,P_FRIEND)) ? 1 : -1;
00405     if (p2>0 && !interactive(ob) && query_once_interactive(ob))
00406       continue; // keine Netztoten.
00407     if (funcall(qp,P_GHOST))
00408       continue;
00409     if ( who<0 && (funcall(qp,P_NO_ATTACK) || funcall(qp,P_NO_GLOBAL_ATTACK)) )
00410       continue;
00411     if (IS_LEARNING(ob) &&
00412         (funcall(qp,P_INVIS) || (who<0 && !pl->IsEnemy(ob))))
00413       continue;
00414     if (p1*p2*who >=0)
00415       res+=({ob});
00416   }
00417   return res;
00418 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

object* FindGroupN ( object  pl,
int  who,
int  n 
)

Definiert in Zeile 421 der Datei spellbook.c.

Benutzt FindGroup() und SA_EXTENSION.

00421                                       {
00422   if (!pl) return ({});
00423   n=(n*(int)pl->QuerySkillAttribute(SA_EXTENSION))/100;
00424   if (n<1) n=1;
00425   return FindGroup(pl,who)[0..(n-1)];
00426 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

object* FindGroupP ( object  pl,
int  who,
int  pr 
)

Definiert in Zeile 429 der Datei spellbook.c.

Benutzt FindGroup(), i und SA_EXTENSION.

00429                                        {
00430   object *res,*nres;
00431   int i;
00432 
00433   nres=({});
00434   if (!pl) return nres;
00435   pr=(pr*(int)pl->QuerySkillAttribute(SA_EXTENSION))/100;
00436   if (pr<0) return nres;
00437   res=FindGroup(pl,who);
00438   for (i=sizeof(res)-1;i>=0;i--)
00439     if (pr>=random(100))
00440       nres+=({res[i]});
00441   return nres;
00442 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

varargs object FindLivingVictim ( string  wen,
object  pl,
string  msg 
)

Definiert in Zeile 583 der Datei spellbook.c.

Benutzt FindVictim() und P_GHOST.

Wird benutzt von DoFindEnemyVictim() und schaetz().

00583                                                     {
00584   object vic;
00585 
00586   if (!(vic=FindVictim(wen,pl,msg)))
00587     return 0;
00588   if (!living(vic) || vic->QueryProp(P_GHOST)) {
00589     printf("%s lebt doch nicht!\n", capitalize((string)vic->name()));
00590     return 0;
00591   }
00592   return vic;
00593 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

varargs object FindNearEnemyVictim ( string  wen,
object  pl,
string  msg 
)

Definiert in Zeile 671 der Datei spellbook.c.

Benutzt DoFindEnemyVictim().

00671                                                        {
00672   return DoFindEnemyVictim(wen,pl,msg,"SelectNearEnemy");
00673 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

varargs object FindVictim ( string  wen,
object  pl,
string  msg 
)

Definiert in Zeile 575 der Datei spellbook.c.

Benutzt find_victim().

Wird benutzt von FindLivingVictim() und identifiziere().

00575                                               {
00576   object vic;
00577 
00578   if (!(vic=find_victim(wen,pl)) && msg)
00579     write(msg);
00580   return vic;
00581 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

void Learn ( object  caster,
string  spell,
mapping  sinfo 
)

Definiert in Zeile 208 der Datei spellbook.c.

Benutzt A_CON, A_DEX, A_INT, A_STR, GetFValue(), GetFValueO(), GetOffset(), SI_DIFFICULTY, SI_LEARN_ATTRIBUTE, SI_SKILLLEARN und SI_SPELLCOST.

Wird benutzt von Misserfolg().

00208                                                   {
00209   int val,diff,attval;
00210   mapping attr;
00211   
00212   // Attribut sollte int sein, wenn nicht anders angegeben
00213  if (mappingp(sinfo[SI_LEARN_ATTRIBUTE]))
00214  {
00215                 attr=sinfo[SI_LEARN_ATTRIBUTE];
00216                 // Direkt in einem durch berechnen.
00217                 // Ich gehe davon aus, dass wir nie nie nie
00218                 // ein weiteres Attribut ins MG einfuegen.
00219                 // Wir berechnen den Mittelwert
00220                 attval=((int)caster->QueryAttribute(A_INT)*attr[A_INT]+
00221                                 (int)caster->QueryAttribute(A_DEX)*attr[A_DEX]+
00222                                 (int)caster->QueryAttribute(A_STR)*attr[A_STR]+
00223                                 (int)caster->QueryAttribute(A_CON)*attr[A_CON])
00224                                 /(attr[A_CON]+attr[A_INT]+attr[A_STR]+attr[A_DEX]);
00225                                 
00226                  
00227  } else {
00228                  attval=(int)caster->QueryAttribute(A_INT);
00229  }
00230 
00231   
00232   val=((attval/2)*GetFValue(SI_SKILLLEARN,sinfo,caster)+
00233        GetOffset(SI_SKILLLEARN,sinfo,caster));
00234   if (!(diff=GetFValueO(SI_DIFFICULTY,sinfo,caster)))
00235     diff=GetFValueO(SI_SPELLCOST,sinfo,caster);
00236   caster->LearnSkill(spell,val,diff);
00237 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

void Misserfolg ( object  caster,
string  spell,
mapping  sinfo 
)

Definiert in Zeile 247 der Datei spellbook.c.

Benutzt Learn().

Wird benutzt von UseSpell().

00247                                                        {
00248   write("Der Zauberspruch ist missglueckt.\n");
00249   write("Du lernst aus Deinem Fehler.\n");
00250   Learn(caster,spell,sinfo);
00251 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

varargs void prepare_spell ( object  caster,
string  spell,
mapping  sinfo 
)

Definiert in Zeile 261 der Datei spellbook.c.

Benutzt SI_PREPARE_MSG.

Wird benutzt von UseSpell().

00261                                                           {
00262   string txt;
00263 
00264   if (!caster || !spell) return ;
00265   if (!mappingp(sinfo) || !stringp(txt=sinfo[SI_PREPARE_MSG]))
00266     txt="Du bereitest Dich auf den Spruch ``%s'' vor.\n";
00267   tell_object(caster,sprintf(txt,spell));
00268 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

mapping QuerySpell ( string  spell  ) 

Definiert in Zeile 40 der Datei spellbook.c.

Benutzt P_SB_SPELLS und Query().

00040                                  {
00041   mapping spi;
00042 
00043   //Query-Methode umgehen, damit nur ein Spellmapping kopiert werden muss und
00044   //nicht das ganzen Mapping mit allen Spells.
00045   if (!spell
00046       || !(spi=Query(P_SB_SPELLS))
00047       || !(spi=spi[spell]))
00048     return 0;
00049   return deep_copy(spi);
00050 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

string SelectSpell ( string  spell,
mapping  sinfo 
)

Definiert in Zeile 254 der Datei spellbook.c.

Benutzt SI_SKILLFUNC.

Wird benutzt von UseSpell().

00254                                          {
00255   if (sinfo && sinfo[SI_SKILLFUNC])
00256     return sinfo[SI_SKILLFUNC];
00257   return spell;
00258 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

int SpellSuccess ( object  caster,
mapping  sinfo 
)

Definiert in Zeile 179 der Datei spellbook.c.

Benutzt MAX_ABILITY, SI_SKILLABILITY, SK_CASTING und SMUL.

Wird benutzt von ausweichen(), feuerball(), identifiziere(), kampfschrei(), licht(), pfeil(), saeurestrahl(), schaetz() und schnell().

00179                                            {
00180   int cval,abil,res;
00181 
00182   abil=sinfo[SI_SKILLABILITY];
00183   cval=(int)caster->UseSkill(SK_CASTING);
00184   res=abil + (SMUL(abil,cval)) / MAX_ABILITY - random(MAX_ABILITY);
00185   if (cval && res>MAX_ABILITY) // besonders gut gelungen?
00186     caster->LearnSkill(SK_CASTING,1+(res-MAX_ABILITY)/2000);
00187   return res;
00188 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

int TryAttackSpell ( object  victim,
int  damage,
mixed  dtypes,
mixed  is_spell,
object  caster,
mapping  sinfo 
)

Definiert in Zeile 107 der Datei spellbook.c.

Benutzt CheckPlayerAttack(), no_attack(), P_GHOST, P_NO_ATTACK, P_NOMAGIC, SA_DAMAGE, SA_ENEMY_SAVE, SI_NOMAGIC, SP_NAME und WER.

Wird benutzt von TryDefaultAttackSpell() und TryGlobalAttackSpell().

00108                                                              {
00109   mixed no_attack;
00110   int nomag;
00111 
00112   if (no_attack = (mixed)victim->QueryProp(P_NO_ATTACK)) {
00113     if (stringp(no_attack))
00114       write(no_attack);
00115     else
00116       write(victim->Name(WER,1)+" laesst sich nicht angreifen!\n");
00117     return 0;
00118   }
00119   if (victim->QueryProp(P_GHOST)) {
00120     write(victim->Name(WER,1)+" ist ein Geist!\n");
00121     return 0;
00122   }
00123 
00124   damage=(damage*(int)caster->QuerySkillAttribute(SA_DAMAGE))/100;
00125 
00126   // ggf. Loggen von PK-Versuchen
00127   if (query_once_interactive(caster) && query_once_interactive(victim))
00128     CheckPlayerAttack(caster, victim, sprintf("Spellbook: %O, Spell: %O\n",
00129                 object_name(this_object()),
00130                 ((mappingp(sinfo) && is_spell) ? sinfo[SP_NAME]  : "") ) );
00131 
00132   nomag=(int)victim->QueryProp(P_NOMAGIC);
00133   if ((sinfo[SI_NOMAGIC] < nomag) &&
00134       nomag*100 > random(100)*(int)caster->QuerySkillAttribute(SA_ENEMY_SAVE)) {
00135     printf("%s wehrt Deinen Zauber ab.\n", capitalize((string)victim->name(WER, 1)));
00136     return 0;
00137   }
00138   else {
00139     return (int)victim->Defend(damage, dtypes, is_spell, caster);
00140   }
00141 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

varargs int TryDefaultAttackSpell ( object  victim,
object  caster,
mapping  sinfo,
mixed  si_spell 
)

Definiert in Zeile 144 der Datei spellbook.c.

Benutzt GetData(), GetRandFValueO(), OFFSET, P_TEAM, SI_SKILLDAMAGE, SI_SKILLDAMAGE_BY_ROW, SI_SKILLDAMAGE_TYPE, SI_SPELL, team und TryAttackSpell().

Wird benutzt von feuerball(), pfeil() und saeurestrahl().

00145                                       {
00146   object team;
00147   int row;
00148   
00149   if (!si_spell) si_spell=sinfo[SI_SPELL];
00150   // Wenn der Spieler in einem Team ist, die Teamreihen-Boni
00151   // beruecksichtigen. Wenn nicht, eben nicht.
00152   if (!team=((object)caster->QueryProp(P_TEAM)))
00153   return TryAttackSpell(victim,
00154                         GetRandFValueO(SI_SKILLDAMAGE,sinfo,caster),
00155                         GetData(SI_SKILLDAMAGE_TYPE,sinfo,caster),
00156                         si_spell,
00157                         caster,
00158                         sinfo);
00159   else
00160   {
00161                   row=(int)caster->PresentPosition();
00162                   return TryAttackSpell(victim,
00163                                   GetRandFValueO(SI_SKILLDAMAGE,sinfo,caster)+
00164                                   // Nur wenn SI_SKILLDAMAGE_BY_ROW ein mapping ist, 
00165                                   // randomisiert addieren
00166                                   (mappingp(sinfo[SI_SKILLDAMAGE_BY_ROW])?
00167                                    random(sinfo[SI_SKILLDAMAGE_BY_ROW][row]):0)+
00168                                   // Nur wenn das OFFSET davon ein mapping ist,
00169                                   // nicht randomisiert addieren.
00170                                   (mappingp(sinfo[OFFSET(SI_SKILLDAMAGE_BY_ROW)])?
00171                                    sinfo[OFFSET(SI_SKILLDAMAGE_BY_ROW)][row] : 0),
00172                                    GetData(SI_SKILLDAMAGE_TYPE,sinfo,caster),
00173                                    si_spell,caster,sinfo);
00174    }
00175 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

varargs int TryGlobalAttackSpell ( object  caster,
mapping  sinfo,
int  suc,
int  damage,
mixed  dt,
mixed  is_spell,
int  dist,
int  depth,
int  width 
)

Definiert in Zeile 689 der Datei spellbook.c.

Benutzt FindDistantGroups(), GetData(), GetRandFValueO(), obs, SI_COLLATERAL_DAMAGE, SI_DEPTH, SI_DISTANCE, SI_NUMBER_ENEMIES, SI_NUMBER_FRIENDS, SI_SKILLABILITY, SI_SKILLDAMAGE, SI_SKILLDAMAGE_TYPE, SI_SPELL, SI_WIDTH, SP_GLOBAL_ATTACK und TryAttackSpell().

00691                                                      {
00692   int i;
00693   mixed x,coldam;
00694   object *obs,ob;
00695 
00696   if (!suc) suc=random(sinfo[SI_SKILLABILITY]);
00697   if (!dt) dt=GetData(SI_SKILLDAMAGE_TYPE,sinfo,caster);
00698   if (!is_spell) is_spell=GetData(SI_SPELL,sinfo,caster);
00699   if (!dist) dist=GetRandFValueO(SI_DISTANCE,sinfo,caster);
00700   if (!depth) depth=GetRandFValueO(SI_DEPTH,sinfo,caster);
00701   if (!width) width=GetRandFValueO(SI_WIDTH,sinfo,caster);
00702 
00703   if (!depth && width) depth=width;
00704   if (!width && depth) width=depth;
00705   if (!mappingp(is_spell)) is_spell=([]);
00706   is_spell[SP_GLOBAL_ATTACK]=1;
00707 
00708   x=FindDistantGroups(caster,dist,depth,width);
00709   sinfo[SI_NUMBER_ENEMIES]=sizeof(x[0]);
00710   sinfo[SI_NUMBER_FRIENDS]=sizeof(x[1]);
00711 
00712   obs=x[0];
00713   for (i=sizeof(obs)-1;i>=0;i--)
00714     if (objectp(ob=obs[i]) && suc>=ob->SpellDefend(caster,sinfo))
00715       TryAttackSpell(ob,(damage?random(damage):
00716                          GetRandFValueO(SI_SKILLDAMAGE,sinfo,caster)),
00717                      dt,is_spell,caster,sinfo);
00718 
00719   if (!intp(coldam=sinfo[SI_COLLATERAL_DAMAGE]) || !coldam)
00720     return 1;
00721   obs=x[1];
00722   for (i=sizeof(obs)-1;i>=0;i--)
00723     if (objectp(ob=obs[i]) && suc>=ob->SpellDefend(caster,sinfo))
00724       ob->reduce_hit_points(((damage?random(damage):
00725                               GetRandFValueO(SI_SKILLDAMAGE,sinfo,caster))
00726                              *coldam)/10);
00727   // 10 statt 100 ist Absicht, weil reduce_hit_points schon um Faktor
00728   // 10 staerker wirkt als Defend.
00729 
00730   return 1;
00731 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

varargs int UseSpell ( object  caster,
string  spell,
mapping  sinfo 
)

Definiert in Zeile 271 der Datei spellbook.c.

Benutzt ABGEWEHRT, AddSkillMappings(), CanTrySpell(), Erfolg(), ERFOLG, GetFValueO(), GetValue(), Misserfolg(), MISSERFOLG, NO_ATTACK_BUSY_QUERY, P_ATTACK_BUSY, P_NEXT_SPELL_TIME, P_NOMAGIC, P_PREPARED_SPELL, P_SP, prepare_spell(), QueryProp(), QuerySpell(), race_modifier(), SelectSpell(), SI_ATTACK_BUSY_AMOUNT, SI_ATTACK_BUSY_MSG, SI_NO_ATTACK_BUSY, SI_NOMAGIC, SI_NOMAGIC_MSG, SI_PREPARE_ABORT_MSG, SI_PREPARE_BUSY_MSG, SI_PREPARE_TIME, SI_SKILLARG, SI_SKILLFUNC, SI_SP_LOW_MSG, SI_SPELLCOST, SI_SPELLFATIGUE, SI_TIME_MSG und spellbook.

00271                                                      {
00272   mapping ski,tmp;
00273   string spellbook,sname,fname,txt;
00274   int res,fat,cost;
00275   mixed ps;
00276 
00277   if (!caster || !spell)
00278     return 0;
00279   sname=SelectSpell(spell,sinfo);
00280   // Spell kann in der Gilde anderen Namen haben
00281   if (!(ski=QuerySpell(sname))) // Existiert dieser Spell?
00282     return 0;
00283   ski=AddSkillMappings(ski,sinfo);
00284   // Gildeneigenschaften sollen Spelleigenschaften ueberschreiben koennen
00285   ski=race_modifier(caster,ski);
00286   // Fuer verschiedene Rassen unterschiedliche Eigenschaften
00287 
00288   // printf("Spellinfo: %O\n",ski);
00289 
00290   if (!CanTrySpell(caster, ski))
00291     return 1;
00292   if (caster->QueryProp(P_SP) < (cost=GetFValueO(SI_SPELLCOST,ski,caster))) {
00293     if(txt=ski[SI_SP_LOW_MSG])write(txt);
00294     else write("Du hast zu wenig Zauberpunkte fuer diesen Spruch.\n");
00295     return 1;
00296   }
00297   // printf("cost: %d\n",cost);
00298 #if __BOOT_TIME__ < 1268687556
00299   if (time()<caster->QueryProp(P_NEXT_SPELL_TIME)) {
00300 #else
00301   if (caster->CheckSpellFatigue()) {
00302 #endif
00303     if(txt=ski[SI_TIME_MSG]) write(txt);
00304     else write("Du bist noch zu erschoepft von Deinem letzten Spruch.\n");
00305     return 1;
00306   }
00307   if (!(ski[SI_NO_ATTACK_BUSY]&NO_ATTACK_BUSY_QUERY) &&
00308       caster->QueryProp(P_ATTACK_BUSY)) {
00309     if (txt=ski[SI_ATTACK_BUSY_MSG]) write(txt);
00310     else write("Du bist schon zu sehr beschaeftigt.\n");
00311     return 1;
00312   }
00313 
00314   // Spruchvorbereitung
00315   if (pointerp(ps=(mixed)caster->QueryProp(P_PREPARED_SPELL)) // Ausstehender Spruch
00316       && sizeof(ps)>=3 && intp(ps[0] && stringp(ps[1]))) {
00317     if (ps[1]==spell) { // Dieser Spruch wird noch vorbereitet
00318       if (time()<ps[0]) {
00319         if (!stringp(txt=ski[SI_PREPARE_BUSY_MSG]))
00320           txt="Du bist noch mit der Spruchvorbereitung beschaeftigt.\n";
00321         write(txt);
00322         return 1;
00323       }
00324     } else { // Andere Sprueche brechen die Vorbereitung ab
00325       if (!mappingp(tmp=QuerySpell(ps[1])) || // richtige Meldung holen...
00326           !stringp(txt=tmp[SI_PREPARE_ABORT_MSG]))
00327         txt="Du brichst die Spruchvorbereitung fuer `%s' ab.\n";
00328       printf(txt,ps[1]);
00329       if (fat=GetValue(SI_PREPARE_TIME,ski,caster)) {
00330         // Spruch braucht vorbereitungszeit
00331         caster->SetProp(P_PREPARED_SPELL,({time()+fat,spell,ski[SI_SKILLARG]}));
00332         prepare_spell(caster,spell,ski);
00333         return 1;
00334       }
00335     }
00336   } else {
00337     if (fat=GetValue(SI_PREPARE_TIME,ski,caster)) {
00338       // Spruch braucht vorbereitungszeit
00339       caster->SetProp(P_PREPARED_SPELL,({time()+fat,spell,ski[SI_SKILLARG]}));
00340       prepare_spell(caster,spell,ski);
00341       return 1;
00342     }
00343   }
00344   if (ps)
00345     caster->SetProp(P_PREPARED_SPELL,0);
00346 
00347   if (!(fname=sinfo[SI_SKILLFUNC]))
00348     fname=sname;
00349   // Funktion kann anderen Namen haben als Spell
00350   res=0;
00351   if((ski[SI_NOMAGIC] < environment(caster)->QueryProp(P_NOMAGIC)) &&
00352       random(100) < environment(caster)->QueryProp(P_NOMAGIC)) {
00353     if (txt=ski[SI_NOMAGIC_MSG]) write(txt);
00354     else write("Dein Zauberspruch verpufft im Nichts.\n");
00355     res=ABGEWEHRT;
00356   } else {
00357     res=(int)call_other(this_object(),fname,caster,ski);
00358   }
00359   if (!res || !caster)
00360     return 1;
00361 
00362   if (!(ski[SI_NO_ATTACK_BUSY]&NO_ATTACK_BUSY_QUERY))
00363                 {
00364                 if (!ski[SI_ATTACK_BUSY_AMOUNT])  
00365                                 caster->SetProp(P_ATTACK_BUSY,1);
00366                 else
00367                                 caster->SetProp(P_ATTACK_BUSY,ski[SI_ATTACK_BUSY_AMOUNT]);
00368                 }
00369   if ((fat=GetFValueO(SI_SPELLFATIGUE,ski,caster))<0)
00370     fat=1;
00371   caster->restore_spell_points(-1*cost);
00372 #if __BOOT_TIME < 1268687556
00373   caster->SetProp(P_NEXT_SPELL_TIME,time()+fat);
00374 #else
00375   caster->SetSpellFatigue(fat);
00376 #endif
00377 
00378   if (res==ERFOLG)
00379     Erfolg(caster,spell,ski);
00380   else
00381   if (res==MISSERFOLG)
00382     Misserfolg(caster,spell,ski);
00383   return 1;
00384 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:


Variablen-Dokumentation

inherit std player pklog

Definiert in Zeile 16 der Datei spellbook.c.

inherit std restriction_checker

Definiert in Zeile 15 der Datei spellbook.c.

inherit std thing

Definiert in Zeile 14 der Datei spellbook.c.

Erzeugt am Thu Jun 3 14:43:19 2010 für MorgenGrauen Mudlib von  doxygen 1.6.3